emf: bitblt, colours and debugging
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Mon Nov 10 11:17:38 CST 2003
Huw Davies <huw at codeweavers.com>
PatBlt()s get recorded as EMR_BITBLT records with offBmiSrc == 0, so
ensure that we pick these out in playback.
EMR_STRETCHBLT should behave like EMR_BITBLT if there are no bits
(ie. it's a PalBlt).
Set the text and bkgnd colour to black and white respectively before
enumerating an emf.
Print out the record names to make debugging easier.
Add a few TRACE()s.
--
Huw Davies
huw at codeweavers.com
Index: objects/enhmetafile.c
===================================================================
RCS file: /home/wine/wine/objects/enhmetafile.c,v
retrieving revision 1.71
diff -u -r1.71 enhmetafile.c
--- objects/enhmetafile.c 5 Sep 2003 23:15:42 -0000 1.71
+++ objects/enhmetafile.c 10 Nov 2003 17:12:12 -0000
@@ -54,6 +54,146 @@
BOOL on_disk; /* true if metafile is on disk */
} ENHMETAFILEOBJ;
+static const struct emr_name {
+ DWORD type;
+ const char *name;
+} emr_names[] = {
+#define X(p) {p, #p}
+X(EMR_HEADER),
+X(EMR_POLYBEZIER),
+X(EMR_POLYGON),
+X(EMR_POLYLINE),
+X(EMR_POLYBEZIERTO),
+X(EMR_POLYLINETO),
+X(EMR_POLYPOLYLINE),
+X(EMR_POLYPOLYGON),
+X(EMR_SETWINDOWEXTEX),
+X(EMR_SETWINDOWORGEX),
+X(EMR_SETVIEWPORTEXTEX),
+X(EMR_SETVIEWPORTORGEX),
+X(EMR_SETBRUSHORGEX),
+X(EMR_EOF),
+X(EMR_SETPIXELV),
+X(EMR_SETMAPPERFLAGS),
+X(EMR_SETMAPMODE),
+X(EMR_SETBKMODE),
+X(EMR_SETPOLYFILLMODE),
+X(EMR_SETROP2),
+X(EMR_SETSTRETCHBLTMODE),
+X(EMR_SETTEXTALIGN),
+X(EMR_SETCOLORADJUSTMENT),
+X(EMR_SETTEXTCOLOR),
+X(EMR_SETBKCOLOR),
+X(EMR_OFFSETCLIPRGN),
+X(EMR_MOVETOEX),
+X(EMR_SETMETARGN),
+X(EMR_EXCLUDECLIPRECT),
+X(EMR_INTERSECTCLIPRECT),
+X(EMR_SCALEVIEWPORTEXTEX),
+X(EMR_SCALEWINDOWEXTEX),
+X(EMR_SAVEDC),
+X(EMR_RESTOREDC),
+X(EMR_SETWORLDTRANSFORM),
+X(EMR_MODIFYWORLDTRANSFORM),
+X(EMR_SELECTOBJECT),
+X(EMR_CREATEPEN),
+X(EMR_CREATEBRUSHINDIRECT),
+X(EMR_DELETEOBJECT),
+X(EMR_ANGLEARC),
+X(EMR_ELLIPSE),
+X(EMR_RECTANGLE),
+X(EMR_ROUNDRECT),
+X(EMR_ARC),
+X(EMR_CHORD),
+X(EMR_PIE),
+X(EMR_SELECTPALETTE),
+X(EMR_CREATEPALETTE),
+X(EMR_SETPALETTEENTRIES),
+X(EMR_RESIZEPALETTE),
+X(EMR_REALIZEPALETTE),
+X(EMR_EXTFLOODFILL),
+X(EMR_LINETO),
+X(EMR_ARCTO),
+X(EMR_POLYDRAW),
+X(EMR_SETARCDIRECTION),
+X(EMR_SETMITERLIMIT),
+X(EMR_BEGINPATH),
+X(EMR_ENDPATH),
+X(EMR_CLOSEFIGURE),
+X(EMR_FILLPATH),
+X(EMR_STROKEANDFILLPATH),
+X(EMR_STROKEPATH),
+X(EMR_FLATTENPATH),
+X(EMR_WIDENPATH),
+X(EMR_SELECTCLIPPATH),
+X(EMR_ABORTPATH),
+X(EMR_GDICOMMENT),
+X(EMR_FILLRGN),
+X(EMR_FRAMERGN),
+X(EMR_INVERTRGN),
+X(EMR_PAINTRGN),
+X(EMR_EXTSELECTCLIPRGN),
+X(EMR_BITBLT),
+X(EMR_STRETCHBLT),
+X(EMR_MASKBLT),
+X(EMR_PLGBLT),
+X(EMR_SETDIBITSTODEVICE),
+X(EMR_STRETCHDIBITS),
+X(EMR_EXTCREATEFONTINDIRECTW),
+X(EMR_EXTTEXTOUTA),
+X(EMR_EXTTEXTOUTW),
+X(EMR_POLYBEZIER16),
+X(EMR_POLYGON16),
+X(EMR_POLYLINE16),
+X(EMR_POLYBEZIERTO16),
+X(EMR_POLYLINETO16),
+X(EMR_POLYPOLYLINE16),
+X(EMR_POLYPOLYGON16),
+X(EMR_POLYDRAW16),
+X(EMR_CREATEMONOBRUSH),
+X(EMR_CREATEDIBPATTERNBRUSHPT),
+X(EMR_EXTCREATEPEN),
+X(EMR_POLYTEXTOUTA),
+X(EMR_POLYTEXTOUTW),
+X(EMR_SETICMMODE),
+X(EMR_CREATECOLORSPACE),
+X(EMR_SETCOLORSPACE),
+X(EMR_DELETECOLORSPACE),
+X(EMR_GLSRECORD),
+X(EMR_GLSBOUNDEDRECORD),
+X(EMR_PIXELFORMAT),
+X(EMR_DRAWESCAPE),
+X(EMR_EXTESCAPE),
+X(EMR_STARTDOC),
+X(EMR_SMALLTEXTOUT),
+X(EMR_FORCEUFIMAPPING),
+X(EMR_NAMEDESCAPE),
+X(EMR_COLORCORRECTPALETTE),
+X(EMR_SETICMPROFILEA),
+X(EMR_SETICMPROFILEW),
+X(EMR_ALPHABLEND),
+X(EMR_SETLAYOUT),
+X(EMR_TRANSPARENTBLT),
+X(EMR_RESERVED_117),
+X(EMR_GRADIENTFILL),
+X(EMR_SETLINKEDUFI),
+X(EMR_SETTEXTJUSTIFICATION),
+X(EMR_COLORMATCHTOTARGETW),
+X(EMR_CREATECOLORSPACEW)
+#undef X
+};
+
+/****************************************************************************
+ * get_emr_name
+ */
+static const char *get_emr_name(DWORD type)
+{
+ int i;
+ for(i = 0; i < sizeof(emr_names) / sizeof(emr_names[0]); i++)
+ if(type == emr_names[i].type) return emr_names[i].name;
+ TRACE("Unknown record type %ld\n", type);
+ return NULL;
+}
/****************************************************************************
* EMF_Create_HENHMETAFILE
@@ -500,7 +640,7 @@
if ( IS_WIN9X() && emr_produces_output(type) )
EMF_Update_MF_Xform(hdc, info);
- TRACE(" type=%d\n", type);
+ TRACE("record %s\n", get_emr_name(type));
switch(type)
{
case EMR_HEADER:
@@ -574,14 +714,18 @@
case EMR_RESTOREDC:
{
PEMRRESTOREDC pRestoreDC = (PEMRRESTOREDC) mr;
+ TRACE("EMR_RESTORE: %ld\n", pRestoreDC->iRelative);
RestoreDC(hdc, pRestoreDC->iRelative);
break;
}
case EMR_INTERSECTCLIPRECT:
{
PEMRINTERSECTCLIPRECT pClipRect = (PEMRINTERSECTCLIPRECT) mr;
- IntersectClipRect(hdc, pClipRect->rclClip.left, pClipRect->rclClip.top,
- pClipRect->rclClip.right, pClipRect->rclClip.bottom);
+ TRACE("EMR_INTERSECTCLIPRECT: rect %ld,%ld - %ld, %ld\n",
+ pClipRect->rclClip.left, pClipRect->rclClip.top,
+ pClipRect->rclClip.right, pClipRect->rclClip.bottom);
+ IntersectClipRect(hdc, pClipRect->rclClip.left, pClipRect->rclClip.top,
+ pClipRect->rclClip.right, pClipRect->rclClip.bottom);
break;
}
case EMR_SELECTOBJECT:
@@ -861,6 +1005,10 @@
rc.top = pExtTextOutW->emrtext.rcl.top;
rc.right = pExtTextOutW->emrtext.rcl.right;
rc.bottom = pExtTextOutW->emrtext.rcl.bottom;
+ TRACE("EMR_EXTTEXTOUTW: x,y = %ld, %ld. rect = %ld, %ld - %ld, %ld. flags %08lx\n",
+ pExtTextOutW->emrtext.ptlReference.x, pExtTextOutW->emrtext.ptlReference.y,
+ rc.left, rc.top, rc.right, rc.bottom, pExtTextOutW->emrtext.fOptions);
+
ExtTextOutW(hdc, pExtTextOutW->emrtext.ptlReference.x, pExtTextOutW->emrtext.ptlReference.y,
pExtTextOutW->emrtext.fOptions, &rc,
(LPWSTR)((BYTE *)mr + pExtTextOutW->emrtext.offString), pExtTextOutW->emrtext.nChars,
@@ -1446,92 +1594,80 @@
case EMR_BITBLT:
{
PEMRBITBLT pBitBlt = (PEMRBITBLT)mr;
- HDC hdcSrc = CreateCompatibleDC(hdc);
- HBRUSH hBrush, hBrushOld;
- HBITMAP hBmp = 0, hBmpOld = 0;
- BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pBitBlt->offBmiSrc);
-
- SetWorldTransform(hdcSrc, &pBitBlt->xformSrc);
- hBrush = CreateSolidBrush(pBitBlt->crBkColorSrc);
- hBrushOld = SelectObject(hdcSrc, hBrush);
- PatBlt(hdcSrc, pBitBlt->rclBounds.left, pBitBlt->rclBounds.top,
- pBitBlt->rclBounds.right - pBitBlt->rclBounds.left,
- pBitBlt->rclBounds.bottom - pBitBlt->rclBounds.top, PATCOPY);
- SelectObject(hdcSrc, hBrushOld);
- DeleteObject(hBrush);
-
- if (pBitBlt->offBmiSrc > 0)
- {
- hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
- (BYTE *)mr + pBitBlt->offBitsSrc, pbi, pBitBlt->iUsageSrc);
- hBmpOld = SelectObject(hdcSrc, hBmp);
- }
-
- BitBlt(hdc,
- pBitBlt->xDest,
- pBitBlt->yDest,
- pBitBlt->cxDest,
- pBitBlt->cyDest,
- hdcSrc,
- pBitBlt->xSrc,
- pBitBlt->ySrc,
- pBitBlt->dwRop);
-
- if (pBitBlt->offBmiSrc > 0)
- {
- SelectObject(hdcSrc, hBmpOld);
- DeleteObject(hBmp);
- }
- DeleteDC(hdcSrc);
+ if(pBitBlt->offBmiSrc == 0) { /* Record is a PatBlt */
+ PatBlt(hdc, pBitBlt->xDest, pBitBlt->yDest, pBitBlt->cxDest, pBitBlt->cyDest,
+ pBitBlt->dwRop);
+ } else { /* BitBlt */
+ HDC hdcSrc = CreateCompatibleDC(hdc);
+ HBRUSH hBrush, hBrushOld;
+ HBITMAP hBmp = 0, hBmpOld = 0;
+ BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pBitBlt->offBmiSrc);
+
+ SetWorldTransform(hdcSrc, &pBitBlt->xformSrc);
+
+ hBrush = CreateSolidBrush(pBitBlt->crBkColorSrc);
+ hBrushOld = SelectObject(hdcSrc, hBrush);
+ PatBlt(hdcSrc, pBitBlt->rclBounds.left, pBitBlt->rclBounds.top,
+ pBitBlt->rclBounds.right - pBitBlt->rclBounds.left,
+ pBitBlt->rclBounds.bottom - pBitBlt->rclBounds.top, PATCOPY);
+ SelectObject(hdcSrc, hBrushOld);
+ DeleteObject(hBrush);
+
+ hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ (BYTE *)mr + pBitBlt->offBitsSrc, pbi, pBitBlt->iUsageSrc);
+ hBmpOld = SelectObject(hdcSrc, hBmp);
+
+ BitBlt(hdc, pBitBlt->xDest, pBitBlt->yDest, pBitBlt->cxDest, pBitBlt->cyDest,
+ hdcSrc, pBitBlt->xSrc, pBitBlt->ySrc, pBitBlt->dwRop);
+
+ SelectObject(hdcSrc, hBmpOld);
+ DeleteObject(hBmp);
+ DeleteDC(hdcSrc);
+ }
break;
}
case EMR_STRETCHBLT:
{
PEMRSTRETCHBLT pStretchBlt= (PEMRSTRETCHBLT)mr;
- HDC hdcSrc = CreateCompatibleDC(hdc);
- HBRUSH hBrush, hBrushOld;
- HBITMAP hBmp = 0, hBmpOld = 0;
- BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pStretchBlt->offBmiSrc);
-
- SetWorldTransform(hdcSrc, &pStretchBlt->xformSrc);
-
- hBrush = CreateSolidBrush(pStretchBlt->crBkColorSrc);
- hBrushOld = SelectObject(hdcSrc, hBrush);
- PatBlt(hdcSrc, pStretchBlt->rclBounds.left, pStretchBlt->rclBounds.top,
- pStretchBlt->rclBounds.right - pStretchBlt->rclBounds.left,
- pStretchBlt->rclBounds.bottom - pStretchBlt->rclBounds.top, PATCOPY);
- SelectObject(hdcSrc, hBrushOld);
- DeleteObject(hBrush);
-
- if (pStretchBlt->offBmiSrc)
- {
- hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
- (BYTE *)mr + pStretchBlt->offBitsSrc, pbi, pStretchBlt->iUsageSrc);
- hBmpOld = SelectObject(hdcSrc, hBmp);
- }
- StretchBlt(hdc,
- pStretchBlt->xDest,
- pStretchBlt->yDest,
- pStretchBlt->cxDest,
- pStretchBlt->cyDest,
- hdcSrc,
- pStretchBlt->xSrc,
- pStretchBlt->ySrc,
- pStretchBlt->cxSrc,
- pStretchBlt->cySrc,
- pStretchBlt->dwRop);
-
-
- if (pStretchBlt->offBmiSrc)
- {
- SelectObject(hdcSrc, hBmpOld);
- DeleteObject(hBmp);
- }
-
- DeleteDC(hdcSrc);
+ TRACE("EMR_STRETCHBLT: %ld, %ld %ldx%ld -> %ld, %ld %ldx%ld. rop %08lx offBitsSrc %ld\n",
+ pStretchBlt->xSrc, pStretchBlt->ySrc, pStretchBlt->cxSrc, pStretchBlt->cySrc,
+ pStretchBlt->xDest, pStretchBlt->yDest, pStretchBlt->cxDest, pStretchBlt->cyDest,
+ pStretchBlt->dwRop, pStretchBlt->offBitsSrc);
+
+ if(pStretchBlt->offBmiSrc == 0) { /* Record is a PatBlt */
+ PatBlt(hdc, pStretchBlt->xDest, pStretchBlt->yDest, pStretchBlt->cxDest, pStretchBlt->cyDest,
+ pStretchBlt->dwRop);
+ } else { /* StretchBlt */
+ HDC hdcSrc = CreateCompatibleDC(hdc);
+ HBRUSH hBrush, hBrushOld;
+ HBITMAP hBmp = 0, hBmpOld = 0;
+ BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pStretchBlt->offBmiSrc);
+
+ SetWorldTransform(hdcSrc, &pStretchBlt->xformSrc);
+
+ hBrush = CreateSolidBrush(pStretchBlt->crBkColorSrc);
+ hBrushOld = SelectObject(hdcSrc, hBrush);
+ PatBlt(hdcSrc, pStretchBlt->rclBounds.left, pStretchBlt->rclBounds.top,
+ pStretchBlt->rclBounds.right - pStretchBlt->rclBounds.left,
+ pStretchBlt->rclBounds.bottom - pStretchBlt->rclBounds.top, PATCOPY);
+ SelectObject(hdcSrc, hBrushOld);
+ DeleteObject(hBrush);
+
+ hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ (BYTE *)mr + pStretchBlt->offBitsSrc, pbi, pStretchBlt->iUsageSrc);
+ hBmpOld = SelectObject(hdcSrc, hBmp);
+
+ StretchBlt(hdc, pStretchBlt->xDest, pStretchBlt->yDest, pStretchBlt->cxDest, pStretchBlt->cyDest,
+ hdcSrc, pStretchBlt->xSrc, pStretchBlt->ySrc, pStretchBlt->cxSrc, pStretchBlt->cySrc,
+ pStretchBlt->dwRop);
+
+ SelectObject(hdcSrc, hBmpOld);
+ DeleteObject(hBmp);
+ DeleteDC(hdcSrc);
+ }
break;
}
@@ -1884,6 +2020,7 @@
SIZE vp_size, win_size;
POINT vp_org, win_org;
INT mapMode = MM_TEXT;
+ COLORREF old_text_color = 0, old_bk_color = 0;
if(!lpRect)
{
@@ -1933,6 +2070,9 @@
hPen = GetCurrentObject(hdc, OBJ_PEN);
hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
hFont = GetCurrentObject(hdc, OBJ_FONT);
+
+ old_text_color = SetTextColor(hdc, RGB(0,0,0));
+ old_bk_color = SetBkColor(hdc, RGB(0xff, 0xff, 0xff));
}
info->mode = MM_TEXT;
@@ -2004,13 +2144,16 @@
while(ret && offset < emh->nBytes)
{
emr = (ENHMETARECORD *)((char *)emh + offset);
- TRACE("Calling EnumFunc with record type %ld, size %ld\n", emr->iType, emr->nSize);
+ TRACE("Calling EnumFunc with record %s, size %ld\n", get_emr_name(emr->iType), emr->nSize);
ret = (*callback)(hdc, ht, emr, emh->nHandles, (LPARAM)data);
offset += emr->nSize;
}
if (hdc)
{
+ SetBkColor(hdc, old_bk_color);
+ SetTextColor(hdc, old_text_color);
+
/* restore pen, brush and font */
SelectObject(hdc, hBrush);
SelectObject(hdc, hPen);
More information about the wine-patches
mailing list