📄 scemfgdiparser.cpp
字号:
SCEMRSMALLTEXTOUTA2 *pTextRec2 = (SCEMRSMALLTEXTOUTA2*)m_pRecord;
// get the EMRTEXT
SCEMRSMALLTEXTOUTA *pTextRec = pRec;
// number of characters
INT iNbChars = pTextRec->nChars;
if (iNbChars<=0)
{
// We don't know the behavior of ExtTextOut:
// - if number of characters is 0
// - if, moreover, TA_UPDATECP is set in the DC
#if 0
// if required, play the record
SCPlayRecord();
#endif
return SC_BRK_NOERROR;
}
UINT uiOptions = pRec->fOptions; // we might have to alter it
// TODO: review this line
BOOL bUnicode = (uiOptions == 0x100);
// Build the string
LPWSTR pwStr = NULL;
if (bUnicode)
{
// The string is in unicode -> we let it as is.
// Offset is from the beginning of the struct and is in bytes.
//
// Get the unicode string
pwStr = (LPWSTR)pTextRec->Text;
#if 0
// TODO:
// Translate glyph indices to code points when the rasterizer does not
// support string measurement for glyph indices.
if ((uiOptions & ETO_GLYPH_INDEX) && (!m_pRenderer->SCCanMeasureGlyphs())
{
int iRes = SCUnicodeCharsFromGlyphs(m_hPlayDC, pString, iNbChars);
if (iRes)
uiOptions &= ~ETO_GLYPH_INDEX;
}
#endif
} else
{
// The string is single-byte encoded.
// Get adress of the string then construct the string.
LPSTR pString = (LPSTR)pTextRec->Text;
// TODO: review this line
if (uiOptions==0x204)
pString = (char *)pTextRec2->Text;
pwStr = new wchar_t[iNbChars+1];
if (pwStr)
{// We will use UNICODE strings exclusively
pwStr[iNbChars] = 0;
int iNum = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pString, iNbChars, pwStr, iNbChars+1);
#ifdef _DEBUG
if (0==iNum)
{
DWORD dwError = GetLastError();
}
#endif
ASSERT(iNum==iNbChars);
}
}
ASSERT(pwStr);
// Get intercharacter spacing array.
// Be careful ! there are cases where OffDx==0.
// TODO: review this line
DWORD OffDx = 0;//pTextRec->offDx;
INT *lpDx = (INT*)((BYTE*)pRec + OffDx);
//if (0==OffDx)
{
// If the lpDx parameter is NULL, the ExtTextOut function uses the default
// spacing between characters. So we do.
//
// Compute intercharacter spacing, based on each character width.
lpDx = new INT[iNbChars];
BOOL bOk = SCGetTextCharWidthsW(m_hPlayDC, pwStr, iNbChars, lpDx);
ASSERT(bOk);
} // else use distances between origins of adjacent character cells as passed to ExtTextOut.
CRect rcText;
if (uiOptions==0x204)
{
rcText.CopyRect((LPRECT)&pTextRec2->rclBoundsSC);
} else
{
uiOptions &= ~ETO_CLIPPED; // we don't have the rectangle
rcText.SetRectEmpty();
}
if (GM_COMPATIBLE==pTextRec->iGraphicsMode)
m_pRenderer->SCDrawText(pTextRec->ptlReference.x, pTextRec->ptlReference.y, uiOptions,
(LPRECT)&rcText, pwStr, iNbChars, lpDx, pRec->exScale, pRec->eyScale);
else
m_pRenderer->SCDrawText(pTextRec->ptlReference.x, pTextRec->ptlReference.y, uiOptions,
(LPRECT)&rcText, pwStr, iNbChars, lpDx, 1, 1);
// Clean up
if (!bUnicode)
delete [] pwStr;
if (0==OffDx)
delete [] lpDx;
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfFORCEUFIMAPPING()
{
// TRACE0("**EMR_FORCEUFIMAPPING\n");
ASSERT(m_pRenderer);
// EMR *pRec = (EMR*)m_pRecord;
// Danger if it writes to the DC
// Worse if it attempts escape-like behavior
//SCPlayRecord();
// Anyway, now it's SCEMF_RESERVED_109
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfNAMEDESCAPE()
{
// TRACE0("**EMR_NAMEDESCAPE\n");
ASSERT(m_pRenderer);
// Do not play escape
// Anyway, now it's SCEMF_RESERVED_110
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfCOLORCORRECTPALETTE()
{
// TRACE0("**EMR_COLORCORRECTPALETTE\n");
ASSERT(m_pRenderer);
// EMR *pRec = (EMR*)m_pRecord;
// TODO_EMF: Place code here to handle EMF record
SCPlayRecord();
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfSETICMPROFILEA()
{
// TRACE0("**EMR_SETICMPROFILEA\n");
ASSERT(m_pRenderer);
// EMR *pRec = (EMR*)m_pRecord;
// TODO_EMF: Place code here to handle EMF record
SCPlayRecord();
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfSETICMPROFILEW()
{
// TRACE0("**EMR_SETICMPROFILEW\n");
ASSERT(m_pRenderer);
// EMR *pRec = (EMR*)m_pRecord;
// TODO_EMF: Place code here to handle EMF record
SCPlayRecord();
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfALPHABLEND()
{
// TRACE0("**EMR_ALPHABLEND\n");
ASSERT(m_pRenderer);
EMRALPHABLEND *pRec = (EMRALPHABLEND*)m_pRecord;
ASSERT(pRec->offBmiSrc && pRec->offBitsSrc);
// Check if there is a bitmap
if (pRec->offBmiSrc && pRec->offBitsSrc)
{
// Source
CRect RcSrc(pRec->xSrc, pRec->ySrc, pRec->xSrc + pRec->cxSrc, pRec->ySrc + pRec->cySrc);
BITMAPINFO *pBmi = (BITMAPINFO *) ((BYTE *)pRec + pRec->offBmiSrc);
BYTE *pBits = (BYTE *) ((BYTE *) pRec + pRec->offBitsSrc);
// Destination
CRect RcDest(pRec->xDest, pRec->yDest, pRec->xDest + pRec->cxDest, pRec->yDest + pRec->cyDest);
m_pRenderer->SCDrawImageAlpha(&RcDest, &RcSrc, pBits, pBmi, pRec->iUsageSrc,
pRec->dwRop, &pRec->xformSrc, pRec->crBkColorSrc);
}
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfALPHADIBBLEND()
{
// TRACE0("**EMR_SETLAYOUT\n");
ASSERT(m_pRenderer);
// Now it's SCEMF_SETLAYOUT
//DWORD SetLayout(
// HDC hdc, // handle to DC
// DWORD dwLayout, // layout options
// );
// dwLayout==LAYOUT_BITMAPORIENTATIONPRESERVED Disables any reflection during BitBlt
// and StretchBlt operations.
// LAYOUT_RTL Sets the default horizontal layout
// to be right to left.
// OSes: Windows 2000 and later, Windows 98 and later
// TODO_EMF: horizontal reflection when the LAYOUT_RTL flag is selected
// m_pRenderer->SCSetLayout(((EMRSETLAYOUT*)m_pRecord)->iMode);
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfTRANSPARENTBLT()
{
// TRACE0("**EMR_TRANSPARENTBLT\n");
ASSERT(m_pRenderer);
EMRTRANSPARENTBLT *pRec = (EMRTRANSPARENTBLT*)m_pRecord;
ASSERT(pRec->offBmiSrc && pRec->offBitsSrc);
// Check if there is a bitmap
if (pRec->offBmiSrc && pRec->offBitsSrc)
{
// Source
CRect RcSrc(pRec->xSrc, pRec->ySrc, pRec->xSrc + pRec->cxSrc, pRec->ySrc + pRec->cySrc);
BITMAPINFO *pBmi = (BITMAPINFO *) ((BYTE *)pRec + pRec->offBmiSrc);
BYTE *pBits = (BYTE *) ((BYTE *) pRec + pRec->offBitsSrc);
// Destination
CRect RcDest(pRec->xDest, pRec->yDest, pRec->xDest + pRec->cxDest, pRec->yDest + pRec->cyDest);
m_pRenderer->SCDrawImageTransparent(&RcDest, &RcSrc, pBits, pBmi, pRec->iUsageSrc,
pRec->dwRop, &pRec->xformSrc, pRec->crBkColorSrc);
}
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfTRANSPARENTDIB()
{
// TRACE0("**EMR_TRANSPARENTDIB\n");
ASSERT(m_pRenderer);
// EMR *pRec = (EMR*)m_pRecord;
// TODO_EMF: Place code here to handle EMF record
// Anyway, now it's SCEMF_RESERVED_117
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfGRADIENTFILL()
{
// TRACE0("**EMR_GRADIENTFILL\n");
ASSERT(m_pRenderer);
EMRGRADIENTFILL *pRec = (EMRGRADIENTFILL*)m_pRecord;
LPBYTE pMesh = (LPBYTE)&pRec->Ver[pRec->nVer];
m_pRenderer->SCGradientFill(pRec->Ver, pRec->nVer, pMesh, pRec->nTri, pRec->ulMode);
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfSETLINKEDUFIS()
{
// TRACE0("**EMR_SETLINKEDUFIS\n");
ASSERT(m_pRenderer);
// EMR *pRec = (EMR*)m_pRecord;
// TODO_EMF: Place code here to handle EMF record
SCPlayRecord();
// Anyway, now it's SCEMF_RESERVED_119
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfSETTEXTJUSTIFICATION()
{
// TRACE0("**EMR_SETTEXTJUSTIFICATION\n");
ASSERT(m_pRenderer);
// EMR *pRec = (EMR*)m_pRecord;
// TODO_EMF: Place code here to handle EMF record
SCPlayRecord();
// Anyway, now it's SCEMF_RESERVED_120
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnEmfCOLORMATCHTOTARGETW()
{
// TRACE0("**EMR_CREATECOLORSPACE\n");
ASSERT(m_pRenderer);
// COLORMATCHTOTARGETW *pRec = (COLORMATCHTOTARGETW*)m_pRecord;
// TODO_EMF: Place code here to handle EMF record
SCPlayRecord();
return SC_BRK_NOERROR;
}
SC_BRKRESULT CSCEMFgdiParser::OnBrkUNKRecord(long lMsg)
{
// TRACE0("**OnBrkUNKRecord\n");
ASSERT(m_pRenderer);
UNUSED(lMsg); // unused in release builds
// By default, play unkown record
SCPlayRecord();
return SC_BRK_NOERROR;
}
//////////////////////////////////////////////////////////////////////
// Helpers
//////////////////////////////////////////////////////////////////////
// called before enumeration
SC_BRKRESULT CSCEMFgdiParser::SCBeginBreak(HDC hDC, LPVOID lpData, CONST RECT *lpRect)
{
SC_BRKRESULT error(SC_BRK_NOERROR);
ASSERT(m_pRenderer);
if (!m_pRenderer)
return SC_BRK_NORENDERER;
GetWorldTransform(hDC, &m_xformOrig);
// call inherited
error = SCBrkEMF::SCBeginBreak(hDC, lpData, lpRect);
// before enumeration
// clone the DC so that this class does not write on the destination DC
m_hDestDC = hDC; // for GDI+
#ifdef SC_USE_DCCLONER
// TODO: fix the bitmap problem in the cloner
m_pCloneDC = new SCDCCloner(hDC);
ASSERT(m_pCloneDC);
m_hPlayDC = m_pCloneDC->SCGetHDC(); // for GDI
#else
m_hPlayDC = hDC; // for GDI
#endif
ASSERT(m_hPlayDC && m_hDestDC);
return error;
}
//////////////////////////////////////////////////////////////////////
// Message map
//////////////////////////////////////////////////////////////////////
SC_BEGIN_MESSAGE_MAP(CSCEMFgdiParser, SCBrkEMF)
ON_VECTRECORD(SCEMF_HEADER, OnEmfHEADER)
ON_VECTRECORD(SCEMF_POLYBEZIER, OnEmfPOLYBEZIER)
ON_VECTRECORD(SCEMF_POLYGON, OnEmfPOLYGON)
ON_VECTRECORD(SCEMF_POLYLINE, OnEmfPOLYLINE)
ON_VECTRECORD(SCEMF_POLYBEZIERTO, OnEmfPOLYBEZIERTO)
ON_VECTRECORD(SCEMF_POLYLINETO, OnEmfPOLYLINETO)
ON_VECTRECORD(SCEMF_POLYPOLYLINE, OnEmfPOLYPOLYLINE)
ON_VECTRECORD(SCEMF_POLYPOLYGON, OnEmfPOLYPOLYGON)
ON_VECTRECORD(SCEMF_SETWINDOWEXTEX, OnEmfSETWINDOWEXTEX)
ON_VECTRECORD(SCEMF_SETWINDOWORGEX, OnEmfSETWINDOWORGEX)
ON_VECTRECORD(SCEMF_SETVIEWPORTEXTEX, OnEmfSETVIEWPORTEXTEX)
ON_VECTRECORD(SCEMF_SETVIEWPORTORGEX, OnEmfSETVIEWPORTORGEX)
ON_VECTRECORD(SCEMF_SETBRUSHORGEX, OnEmfSETBRUSHORGEX)
ON_VECTRECORD(SCEMF_EOF, OnEmfEOF)
ON_VECTRECORD(SCEMF_SETPIXELV, OnEmfSETPIXELV)
ON_VECTRECORD(SCEMF_SETMAPPERFLAGS, OnEmfSETMAPPERFLAGS)
ON_VECTRECORD(SCEMF_SETMAPMODE, OnEmfSETMAPMODE)
ON_VECTRECORD(SCEMF_SETBKMODE, OnEmfSETBKMODE)
ON_VECTRECORD(SCEMF_SETPOLYFILLMODE, OnEmfSETPOLYFILLMODE)
ON_VECTRECORD(SCEMF_SETROP2, OnEmfSETROP2)
ON_VECTRECORD(SCEMF_SETSTRETCHBLTMODE, OnEmfSETSTRETCHBLTMODE)
ON_VECTRECORD(SCEMF_SETTEXTALIGN, OnEmfSETTEXTALIGN)
ON_VECTRECORD(SCEMF_SETCOLORADJUSTMENT, OnEmfSETCOLORADJUSTMENT)
ON_VECTRECORD(SCEMF_SETTEXTCOLOR, OnEmfSETTEXTCOLOR)
ON_VECTRECORD(SCEMF_SETBKCOLOR, OnEmfSETBKCOLOR)
ON_VECTRECORD(SCEMF_OFFSETCLIPRGN, OnEmfOFFSETCLIPRGN)
ON_VECTRECORD(SCEMF_MOVETOEX, OnEmfMOVETOEX)
ON_VECTRECORD(SCEMF_SETMETARGN, OnEmfSETMETARGN)
ON_VECTRECORD(SCEMF_EXCLUDECLIPRECT, OnEmfEXCLUDECLIPRECT)
ON_VECTRECORD(SCEMF_INTERSECTCLIPRECT, OnEmfINTERSECTCLIPRECT)
ON_VECTRECORD(SCEMF_SCALEVIEWPORTEXTEX, OnEmfSCALEVIEWPORTEXTEX)
ON_VECTRECORD(SCEMF_SCALEWINDOWEXTEX, OnEmfSCALEWINDOWEXTEX)
ON_VECTRECORD(SCEMF_SAVEDC, OnEmfSAVEDC)
ON_VECTRECORD(SCEMF_RESTOREDC, OnEmfRESTOREDC)
ON_VECTRECORD(SCEMF_SETWORLDTRANSFORM, OnEmfSETWORLDTRANSFORM)
ON_VECTRECORD(SCEMF_MODIFYWORLDTRANSFORM, OnEmfMODIFYWORLDTRANSFORM)
ON_VECTRECORD(SCEMF_SELECTOBJECT, OnEmfSELECTOBJECT)
ON_VECTRECORD(SCEMF_CREATEPEN, OnEmfCREATEPEN)
ON_VECTRECORD(SCEMF_CREATEBRUSHINDIRECT, OnEmfCREATEBRUSHINDIRECT)
ON_VECTRECORD(SCEMF_DELETEOBJECT, OnEmfDELETEOBJECT)
ON_VECTRECORD(SCEMF_ANGLEARC, OnEmfANGLEARC)
ON_VECTRECORD(SCEMF_ELLIPSE, OnEmfELLIPSE)
ON_VECTRECORD(SCEMF_RECTANGLE, OnEmfRECTANGLE)
ON_VECTRECORD(SCEMF_ROUNDRECT, OnEmfROUNDRECT)
ON_VECTRECORD(SCEMF_ARC, OnEmfARC)
ON_VECTRECORD(SCEMF_CHORD, OnEmfCHORD)
ON_VECTRECORD(SCEMF_PIE, OnEmfPIE)
ON_VECTRECORD(SCEMF_SELECTPALETTE, OnEmfSELECTPALETTE)
ON_VECTRECORD(SCEMF_CREATEPALETTE, OnEmfCREATEPALETTE)
ON_VECTRECORD(SCEMF_SETPALETTEENTRIES, OnEmfSETPALETTEENTRIES)
ON_VECTRECORD(SCEMF_RESIZEPALETTE, OnEmfRESIZEPALETTE)
ON_VECTRECORD(SCEMF_REALIZEPALETTE, OnEmfREALIZEPALETTE)
ON_VECTRECORD(SCEMF_EXTFLOODFILL, OnEmfEXTFLOODFILL)
ON_VECTRECORD(SCEMF_LINETO, OnEmfLINETO)
ON_VECTRECORD(SCEMF_ARCTO, OnEmfARCTO)
ON_VECTRECORD(SCEMF_POLYDRAW, OnEmfPOLYDRAW)
ON_VECTRECORD(SCEMF_SETARCDIRECTION, OnEmfSETARCDIRECTION)
ON_VECTRECORD(SCEMF_SETMITERLIMIT, OnEmfSETMITERLIMIT)
ON_VECTRECORD(SCEMF_BEGINPATH, OnEmfBEGINPATH)
ON_VECTRECORD(SCEMF_ENDPATH, OnEmfENDPATH)
ON_VECTRECORD(SCEMF_CLOSEFIGURE, OnEmfCLOSEFIGURE)
ON_VECTRECORD(SCEMF_FILLPATH, OnEmfFILLPATH)
ON_VECTRECORD(SCEMF_STROKEANDFILLPATH, OnEmfSTROKEANDFILLPATH)
ON_VECTRECORD(SCEMF_STROKEPATH, OnEmfSTROKEPATH)
ON_VECTRECORD(SCEMF_FLATTENPATH, OnEmfFLATTENPATH)
ON_VECTRECORD(SCEMF_WIDENPATH, OnEmfWIDENPATH)
ON_VECTRECORD(SCEMF_SELECTCLIPPATH, OnEmfSELECTCLIPPATH)
ON_VECTRECORD(SCEMF_ABORTPATH, OnEmfABORTPATH)
ON_VECTRECORD(SCEMF_GDICOMMENT, OnEmfGDICOMMENT)
ON_VECTRECORD(SCEMF_FILLRGN, OnEmfFILLRGN)
ON_VECTRECORD(SCEMF_FRAMERGN, OnEmfFRAMERGN)
ON_VECTRECORD(SCEMF_INVERTRGN, OnEmfINVERTRGN)
ON_VECTRECORD(SCEMF_PAINTRGN, OnEmfPAINTRGN)
ON_VECTRECORD(SCEMF_EXTSELECTCLIPRGN, OnEmfEXTSELECTCLIPRGN)
ON_VECTRECORD(SCEMF_BITBLT, OnEmfBITBLT)
ON_VECTRECORD(SCEMF_STRETCHBLT, OnEmfSTRETCHBLT)
ON_VECTRECORD(SCEMF_MASKBLT, OnEmfMASKBLT)
ON_VECTRECORD(SCEMF_PLGBLT, OnEmfPLGBLT)
ON_VECTRECORD(SCEMF_SETDIBITSTODEVICE, OnEmfSETDIBITSTODEVICE)
ON_VECTRECORD(SCEMF_STRETCHDIBITS, OnEmfSTRETCHDIBITS)
ON_VECTRECORD(SCEMF_EXTCREATEFONTINDIRECTW, OnEmfEXTCREATEFONTINDIRECTW)
ON_VECTRECORD(SCEMF_EXTTEXTOUTA, OnEmfEXTTEXTOUTA)
ON_VECTRECORD(SCEMF_EXTTEXTOUTW, OnEmfEXTTEXTOUTW)
ON_VECTRECORD(SCEMF_POLYBEZIER16, OnEmfPOLYBEZIER16)
ON_VECTRECORD(SCEMF_POLYGON16, OnEmfPOLYGON16)
ON_VECTRECORD(SCEMF_POLYLINE16, OnEmfPOLYLINE16)
ON_VECTRECORD(SCEMF_POLYBEZIERTO16, OnEmfPOLYBEZIERTO16)
ON_VECTRECORD(SCEMF_POLYLINETO16, OnEmfPOLYLINETO16)
ON_VECTRECORD(SCEMF_POLYPOLYLINE16, OnEmfPOLYPOLYLINE16)
ON_VECTRECORD(SCEMF_POLYPOLYGON16, OnEmfPOLYPOLYGON16)
ON_VECTRECORD(SCEMF_POLYDRAW16, OnEmfPOLYDRAW16)
ON_VECTRECORD(SCEMF_CREATEMONOBRUSH, OnEmfCREATEMONOBRUSH)
ON_VECTRECORD(SCEMF_CREATEDIBPATTERNBRUSHPT, OnEmfCREATEDIBPATTERNBRUSHPT)
ON_VECTRECORD(SCEMF_EXTCREATEPEN, OnEmfEXTCREATEPEN)
ON_VECTRECORD(SCEMF_POLYTEXTOUTA, OnEmfP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -