⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 renderpages.cpp

📁 虚拟打印机
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * * renderpages.cpp *   Copyright (C) 2006 Michael H. Overlin   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Contact at poster_printer@yahoo.com * */#include "renderpages.h"#include "gdiutils.h"#include "mathutils.h"#include "spoolutils.h"#include "utils.h"#include <windows.h>#include <strsafe.h>#define MAX_CUTGUIDE_CCH			256#define CUTGUIDE_LINE_SPACE_INCHES	(1.0/128)#define FUDGE_MOSAICFROMZOOM		1.0E-12void RenderMosaicPage_Internal(	OUT HDC hdc, 	IN const RECT* prlDest, 	IN const POINT& ptPage,	IN const RenderSpec& rs, 	IN const PageSpec& ps,	IN HENHMETAFILE hMeta,	IN const SourceSpec &ss,	OUT RECTD *prdRenderedImageBounds_Inches	) ;void DrawCutGuide(OUT HDC hdc, IN const RECTD& in_rdCutGuide_Inches, 				  IN const POINTD& in_ptdLogPix, IN BOOL bVertical,				  IN const POINT& ptPage, IN double dCutGuide_Inches) ;void OffsetViewportOrg(OUT HDC hdc, IN const POINT& pt) {	OffsetViewportOrgEx(hdc, pt.x, pt.y, NULL);}void OffsetWindowOrg(OUT HDC hdc, IN const POINT& pt) {	OffsetWindowOrgEx(hdc, pt.x, pt.y, NULL);}void SetViewportOrg(OUT HDC hdc, IN const POINT& pt) {	SetViewportOrgEx(hdc, pt.x, pt.y, NULL);}void SetWindowOrg(OUT HDC hdc, IN const POINT& pt) {	SetWindowOrgEx(hdc, pt.x, pt.y, NULL);}void SetViewportExt(OUT HDC hdc, IN const SIZEL& szl) {	SetViewportExtEx(hdc, szl.cx, szl.cy, NULL);}void SetWindowExt(OUT HDC hdc, IN const SIZEL& szl) {	SetWindowExtEx(hdc, szl.cx, szl.cy, NULL);}// 6/1void RenderMosaicPage(	OUT HDC hdc, 	IN const RECT& rlDest, 	IN const POINT& ptPage,	IN const RenderSpec& rs, 	IN const PageSpec& ps,	IN HENHMETAFILE hMeta,	IN const SourceSpec &ss	) {	RenderMosaicPage_Internal(hdc, &rlDest, ptPage, rs, ps, hMeta, ss, NULL);}void RenderMosaicPage_Internal(	OUT HDC hdc, 	IN const RECT* prlDest, 	IN const POINT& ptPage,	IN const RenderSpec& rs, 	IN const PageSpec& ps,	IN HENHMETAFILE hMeta,	IN const SourceSpec &ss,	OUT RECTD *prdRenderedImageBounds_Inches	) {	// IS ALL PHYSICAL PAGE HEIGHT AVAILABLE FOR PRINTING?	// THIS TYPICALLY MEANS PAGE IS TRACTOR-FEAD	BOOL bAllHeight = (ps.szlPhysicalPage.cy == ps.szlPrintable.cy);		// IS ALL PHYSICAL PAGE WIDTH AVAILABLE FOR PRINTING?	BOOL bAllWidth = (ps.szlPhysicalPage.cx == ps.szlPrintable.cx);	// PIXELS PER INCH "LOGPIXELS"	POINTD ptdPageLogPixels = { 		ps.szlPhysicalPage.cx / ps.szdPhysicalPage_Inches.cx,		ps.szlPhysicalPage.cy / ps.szdPhysicalPage_Inches.cy	};	// TOTAL SIZE OF MOSAIC OF PAGES	SIZED szdPhysicalMosaic_Inches = {		ps.szdPhysicalPage_Inches.cx * rs.szMosaic.cx,		ps.szdPhysicalPage_Inches.cy * rs.szMosaic.cy	};	// OFFSET INTO PHYSICAL PAGE OF PRINTABLE AREA, IN INCHES	POINTD ptdOffsetPrintable_Inches = {		ps.ptlOffsetPrintable.x / ptdPageLogPixels.x,		ps.ptlOffsetPrintable.y / ptdPageLogPixels.y	};	// PAGE PRINTABLE SIZE IN INCHES	SIZED szdPrintablePage_Inches = {		ps.szlPrintable.cx / ptdPageLogPixels.x,		ps.szlPrintable.cy / ptdPageLogPixels.y	};	// TOTAL PRINTABLE MOSAIC SIZE IN INCHES	SIZED szdPrintableMosaic_Inches = { 		szdPrintablePage_Inches.cx * rs.szMosaic.cx,		szdPrintablePage_Inches.cy * rs.szMosaic.cy	};	// OFFSET OF IMAGE SELECTION WITHIN TOTAL IMAGE	POINTD ptdImageSelectionOffsetIntoTotal_Inches = {		ss.rdSelection_Inches.left - ss.rdTotalImage_Inches.left,		ss.rdSelection_Inches.top - ss.rdTotalImage_Inches.top	};	// TOTAL FREE PRINTABLE MOSAIC SIZE IN INCHES -- SPACE AVAILABLE FOR THE IMAGE ITSELF	// APART FROM OVERLAPPING MARGINS, CUTTING GUIDES, AND EDGE MARGINS	SIZED szdMargins_Inches;	szdMargins_Inches.cy = ps.ms.rdEdgeMargins_Inches.top + ps.ms.rdEdgeMargins_Inches.bottom - 		(ps.szdPhysicalPage_Inches.cy - szdPrintablePage_Inches.cy);	if (!bAllHeight) {		szdMargins_Inches.cy += 			(rs.szMosaic.cy - 1) * 			(ps.ms.dOverlapMargin_Inches + (rs.bCutGuides ? ps.ms.dCutGuideMargin_Inches : 0));	}	szdMargins_Inches.cx = ps.ms.rdEdgeMargins_Inches.left + ps.ms.rdEdgeMargins_Inches.right - 		(ps.szdPhysicalPage_Inches.cx - szdPrintablePage_Inches.cx);	if (!bAllWidth) {		szdMargins_Inches.cx += 			(rs.szMosaic.cx - 1) * (ps.ms.dOverlapMargin_Inches + (rs.bCutGuides ? ps.ms.dCutGuideMargin_Inches : 0));	}	SIZED szdFreePrintableMosaic_Inches = {		szdPrintableMosaic_Inches.cx - szdMargins_Inches.cx,		szdPrintableMosaic_Inches.cy - szdMargins_Inches.cy	};	// IMAGE SELECTION SIZE IN INCHES	SIZED szdImageSelection_Inches = { RW(ss.rdSelection_Inches), RH(ss.rdSelection_Inches) };	// ZOOMED SELECTED IMAGE TOTAL SIZE IN INCHES	double dZoom;	if (rs.mode == RenderSpec::eZoom) {		//dZoom = rs.wZoom / 100.0;		dZoom = rs.dZoom;	} else {		if (szdImageSelection_Inches.cx * szdFreePrintableMosaic_Inches.cy <			szdImageSelection_Inches.cy * szdFreePrintableMosaic_Inches.cx) {			dZoom = szdFreePrintableMosaic_Inches.cy / szdImageSelection_Inches.cy;		} else {			dZoom = szdFreePrintableMosaic_Inches.cx / szdImageSelection_Inches.cx;		}	}	SIZED szdZoomedImageSelection_Inches = {		szdImageSelection_Inches.cx * dZoom, szdImageSelection_Inches.cy * dZoom	};	SIZED szdTotalImage_Inches = { RW(ss.rdTotalImage_Inches), RH(ss.rdTotalImage_Inches) };	SIZED szdZoomedTotalImage_Inches = { szdTotalImage_Inches.cx * dZoom, szdTotalImage_Inches.cy * dZoom };	// 5/29 ADD A "bCenter" FLAG TO RenderSpec (WAS DEFAULT)	POINTD ptdZoomedImageSelectionOffsetIntoFreePrintableMosaic_Inches = {		(rs.bCenter ? ( szdFreePrintableMosaic_Inches.cx - szdZoomedImageSelection_Inches.cx ) / 2.0 : 0.0),		(rs.bCenter ? ( szdFreePrintableMosaic_Inches.cy - szdZoomedImageSelection_Inches.cy ) / 2.0 : 0.0)	};	RECTD rdZoomedImageSelectionIntoFreePrintableMosaic_Inches = {		ptdZoomedImageSelectionOffsetIntoFreePrintableMosaic_Inches.x,		ptdZoomedImageSelectionOffsetIntoFreePrintableMosaic_Inches.y,		ptdZoomedImageSelectionOffsetIntoFreePrintableMosaic_Inches.x + szdZoomedImageSelection_Inches.cx,		ptdZoomedImageSelectionOffsetIntoFreePrintableMosaic_Inches.y + szdZoomedImageSelection_Inches.cy	};	POINTD ptdZoomedTotalImageOffsetIntoFreePrintableMosaic_Inches = {		ptdZoomedImageSelectionOffsetIntoFreePrintableMosaic_Inches.x - 			ptdImageSelectionOffsetIntoTotal_Inches.x * dZoom,		ptdZoomedImageSelectionOffsetIntoFreePrintableMosaic_Inches.y - 			ptdImageSelectionOffsetIntoTotal_Inches.y * dZoom	};	RECTD rdZoomedTotalImageIntoFreePrintableMosaic_Inches = {		ptdZoomedTotalImageOffsetIntoFreePrintableMosaic_Inches.x,		ptdZoomedTotalImageOffsetIntoFreePrintableMosaic_Inches.y,		ptdZoomedTotalImageOffsetIntoFreePrintableMosaic_Inches.x + szdZoomedTotalImage_Inches.cx,		ptdZoomedTotalImageOffsetIntoFreePrintableMosaic_Inches.y + szdZoomedTotalImage_Inches.cy	};	// START WITH ENTIRE PRINTABLE RECT -- AS USUAL RELATIVE TO UPPER-LEFT CORNER OR PRINTABLE AREA ITSELF	// LATER ALL WILL BE TRANSLATED TO ITS LOCATION IN TOTAL PRINTABLE SPACE	// WE ONLY NEED TO CLIP OUT THE CUT GUIDES IF ANY, BECAUSE THE MARGINS ARE TAKEN CARE OF BY CLIPPING	// THE SELECTED IMAGE AREA	RECTD rdCutoutClipThisPage_Inches = { 0, 0, szdPrintablePage_Inches.cx, szdPrintablePage_Inches.cy };	// JUST AT THE TOP AND TO THE LEFT OF PAGES THAT DON'T LIE AT THE 	// MOSAIC TOP, LEFT BORDERS (THAT'S ALL YOU NEED TO CUT)	// *FIXED* DEBUG - FIX -- SEEM TO HAVE FORGOTTEN bAllWidth, bAllHeight	if (rs.bCutGuides) {		if (ptPage.y != 0 && !bAllHeight) {			rdCutoutClipThisPage_Inches.top += ps.ms.dCutGuideMargin_Inches;		} 		if (ptPage.x != 0 && !bAllWidth) {			rdCutoutClipThisPage_Inches.left += ps.ms.dCutGuideMargin_Inches;		}	}	POINTD ptdOffsetIntoFreePrintableMosaicThisPage_Inches = {		szdPrintablePage_Inches.cx * ptPage.x,		szdPrintablePage_Inches.cy * ptPage.y	};	ptdOffsetIntoFreePrintableMosaicThisPage_Inches.x -= ps.ms.rdEdgeMargins_Inches.left - ptdOffsetPrintable_Inches.x;	ptdOffsetIntoFreePrintableMosaicThisPage_Inches.y -= ps.ms.rdEdgeMargins_Inches.top - ptdOffsetPrintable_Inches.y;	if (!bAllHeight) {		ptdOffsetIntoFreePrintableMosaicThisPage_Inches.y -= 			ptPage.y * (ps.ms.dOverlapMargin_Inches + (rs.bCutGuides ? ps.ms.dCutGuideMargin_Inches : 0));	}	if (!bAllWidth) {		ptdOffsetIntoFreePrintableMosaicThisPage_Inches.x -= 			ptPage.x * (ps.ms.dOverlapMargin_Inches + (rs.bCutGuides ? ps.ms.dCutGuideMargin_Inches : 0));	}	if (prdRenderedImageBounds_Inches != NULL) {		RECTD rdTemp1;		::SetRect(rdTemp1, ptdOffsetIntoFreePrintableMosaicThisPage_Inches, szdPrintablePage_Inches);		RECTD rdTemp2;		::IntersectRect(rdTemp2, rdTemp1, rdZoomedImageSelectionIntoFreePrintableMosaic_Inches);		::OffsetRect(rdTemp2, 			- ptdOffsetIntoFreePrintableMosaicThisPage_Inches.x, - ptdOffsetIntoFreePrintableMosaicThisPage_Inches.y);		::IntersectRect(*prdRenderedImageBounds_Inches, rdTemp2, rdCutoutClipThisPage_Inches);	}	if (hdc != NULL) {		int nSaveDC = ::SaveDC(hdc);		RECT rlZoomedImageSelectionIntoFreePrintableMosaic;		RoundMult(rlZoomedImageSelectionIntoFreePrintableMosaic, 			rdZoomedImageSelectionIntoFreePrintableMosaic_Inches, ptdPageLogPixels);		RECT rlZoomedTotalImageIntoFreePrintableMosaic;		RoundMult(rlZoomedTotalImageIntoFreePrintableMosaic, 			rdZoomedTotalImageIntoFreePrintableMosaic_Inches, ptdPageLogPixels);		RECT rlCutoutClipThisPage;		RoundMult(rlCutoutClipThisPage, rdCutoutClipThisPage_Inches, ptdPageLogPixels);		// NOW WE WANT THIS PAGES PRINTABLE COORDS TO BE DISPLACED		// TO LIE AT IT'S MOSAIC POSITION, AND TO CLIP THE CUTTING GUIDES		// AND TO CLIP THE OVERALL ZOOMED IMAGE SELECTION		SetMapMode(hdc, MM_ANISOTROPIC);		SetViewport(hdc, *prlDest);		SetWindowExt(hdc, ps.szlPrintable);		SetWindowOrgEx(hdc, 0, 0, NULL);		// 5/31 DRAW THE CUTTING GUIDES IF ANY		// *FIXED* DEBUG - FIX -- SEEM TO HAVE FORGOTTEN bAllWidth, bAllHeight		if (rs.bCutGuides && ptPage.x != 0 && !bAllWidth) {			RECTD rdCutGuide_Inches = { 0, 0, ps.ms.dCutGuideMargin_Inches, szdPrintablePage_Inches.cy };			::DrawCutGuide(hdc, rdCutGuide_Inches, ptdPageLogPixels, TRUE, ptPage, ps.ms.dCutGuideMargin_Inches);				}		if (rs.bCutGuides && ptPage.y != 0 && !bAllHeight) {			RECTD rdCutGuide_Inches = { 0, 0, szdPrintablePage_Inches.cx, ps.ms.dCutGuideMargin_Inches,  };			::DrawCutGuide(hdc, rdCutGuide_Inches, ptdPageLogPixels, FALSE, ptPage, ps.ms.dCutGuideMargin_Inches);				}		IntersectClipRect(hdc, rlCutoutClipThisPage);		POINT ptlOffsetIntoFreePrintableMosaicThisPage;		RoundMult(ptlOffsetIntoFreePrintableMosaicThisPage, 			ptdOffsetIntoFreePrintableMosaicThisPage_Inches, ptdPageLogPixels);		OffsetWindowOrg(hdc, ptlOffsetIntoFreePrintableMosaicThisPage);		IntersectClipRect(hdc, rlZoomedImageSelectionIntoFreePrintableMosaic);		// 7/9		::SetStretchBltMode(hdc, COLORONCOLOR);		PlayEnhMetaFile(hdc, hMeta, &rlZoomedTotalImageIntoFreePrintableMosaic);		::RestoreDC(hdc, nSaveDC);	}}void CalculateMosaicSizeFromZoom(	OUT SIZE& szMosaic, 	IN double dZoom,	IN const RenderSpec& rs, 	IN const PageSpec& ps, 	IN const SourceSpec &ss) {	// IS ALL PHYSICAL PAGE HEIGHT AVAILABLE FOR PRINTING?	// THIS TYPICALLY MEANS PAGE IS TRACTOR-FEAD	BOOL bAllHeight = (ps.szlPhysicalPage.cy == ps.szlPrintable.cy);		// IS ALL PHYSICAL PAGE WIDTH AVAILABLE FOR PRINTING?	BOOL bAllWidth = (ps.szlPhysicalPage.cx == ps.szlPrintable.cx);	// PIXELS PER INCH "LOGPIXELS"	POINTD ptdPageLogPixels = { 		ps.szlPhysicalPage.cx / ps.szdPhysicalPage_Inches.cx,		ps.szlPhysicalPage.cy / ps.szdPhysicalPage_Inches.cy	};	// PAGE PRINTABLE SIZE IN INCHES	SIZED szdPrintablePage_Inches = {		ps.szlPrintable.cx / ptdPageLogPixels.x,		ps.szlPrintable.cy / ptdPageLogPixels.y	};	SIZED szdImageSelection_Inches = { RW(ss.rdSelection_Inches), RH(ss.rdSelection_Inches) };	SIZED szdMinFreePrintableMosaic_Inches = 		{ szdImageSelection_Inches.cx * dZoom, szdImageSelection_Inches.cy * dZoom };	SIZED szdOuterMargin = { 		ps.ms.rdEdgeMargins_Inches.left + ps.ms.rdEdgeMargins_Inches.right - (ps.szdPhysicalPage_Inches.cx - szdPrintablePage_Inches.cx),		 ps.ms.rdEdgeMargins_Inches.top + ps.ms.rdEdgeMargins_Inches.bottom - (ps.szdPhysicalPage_Inches.cy - szdPrintablePage_Inches.cy)	};	double dMoreInnerMargin = ps.ms.dOverlapMargin_Inches + (rs.bCutGuides ? ps.ms.dCutGuideMargin_Inches : 0);	SIZED szdMoreInnerMargin = { (bAllWidth ? 0 : dMoreInnerMargin), (bAllHeight ? 0 : dMoreInnerMargin) };	SIZED szdMinMosaic;	szdMinMosaic.cy = ( szdMinFreePrintableMosaic_Inches.cy + szdOuterMargin.cy - szdMoreInnerMargin.cy ) /		(szdPrintablePage_Inches.cy - szdMoreInnerMargin.cy);	szdMinMosaic.cx = ( szdMinFreePrintableMosaic_Inches.cx + szdOuterMargin.cx - szdMoreInnerMargin.cx ) /		(szdPrintablePage_Inches.cx - szdMoreInnerMargin.cx);	if (szdMinMosaic.cx < 1) {		szMosaic.cx = 1;	} else {		// 6/3 SAW 5 + 9E-16 GET ROUNDED UP TO 6, LOSS OF PRECISION IN CALCULATIONS		// AD-HOC FACTOR TO FIX THIS		szMosaic.cx = ::RoundUp(szdMinMosaic.cx - FUDGE_MOSAICFROMZOOM);	}	if (szdMinMosaic.cy < 1) {		szMosaic.cy = 1;	} else {		szMosaic.cy = ::RoundUp(szdMinMosaic.cy - FUDGE_MOSAICFROMZOOM);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -