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

📄 scemfimage.cpp

📁 Source code for EMFexplorer 1.0
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	// So save its state
	int iState = SaveDC(hDC);

	SCComputePageInfo(pInfo->m_nCurPage);

	// scaling
	int iPgIdx = pInfo->m_nCurPage - 1;
	HENHMETAFILE hEMF = m_pEMFDoc->SCGetPageEMF(iPgIdx);
	CPoint PageStart;
	{
		float iPrnDevResX = (float)GetDeviceCaps(pDC->m_hAttribDC, LOGPIXELSX);
		long lEmfDPIX = 0;
		long lEmfDPIY = 0;

		SCGetEMFDPIs(hEMF, lEmfDPIX, lEmfDPIY);
		m_DrawingAttributes.fPageScale = iPrnDevResX/lEmfDPIX;

		// get offset of the printable area in device units an convert to logical
		PageStart.x = GetDeviceCaps(pDC->m_hAttribDC, PHYSICALOFFSETX);
		PageStart.y = GetDeviceCaps(pDC->m_hAttribDC, PHYSICALOFFSETY);
		DPtoLP(pDC->m_hAttribDC, &PageStart, 1);
	}

	// Position of the EMF rectangle in world coordinates for playing
	int iAngle = m_iAngle;
	CSize sizeEMF;
	float fScaleEMF=1.0;
	SCGetEMFPlaySize(hEMF, sizeEMF, pDC->m_hAttribDC, &fScaleEMF);
	CSize sizeEMFScaled((int)(m_DrawingAttributes.fPageScale*sizeEMF.cx - 2*PageStart.x),
						(int)(m_DrawingAttributes.fPageScale*sizeEMF.cy - 2*PageStart.y));

	int iWdt = sizeEMF.cx;
	int iHgt = sizeEMF.cy;

	int iImgCx = sizeEMFScaled.cx;
	int iImgCy = sizeEMFScaled.cy;
	int iPaperCx = rcPaper.Width();
	int iPaperCy = rcPaper.Height();

	if (bFit)
	{
		if (iImgCx > iPaperCx)
		{
			iWdt = (int)(iPaperCx/m_DrawingAttributes.fPageScale);
			iHgt = MulDiv(iWdt, sizeEMF.cy, sizeEMF.cx);
		} else
		if (iImgCy > iPaperCy)
		{
			iHgt = (int)(iPaperCy/m_DrawingAttributes.fPageScale);
			iWdt = MulDiv(iHgt, sizeEMF.cx, sizeEMF.cy);
		}
	}
	else // attempt auto rotate
	if (iImgCx > iImgCy)
	{// landscape-like image
		if (iPaperCx > iPaperCy)
		{// landscape-like paper
			if (iImgCx > iPaperCx)
			{// x-fit
				iWdt = (int)(iPaperCx/m_DrawingAttributes.fPageScale);
				iHgt = MulDiv(iWdt, iImgCy, iImgCx);
			} else
			if (iImgCy > iPaperCy)
			{// y-fit
				iHgt = (int)(iPaperCy/m_DrawingAttributes.fPageScale);
				iWdt = MulDiv(iHgt, iImgCx, iImgCy);
			}
		}
		else
		{// portrait-like paper
			if (iImgCx > iPaperCx)
			{// rotate and fit
				iAngle = 270;
				if (iImgCx > iPaperCy)
				{// rotated x-fit
					iWdt = (int)(iPaperCy/m_DrawingAttributes.fPageScale);
					iHgt = MulDiv(iWdt, iImgCy, iImgCx);
				} else
				if (iImgCy > iPaperCx)
				{// rotated y-fit
					iHgt = (int)(iPaperCx/m_DrawingAttributes.fPageScale);
					iWdt = MulDiv(iHgt, iImgCx, iImgCy);
				}
			} //else (iImgCy <= iPaperCy)
#ifdef _DEBUG
			else
			{
				ASSERT((iImgCy <= iPaperCy));
			}
#endif
		}
	}
	else
	{// portrait-like image
		if (iPaperCx > iPaperCy)
		{// landscape-like paper
			if (iImgCy > iPaperCy)
			{// rotate and fit
				iAngle = 270;
				if (iImgCy > iPaperCx)
				{// rotated x-fit
					iHgt = (int)(iPaperCx/m_DrawingAttributes.fPageScale);
					iWdt = MulDiv(iHgt, iImgCx, iImgCy);
				} else
				if (iImgCx > iPaperCy)
				{// rotated y-fit
					iWdt = (int)(iPaperCy/m_DrawingAttributes.fPageScale);
					iHgt = MulDiv(iWdt, iImgCy, iImgCx);
				}
			} // else iImgCx <= iPaperCx
#ifdef _DEBUG
			else
			{
				ASSERT((iImgCx <= iPaperCx));
			}
#endif
		}
		else
		{// portrait-like paper
			if (iImgCx > iPaperCx)
			{// x-fit
				iWdt = (int)(iPaperCx/m_DrawingAttributes.fPageScale);
				iHgt = MulDiv(iWdt, iImgCy, iImgCx);
			} else
			if (iImgCy > iPaperCy)
			{// y-fit
				iHgt = (int)(iPaperCy/m_DrawingAttributes.fPageScale);
				iWdt = MulDiv(iHgt, iImgCx, iImgCy);
			}
		}
	}

	// TODO: compute scale (in preview and actual printing)
	iWdt = (int)(iWdt*m_DrawingAttributes.fPageScale);
	iHgt = (int)(iHgt*m_DrawingAttributes.fPageScale);
	m_DrawingAttributes.fPageScale = 1;
	//

	CRect rcPlay(xDest, yDest, xDest + iWdt, yDest + iHgt);

	if (iAngle)
	{// Position of the PAGE rectangle for rotation in world coordinates
		CRect rcRotate(0, 0, sizeEMFScaled.cx, sizeEMFScaled.cy);
		
		// Give the actual page rectangle for the rotation
		// and the actual destination (xDest, yDest) for the translation
		int iGrOldMode;
		SCRotateDC(hDC, iAngle, rcRotate, xDest, yDest, iGrOldMode);
	}

	// Rasterize
#ifndef SC_RENDERER_CAN_DOROP
	// In this version, GDI+ is not used for printing
	BOOL bOK;
	if (SCGdipGetEMFType(hEMF)!=EmfTypeEmfOnly)
		bOK = SCGdipPlayMetafile(hDC, hEMF, rcPlay);
	else
		bOK = PlayEnhMetaFile(hDC, hEMF, (LPRECT)&rcPlay);
#else
	BOOL bOK = SCRasterizeEMF(hDC, hEMF, rcPlay, TRUE);
#endif

	// Comments
	PSCEMFDocPage pDocPage = m_pEMFDoc->SCGetDocPage(iPgIdx);
	ASSERT(pDocPage);
	switch (iAngle)
	{
	case 90:
	case 270:
		pDocPage->SCDisplayPageComments(hDC, float(m_iCurZoom)/float(SC_ZOOM100),
			xDest, yDest, iHgt, iWdt);
		break;
	default:
		pDocPage->SCDisplayPageComments(hDC, float(m_iCurZoom)/float(SC_ZOOM100),
			xDest, yDest, iWdt, iHgt);
	}

	// Restore DC state
	RestoreDC(hDC, iState);

	// Perform full rvideo
	if (SCIsFullReverseVideo())
		PatBlt(hDC, xDest-1, yDest-1, iWdt+2, iHgt+2, DSTINVERT);
}

void CSCEMFImage::SCInitConverter(SCEMFConverter& converter)
{
	CRect rcClient;
	GetClientRect(&rcClient);
	
	converter.SCSetEMFDoc(m_pEMFDoc);
	converter.SCSetCurZoom(m_iCurZoom);
	converter.SCSetAngle(m_iAngle);
	converter.SCSetMargins(m_rectMargins);
	converter.SCSetReverseVideo(m_bReverseVideo);
	converter.SCSetRasEngine(m_uiRasEngine);
	converter.SCSetPaperColor(SCGetTranslatedPaperColor());
	converter.SCSetRectClient(rcClient);
	converter.SCSetFitMode(m_iFitMode);
	converter.SCSetDrawingAttributes(m_DrawingAttributes);
}

void CSCEMFImage::SCSaveImageDiscardHandle(HANDLE hRes, LPCTSTR lpszPathname, int iType, int iSubType)
{
	if (hRes)
	{
		switch (iType)
		{
		case SC_FTYPE_EMF:
		case SC_FTYPE_WMF:
			if (SC_FTYPE_EMF==iType)
				SCWriteEMFtoDisk((HENHMETAFILE)hRes, lpszPathname);
			else
				SCConvertEMFtoWMF((HENHMETAFILE)hRes, lpszPathname);
			::DeleteEnhMetaFile((HENHMETAFILE)hRes);
			break;
			
		case SC_FTYPE_IMG:
			 // TODO: for JPEGs ask quality level to user
			SCGDIpSaveImage((HBITMAP)hRes, lpszPathname, iSubType);
			::DeleteObject((HBITMAP)hRes);
			break;
			
		default:
			ASSERT(0);
		}
	}
}

///
/// Save current EMF or all pages to disk
///
void CSCEMFImage::SCSaveDocument(LPCTSTR lpszPathname, int iType, BOOL bSaveAll/*=FALSE*/, BOOL bSaveAsIs/*=TRUE*/)
{
	if (!m_pEMFDoc)
		return;

	int iNbPages=m_pEMFDoc->SCGetNbPages();
	if (0==iNbPages)
		return;

	int iSubType = iType & SC_SUBTYPE_MASK;
	iType &= SC_FTYPE_MASK;

	SCEMFConverter converter;
	SCInitConverter(converter);
	CRect PaperRect;
	if (bSaveAll)
	{// save each page
		CString strPrefix;
		TCHAR szExt[_MAX_EXT];
		{
			TCHAR szDrive[SC_MAX_UNC_DRIVE];
			TCHAR szDir[_MAX_DIR];
			TCHAR szFname[_MAX_FNAME];
			SCSplitPath(lpszPathname, szDrive, szDir, szFname, szExt);
			strPrefix.Format(_T("%s%s%s"), szDrive, szDir, szFname);
		}

		CString strName;
		for (int iPage=0; (iPage<iNbPages); iPage++)
		{
			strName.Format(_T("%s%d%s"), strPrefix, iPage+1, szExt);
			HANDLE hRes = converter.SCCopyPage(iPage+1, iType, iSubType, bSaveAsIs);
			SCSaveImageDiscardHandle(hRes, strName, iType, iSubType);
		}
	} else
	{
		ASSERT(m_iCurPage);
		HANDLE hRes = converter.SCCopyPage(m_iCurPage, iType, iSubType, bSaveAsIs);
		SCSaveImageDiscardHandle(hRes, lpszPathname, iType, iSubType);
	}
}


///
/// Copy the current page to cliboard in many formats.
/// (no partial copy is provided in this version; pSrcRect is not used)
///
BOOL CSCEMFImage::SCCopyToClipBoard(CRect* pSrcRect/*=NULL*/) 
{
	UNUSED(pSrcRect);	// Zzzz!... let it sleep for now

	if (!OpenClipboard())
		return FALSE;
	
	BOOL bOk = FALSE;
	if (::EmptyClipboard())
	{
		HANDLE hCopied = NULL;

		SCEMFConverter converter;
		SCInitConverter(converter);
		
		// EMF
		HANDLE hData = converter.SCCopyPage(m_iCurPage, SC_FTYPE_EMF, SC_SUBTYPE_EMF_EMF, TRUE);
		if (hData)
		{
			hCopied = ::SetClipboardData(CF_ENHMETAFILE, (HENHMETAFILE)hData);
			if (!hCopied)
				::DeleteEnhMetaFile((HENHMETAFILE)hData);
			bOk = TRUE;
		}
		
		// Bitmap
		hData = converter.SCCopyPage(m_iCurPage, SC_FTYPE_IMG, SC_SUBTYPE_IMG_BMP, TRUE);
		if (hData)
		{
			hCopied = ::SetClipboardData(CF_BITMAP, (HBITMAP)hData);
			if (!hCopied)
				::DeleteObject((HBITMAP)hData);
			bOk = TRUE;
		}
	}
	::CloseClipboard();
	return bOk;
}

///
/// Paste the clipboard content as a new full page
/// (no partial paste is provided in this version; pDestRect is not used)
///
BOOL CSCEMFImage::SCPasteFromClipBoard(CRect* pDestRect/*=NULL*/) 
{
	UNUSED(pDestRect);	// Zzzz!... let it sleep for now

	if (!m_pEMFDoc)
		return FALSE;

    if (!OpenClipboard())
		return FALSE;

	BOOL bOk = FALSE;
	HEMFVECTOR vectHandles;
	BeginWaitCursor();
	
	// Check main vector formats
	UINT uiFmt = 0;
	while (uiFmt = EnumClipboardFormats(uiFmt))
	{
		if (uiFmt == CF_ENHMETAFILE)
		{
			HENHMETAFILE hEMF = (HENHMETAFILE)::GetClipboardData(CF_ENHMETAFILE);
			if (hEMF)
			{
				hEMF = CopyEnhMetaFile(hEMF, NULL);
				if (hEMF)
					vectHandles.push_back(hEMF);
			}
			break;
		} else
		if (uiFmt == s_cfRTF)
		{
			HANDLE hMem = ::GetClipboardData(s_cfRTF);
			SCConvertRTFtoEMF(hMem, vectHandles); 
			break;
		}
	}

	// Check text formats
	if (!vectHandles.size())
	{
		HANDLE hMem = ::GetClipboardData(CF_UNICODETEXT);
		if (hMem)
			SCConvertRTFtoEMF(hMem, vectHandles, FALSE);
	}

	// Check bitmap formats
    if (!vectHandles.size())
	{
		HENHMETAFILE hEMF = NULL;
		HBITMAP hbm;
		if (hbm = (HBITMAP)GetClipboardData(CF_BITMAP))
		{
			// Any palette in the clipboard at this time is assumed to be the one
			// the bitmap is realized against.
			HPALETTE hpal = (HPALETTE)GetClipboardData(CF_PALETTE);
			if (!hpal)
				hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
			hEMF = SCGDIpConvertBitmaptoEMF(hbm, hpal);
		} else
		{
			HANDLE hMem = NULL;
			if (hMem =  GetClipboardData(CF_TIFF))
				hEMF = SCGDIpConvertImagetoEMF(hMem);
		}
		if (hEMF)
			vectHandles.push_back(hEMF);
	}

	CloseClipboard();

    // Add pages to the doc
	if (vectHandles.size())
		bOk = m_pEMFDoc->SCPasteEMFPages(vectHandles);

	EndWaitCursor();
	return bOk;
}

// Display context menu
void CSCEMFImage::OnRButtonDown(UINT nFlags, CPoint point) 
{
	if (m_hCtxMenu)
	{
		CMenu menu;
		if (menu.Attach(m_hCtxMenu))
		{
			//convert client coordinates to screen coordinates
			ClientToScreen(&point);
			
			//show context menu
			CWnd* pOwner = this;
			if (m_pICtlOwner)
			{
				pOwner = m_pICtlOwner->SCGetMenuOwner();
				if (!pOwner)
					pOwner = this;
				m_pICtlOwner->SCSetupCtxMenu(&menu);
			}
			menu.TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, pOwner);
			menu.Detach();
		}
	}

	CWnd::OnRButtonDown(nFlags, point);
}

BOOL CSCEMFImage::OnCommand( WPARAM wParam, LPARAM lParam )
{
	if (m_pICtlOwner)
		m_pICtlOwner->SCOnCtxCommand(wParam, lParam);
	return TRUE;
}


⌨️ 快捷键说明

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