使用soui4实现一个打印排版软件(十四)将排版的图像导出

void CMainDlg::OnBnClickExport()
{
	CPaletteContainer* pContainer = FindChildByName2<CPaletteContainer>(L"palette_container");
	if (pContainer->GetChildrenCount() == 0) return;
	//先计算实际有元素的区域
	std::map<int, int> mapX;
	std::map<int, int> mapY;
	for (int i = 0; i < pContainer->GetChildrenCount(); i++)
	{
		CEleBase* pBase = sobj_cast<CEleBase>(pContainer->GetChild(i + 1));
		if (pBase)
		{
			mapX[pBase->m_ptLT.x] = pBase->m_ptLT.x;
			mapX[pBase->m_ptRB.x] = pBase->m_ptRB.x;
			mapY[pBase->m_ptLT.y] = pBase->m_ptLT.y;
			mapY[pBase->m_ptRB.y] = pBase->m_ptRB.y;
		}
	}

	auto iterXLast = mapX.rbegin();
	auto iterYLast = mapY.rbegin();

	CPoint ptLT(0, 0);
	CPoint ptRB(iterXLast->first, iterYLast->first);
	CRect rcContent(ptLT, ptRB); //实际有内容的区域

	int nXDPI = 600;
	int nYDPI = 600;
	int nDefaultPix2CM = 20;
	int nContentWid = rcContent.Width();
	int nContentHei = rcContent.Height();

	double dContentWidMM = (double)nContentWid / nDefaultPix2CM * 10;
	double dContentHeiMM = (double)nContentHei / nDefaultPix2CM * 10;

	int nExportWid = dContentWidMM * nXDPI / 25.4;
	int nExportHei = dContentHeiMM * nYDPI / 25.4;

	CRect rcContainer(0, 0, nExportWid, nExportHei);
	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	{//绘制白色背景
		COLORREF clrBkgnd = GETCOLOR(L"rgba(255,255,255,255)");
		CAutoRefPtr<IBrush> brush, oldbrush;
		pRTContainer->CreateSolidColorBrush(clrBkgnd, &brush);
		pRTContainer->SelectObject(brush, (IRenderObj**)&oldbrush);
		pRTContainer->FillRectangle(&rcContainer);
		pRTContainer->SelectObject(oldbrush, NULL);
	}

	for (int i = 0; i < pContainer->GetChildrenCount(); i++)
	{
		CEleBase* pBase = sobj_cast<CEleBase>(pContainer->GetChild(i + 1));
		if (pBase)
		{
			//获取ele的位置、大小的mm  然后转为对应新缩放比例的位置大小
			CPoint ptLT(pBase->m_ptLT);
			CPoint ptRB(pBase->m_ptRB);
			//将坐标信息根据排版页面的缩放系数转为mm
			double dLeftMM = (double)ptLT.x / nDefaultPix2CM * 10;
			double dTopMM = (double)ptLT.y / nDefaultPix2CM * 10;
			double dRightMM = (double)ptRB.x / nDefaultPix2CM * 10;
			double dBottomMM = (double)ptRB.y / nDefaultPix2CM * 10;
			//将mm坐标信息转为导出缩放系数的像素值
			//根据X、Y DPI计算元素实际大小
			int nExportLeft = dLeftMM * nXDPI / 25.4;
			int nExportTop = dTopMM * nYDPI / 25.4;
			int nExportRight = dRightMM * nXDPI / 25.4;
			int nExportBottom = dBottomMM * nYDPI / 25.4;
			CRect rcArea(nExportLeft, nExportTop, nExportRight, nExportBottom);
			SStringW sstrClassName = pBase->GetObjectClass();
			if (sstrClassName == L"ele_rect")
			{
				CEleRect* pEle = sobj_cast<CEleRect>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_ellipse")
			{
				CEleEllipse* pEle = sobj_cast<CEleEllipse>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_circular")
			{
				CEleCircular* pEle = sobj_cast<CEleCircular>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_triangle")
			{
				CEleTriangle* pEle = sobj_cast<CEleTriangle>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_diamond")
			{
				CEleDiamond* pEle = sobj_cast<CEleDiamond>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_barcode")
			{
				CEleBarcode* pEle = sobj_cast<CEleBarcode>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_qrcode")
			{
				CEleQRcode* pEle = sobj_cast<CEleQRcode>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_text")
			{
				CEleText* pEle = sobj_cast<CEleText>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_picture")
			{
				CElePicture* pEle = sobj_cast<CElePicture>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
			else if (sstrClassName == L"ele_pdf")
			{
				CElePDF* pEle = sobj_cast<CElePDF>(pBase);
				pEle->OnPaintExport(pRTContainer, rcArea, nXDPI, nYDPI);
			}
		}
	}

	CAutoRefPtr<IBitmap> bmpExport = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	//保存图片
	SStringW sstrName = L"export.png";
	bmpExport->Save(sstrName, (LPVOID)&ImageFormatPNG);
}

Rect元素导出绘制:

void CEleRect::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);

	int nBorderWidth = 20;
	rcContainer.DeflateRect(nBorderWidth / 2, nBorderWidth / 2, nBorderWidth / 2, nBorderWidth / 2);

	COLORREF clrBorder = GETCOLOR(RGB(0,0,0));
	CAutoRefPtr<IPen> pen, oldpen;
	pRTContainer->CreatePen(PS_SOLID, clrBorder, nBorderWidth, &pen);
	pRTContainer->SelectObject(pen, (IRenderObj**)&oldpen);
	pRTContainer->DrawRectangle(&rcContainer);
	pRTContainer->SelectObject(oldpen, NULL);

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

Ellipse元素导出绘制:

void CEleEllipse::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);

	int nBorderWidth = 20;
	rcContainer.DeflateRect(nBorderWidth / 2, nBorderWidth / 2, nBorderWidth / 2, nBorderWidth / 2);

	COLORREF clrBorder = GETCOLOR(RGB(0, 0, 0));
	CAutoRefPtr<IPen> pen, oldpen;
	pRTContainer->CreatePen(PS_SOLID, clrBorder, nBorderWidth, &pen);
	pRTContainer->SelectObject(pen, (IRenderObj**)&oldpen);
	pRTContainer->DrawEllipse(&rcContainer);
	pRTContainer->SelectObject(oldpen, NULL);

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

Circular元素导出绘制:

void CEleCircular::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);

	int nBorderWidth = 20;
	rcContainer.DeflateRect(nBorderWidth / 2, nBorderWidth / 2, nBorderWidth / 2, nBorderWidth / 2);

	COLORREF clrBorder = GETCOLOR(RGB(0, 0, 0));
	CAutoRefPtr<IPen> pen, oldpen;
	pRTContainer->CreatePen(PS_SOLID, clrBorder, nBorderWidth, &pen);
	pRTContainer->SelectObject(pen, (IRenderObj**)&oldpen);
	pRTContainer->DrawEllipse(&rcContainer);
	pRTContainer->SelectObject(oldpen, NULL);

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

Triangle元素导出绘制:

void CEleTriangle::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);

	int nBorderWidth = 2;
 	rcContainer.DeflateRect(0, 0, 0, nBorderWidth / 2);

	CAutoRefPtr<IPathS> path;
	GETRENDERFACTORY->CreatePath(&path);
	COLORREF clrBorder = GETCOLOR(L"RGB(0,0,255)");
	int nBorderLine = PS_SOLID;
	CAutoRefPtr<IPen> pen, oldpen;

	CPoint ptCenter = rcContainer.CenterPoint();
	CPoint pt1, pt2, pt3;
	pt1.x = rcContainer.left;
	pt1.y = rcContainer.bottom;
	pt2.x = ptCenter.x;
	pt2.y = rcContainer.top;
	pt3 = rcContainer.BottomRight();

	path->moveTo(pt1.x, pt1.y);
	path->lineTo(pt2.x, pt2.y);
	path->lineTo(pt3.x, pt3.y);
	path->lineTo(pt1.x, pt1.y);

	pRT->CreatePen(nBorderLine | PS_ENDCAP_SQUARE, clrBorder, nBorderWidth, &pen);
	pRT->SelectObject(pen, (IRenderObj**)&oldpen);
	pRT->DrawPath(path);
	pRT->SelectObject(oldpen, NULL);


	pRTContainer->SelectObject(oldpen, NULL);

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

Diamond元素导出绘制:

void CEleDiamond::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);

	CPoint ptCenter = rcContainer.CenterPoint();
	int nBorderWidth = 2;
	//rcContainer.DeflateRect(nBorderWidth / 2, nBorderWidth / 2, nBorderWidth / 2, nBorderWidth / 2);

	CAutoRefPtr<IPathS> path;
	GETRENDERFACTORY->CreatePath(&path);
	COLORREF clrBorder = GETCOLOR(L"RGB(0,0,255)");
	int nBorderLine = PS_SOLID;
	CAutoRefPtr<IPen> pen, oldpen;

	CPoint pt1, pt2, pt3, pt4;
	pt1.x = ptCenter.x;
	pt1.y = rcContainer.bottom;

	pt2.x = rcContainer.left;
	pt2.y = ptCenter.y;

	pt3.x = ptCenter.x;
	pt3.y = rcContainer.top;

	pt4.x = rcContainer.right;
	pt4.y = ptCenter.y;

	path->moveTo(pt1.x, pt1.y);
	path->lineTo(pt2.x, pt2.y);
	path->lineTo(pt3.x, pt3.y);
	path->lineTo(pt4.x, pt4.y);
	path->lineTo(pt1.x, pt1.y);

	pRT->CreatePen(nBorderLine | PS_ENDCAP_SQUARE, clrBorder, nBorderWidth, &pen);
	pRT->SelectObject(pen, (IRenderObj**)&oldpen);
	pRT->DrawPath(path);
	pRT->SelectObject(oldpen, NULL);

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

Barcode元素导出绘制:

void CEleBarcode::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	//计算字体放大系数(默认字体为12号字体)
	int nRatio = nExportWid / (nPix2CM * dWid / 10.0);
	int nFotSize = nRatio * 12;
	SStringW sstrFontFormat;
	sstrFontFormat.Format(L"face:微软雅黑,bold:0,italic:0,underline:0,strike:0,size:%d", nFotSize);
	SOUI::IFontPtr pFont = SFontPool::GetFont(sstrFontFormat, GetScale());

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);
	pRTContainer->SelectObject(pFont);

	SStringW sstrContent = L"0123456789";
	//计算文本所占的大小
	SIZE szContent;
	pRTContainer->MeasureText(sstrContent, sstrContent.GetLength(), &szContent);

	//将绘制条码的区域跟绘制文本的区域分开(此处只考虑文本在下方的情况,如有其他的需求可自己实现)
	CRect rcBar(rcContainer);
	rcBar.bottom = rcBar.bottom - szContent.cy;
	CRect rcText(rcContainer);
	rcText.top = rcBar.bottom;

	std::string strContent = S_CW2A(sstrContent);
	struct zint_symbol* symbol;
	symbol = ZBarcode_Create();
	symbol->symbology = BARCODE_CODE128;
	symbol->input_mode = DATA_MODE; //编码格式
	int nRet = ZBarcode_Encode_and_Buffer_Vector(symbol, (unsigned char*)strContent.c_str(), strContent.size(), 0);
	if (nRet == 0)
	{
		ZBarcode_Print(symbol, 0);
		std::vector<CRect> vecLines;
		if (symbol->vector)
		{
			struct zint_vector_rect* rect = symbol->vector->rectangles;
			while (rect)
			{
				CRect rcLine;
				rcLine.left = rect->x;
				rcLine.top = rect->y;
				rcLine.right = rcLine.left + rect->width;
				rcLine.bottom = rcLine.top + rect->height;
				vecLines.push_back(rcLine);
				rect = rect->next;
			}

			double nDrawUint = (double)rcBar.Width() / symbol->width;
			double nUint = (double)symbol->bitmap_width / symbol->width;

			CAutoRefPtr<IPathS> path;
			GETRENDERFACTORY->CreatePath(&path);
			for (int i = 0; i < vecLines.size(); i++)
			{
				CRect rcTmp(vecLines[i]);
				rcTmp.left = rcTmp.left / nUint * nDrawUint;
				rcTmp.right = rcTmp.right / nUint * nDrawUint;
				rcTmp.bottom = rcTmp.top + rcBar.Height();

				CRect rcBlack;
				rcBlack.left += rcTmp.left + rcBar.left;
				rcBlack.top += rcTmp.top + rcBar.top;
				rcBlack.right = rcBlack.left + rcTmp.Width();
				rcBlack.bottom = rcBlack.top + rcTmp.Height();

				path->addRect(rcBlack);
			}
			COLORREF clrFrg = GETCOLOR(L"RGB(0,0,0)");
			CAutoRefPtr<IBrush> brush, oldbrush;
			pRTContainer->CreateSolidColorBrush(clrFrg, &brush);

			pRTContainer->SelectObject(brush, (IRenderObj**)&oldbrush);
			pRTContainer->FillPath(path);
			pRTContainer->SelectObject(oldbrush, NULL);

			//绘制文本
			{
				pRTContainer->DrawText(sstrContent, -1, (LPRECT)rcText, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX);
			}
		}
	}

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

QRcode元素导出绘制:

void CEleQRcode::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);

	SStringW sstrContent = L"12359ABCDE";
	std::string strContent = S_CW2A(sstrContent);
	struct zint_symbol* symbol;
	symbol = ZBarcode_Create();
	symbol->symbology = BARCODE_QRCODE;
	symbol->input_mode = DATA_MODE; //编码格式

	//symbol->option_1;  //设置QRCode的EccLevel
	//symbol->option_2;  //设置QRCode的Version
	//symbol->option_3;  //设置QRCode的掩码

	int nRet = ZBarcode_Encode_and_Buffer_Vector(symbol, (unsigned char*)strContent.c_str(), strContent.size(), 0);
	if (nRet == 0)
	{
		ZBarcode_Print(symbol, 0);
		std::vector<CRect> vecRects;
		if (symbol->vector)
		{
			struct zint_vector_rect* rect = symbol->vector->rectangles;
			while (rect)
			{
				CRect rcTmp;
				rcTmp.left = rect->x;
				rcTmp.top = rect->y;
				rcTmp.right = rcTmp.left + rect->width;
				rcTmp.bottom = rcTmp.top + rect->height;
				vecRects.push_back(rcTmp);
				rect = rect->next;
			}
		}

		double dDrawXUint = (double)rcContainer.Width() / symbol->width;
		double dDrawYUint = (double)rcContainer.Height() / symbol->rows;
		double dXUint = (double)symbol->bitmap_width / symbol->width;
		double dYUint = (double)symbol->bitmap_height / symbol->rows;
		std::vector<CRect> vecDrawRects;  //二维码黑色真实区域
		for (int i = 0; i < vecRects.size(); i++)
		{
			CRect rcTmp(vecRects[i]);
			rcTmp.left = (rcTmp.left / dXUint * dDrawXUint);
			rcTmp.right = (rcTmp.right / dXUint * dDrawXUint);
			rcTmp.top = (rcTmp.top / dYUint * dDrawYUint);
			rcTmp.bottom = (rcTmp.bottom / dYUint * dDrawYUint);
			rcTmp.InflateRect(0, 1, 0, 1);
			vecDrawRects.push_back(rcTmp);
		}
		CAutoRefPtr<IPath> path;
		GETRENDERFACTORY->CreatePath(&path);
		for (int i = 0; i < vecDrawRects.size(); i++)
		{
			CRect rcRect;
			rcRect.left += vecDrawRects[i].left + rcContainer.left;
			rcRect.top += vecDrawRects[i].top + rcContainer.top;
			rcRect.right = rcRect.left + vecDrawRects[i].Width();
			rcRect.bottom = rcRect.top + vecDrawRects[i].Height();
			path->addRect(rcRect);
		}

		COLORREF clrFrgnd = GETCOLOR(L"RGB(0,0,0)");
		CAutoRefPtr<IBrush> brush, oldbrush;
		pRT->CreateSolidColorBrush(clrFrgnd, &brush);

		pRT->SelectObject(brush, (IRenderObj**)&oldbrush);
		pRT->FillPath(path);
		pRT->SelectObject(oldbrush, NULL);
	}

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

Text元素导出绘制:

void CEleText::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	//计算字体放大系数(默认字体为12号字体)
	int nRatio = nExportWid / (nPix2CM * dWid / 10.0);
	int nFotSize = nRatio * 12;
	SStringW sstrFontFormat;
	sstrFontFormat.Format(L"face:微软雅黑,bold:0,italic:0,underline:0,strike:0,size:%d", nFotSize);
	SOUI::IFontPtr pFont = SFontPool::GetFont(sstrFontFormat, GetScale());

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);
	pRTContainer->SelectObject(pFont);

	if (m_nType == 0)
	{
		//单行文本测试
		pRTContainer->DrawText(m_sstrContent, -1, (LPRECT)rcContainer, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_NOPREFIX);
	}
	else if (m_nType == 1)
	{
		//多行文本测试
		pRTContainer->DrawText(m_sstrContent, -1, (LPRECT)rcContainer, DT_LEFT | DT_TOP | DT_WORDBREAK | DT_NOPREFIX);
	}
	else
	{
		//填充文本测试
		SIZE szContent;
		pRTContainer->MeasureText(m_sstrContent, m_sstrContent.GetLength(), &szContent);
		float fXScale = (float)(rcContainer.Width()) / szContent.cx;
		float fYScale = (float)(rcContainer.Height()) / szContent.cy;
		SMatrix matrix;
		matrix.setScale(fXScale, fYScale);
		pRTContainer->SetTransform(matrix.fMat, NULL);
		pRTContainer->TextOutW(rcContainer.left / fXScale, rcContainer.top / fYScale, m_sstrContent, m_sstrContent.GetLength());
		pRTContainer->SetTransform(SMatrix().fMat);
	}

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

Picture元素导出绘制:

void CElePicture::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);

	{
		SStringW sstrPicPath = L"test.png";
		SAutoRefPtr<IBitmap> pBmp = SResLoadFromFile::LoadImage(sstrPicPath);

		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		if (pBmp)
		{
			CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
			pRTContainer->DrawBitmapEx(rcContainer, pBmp, &rcSrc, mode, 255);
			pBmp->Release();
		}
		else
		{
			//image load failed
		}
	}

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

PDF元素导出绘制:

void CElePDF::OnPaintExport(IRenderTarget* pRT, CRect& rcArea, int& nXDPI, int& nYDPI)
{
	//先根据最大的DPI生成一个大的图
	//然后根据输出DPI把大的图绘制到输出RT上(如果DPI不一致则会出现拉伸或压缩)
	int nPix2CM = 20;
	CRect rcClient = GetClientRect();
	int nDPI = (nXDPI > nYDPI) ? nXDPI : nYDPI;

	double dWid = (double)rcClient.Width() / nPix2CM * 10;
	double dHei = (double)rcClient.Height() / nPix2CM * 10;
	int nExportWid = dWid * nDPI / 25.4;
	int nExportHei = dHei * nDPI / 25.4;

	CAutoRefPtr<IRenderTarget> pRTContainer;
	GETRENDERFACTORY->CreateRenderTarget(&pRTContainer, nExportWid, nExportHei);
	CRect rcContainer(0, 0, 0, 0);
	rcContainer.right = rcContainer.left + nExportWid;
	rcContainer.bottom = rcContainer.top + nExportHei;
	pRTContainer->SetAntiAlias(TRUE);

	{
		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());
			pRTContainer->DrawBitmapEx(rcContainer, pBmp, &rcSrc, mode, 255);
			pBmp->Release();
		}
		else
		{
			//image load failed
		}
	}

	CAutoRefPtr<IBitmap> pBmp = NULL;
	pBmp = (IBitmap*)pRTContainer->GetCurrentObject(OT_BITMAP);
	if (pBmp)
	{
		DWORD mode = MAKELONG(EM_STRETCH, kNone_FilterLevel);
		CRect rcSrc(0, 0, pBmp->Width(), pBmp->Height());
		pRT->DrawBitmapEx(rcArea, pBmp, &rcSrc, mode, 255);
	}
}

排版内容:
在这里插入图片描述
导出内容:
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值