使用soui4实现一个打印排版软件(十三)PDF元素控件实现

PDF元素的移动、拉伸参考rect的实现,这里我们主要看看PDF的绘制部分代码
我这边的做法是先将PDF页面生成一张图片,然后跟图片控件一样进行贴图展示。
关于PDF的解析这边使用了第三方开源库mupdf
库导入:

#include "../mupdf/include/mupdf/fitz.h"
#include "../mupdf/include/mupdf/pdf.h"
#ifdef _DEBUG
#pragma comment(lib,"../mupdf/lib/x64/Debug/libmupdf.lib")
#else
#pragma comment(lib,"../mupdf/lib/x64/Release/libmupdf.lib")
#endif

PDF解析、以及图片绘制如下:

#pragma once
#include "CEleBase.h"

class CElePDF : public CEleBase
{
	DEF_SOBJECT(SWindow, L"ele_pdf")
public:
	CElePDF();
	~CElePDF();
public:
	void OnPaint(IRenderTarget* pRT);
protected:
	LRESULT OnCreate(LPVOID);

	void OnLButtonDown(UINT nFlags, SOUI::CPoint point);
	void OnLButtonUp(UINT nFlags, SOUI::CPoint point);
	void OnMouseMove(UINT nFlags, SOUI::CPoint point);
	void OnLButtonDblClk(UINT nFlags, SOUI::CPoint point);
	void OnRButtonUp(UINT nFlags, CPoint point);
protected:
	SOUI_MSG_MAP_BEGIN()
		MSG_WM_CREATE(OnCreate)
		MSG_WM_PAINT_EX(OnPaint)

		MSG_WM_LBUTTONDOWN(OnLButtonDown)
		MSG_WM_LBUTTONUP(OnLButtonUp)
		MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
		MSG_WM_RBUTTONUP(OnRButtonUp)
		MSG_WM_MOUSEMOVE(OnMouseMove)

		SOUI_MSG_MAP_END()
private:
	CPoint  m_ptDown;
	EcPosType m_curEcPosType;
};
#include "stdafx.h"
#include "CElePDF.h"
CElePDF::CElePDF()
{
	//
}
CElePDF::~CElePDF()
{
	//
}
void CElePDF::OnPaint(IRenderTarget* pRT)
{
	SetMsgHandled(FALSE);
	pRT->SetAntiAlias(TRUE);
	CRect rcWindow = GetWindowRect();
	SStringW sstrPath = L"test.pdf";
	std::string strUTF8Path = S_CW2A(sstrPath, CP_UTF8);
	fz_context* ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
	fz_register_document_handlers(ctx);
	fz_document* doc = fz_open_document(ctx, strUTF8Path.c_str());
	int nCount = fz_count_pages(ctx, doc);
	//设置缩放
	double dXDPI = 100.0;
	double dYDPI = 100.0;
	float xZoom = dXDPI / 72;
	float yZoom = dYDPI / 72;
	fz_matrix ctm = fz_scale(xZoom, yZoom);
	fz_pixmap* pix = NULL;
	int nPageIndex = 0;
	pix = fz_new_pixmap_from_page_number(ctx, doc, nPageIndex, ctm, fz_device_rgb(ctx), 0); 
	//直接读取pix中的像素值没搞明白,这里暂时先保存成一个本地图片吧
	fz_save_pixmap_as_png(ctx, pix, "pdf2image.png");
	fz_drop_pixmap(ctx, pix);
	fz_drop_document(ctx, doc);
	fz_drop_context(ctx);

	SStringW sstrPicPath = L"pdf2image.png";
	SAutoRefPtr<IBitmap> pBmp = SResLoadFromFile::LoadImage(sstrPicPath);
	DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
	if (pBmp)
	{
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcWindow, pBmp, &rcSrc, mode, 255);
		pBmp->Release();
	}
	else
	{
		//image load failed
	}

	//...
}

LRESULT CElePDF::OnCreate(LPVOID)
{
	SetMsgHandled(FALSE);
	//生成元素ID
	std::string strUUID = CGlobalUnits::GetInstance()->GenerateUUID();
	m_strUUID = strUUID;
	return __super::OnCreate(NULL);
}

void CElePDF::OnLButtonDown(UINT nFlags, SOUI::CPoint point)
{
	SetMsgHandled(FALSE);
	SetCapture();
	//...
}

void CElePDF::OnLButtonUp(UINT nFlags, SOUI::CPoint point)
{
	SetMsgHandled(FALSE);
	ReleaseCapture();
	//...
}

void CElePDF::OnMouseMove(UINT nFlags, SOUI::CPoint point)
{
	SetMsgHandled(FALSE);
	//...
}

void CElePDF::OnLButtonDblClk(UINT nFlags, SOUI::CPoint point)
{
	SetMsgHandled(FALSE);
}

void CElePDF::OnRButtonUp(UINT nFlags, CPoint point)
{
	SetMsgHandled(FALSE);
}

控件使用:
先注册,再在容器中创建元素

m_theApp->RegisterWindowClass<CElePDF>();
CElePDF* pEle = (CElePDF*)SApplication::getSingleton().CreateWindowByName(L"ele_pdf");
SASSERT(pEle);
SApplication::getSingleton().SetSwndDefAttr(pEle);
this->InsertChild(pEle);
pEle->SSendMessage(WM_CREATE);
CPoint ptReal(point);
ptReal.x -= rcContainer.left;
ptReal.y -= rcContainer.top;

SStringT sstrRectPos;
sstrRectPos.Format(_T("%d,%d,@%d,@%d"), ptReal.x, ptReal.y, 200, 200);
pEle->SetAttribute(L"pos", sstrRectPos);

//将位置、长宽等信息转为毫米
CPoint ptRB(ptReal.x + 200, ptReal.y + 200);
pEle->m_ptLT = ptReal;
pEle->m_ptRB = ptRB;

以上就是PDF控件的实现以及使用。
效果如下:
在这里插入图片描述
源PDF文件:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值