Implement playing of EMR_BITBLT, EMR_STRETCHBLT, EMR_MASKBLT,
EMR_PLGBLT, EMR_SETDIBITSTODEVICE, EMR_POLYTEXTOUTA, EMR_POLYTEXTOUTW,
EMR_FILLRGN, EMR_FRAMERGN, EMR_INVERTRGN, EMR_PAINTRGN enhanced
metafile record types according to specs.
diff --git a/objects/enhmetafile.c b/objects/enhmetafile.c
index 9a9697e..b11df0f 100644
--- a/objects/enhmetafile.c
+++ b/objects/enhmetafile.c
@@ -1185,7 +1185,7 @@
PEMRCREATEMONOBRUSH pCreateMonoBrush = (PEMRCREATEMONOBRUSH)mr;
BITMAPINFO *pbi = (BITMAPINFO *)((BYTE *)mr + pCreateMonoBrush->offBmi);
HBITMAP hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
- (BYTE *)mr + pCreateMonoBrush->offBits, pbi, 0);
+ (BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage);
(handletable->objectHandle)[pCreateMonoBrush->ihBrush] = CreatePatternBrush(hBmp);
/* CreatePatternBrush created a copy of the bitmap */
DeleteObject(hBmp);
@@ -1193,17 +1193,316 @@
}
case EMR_BITBLT:
+ {
+ PEMRBITBLT pBitBlt = (PEMRBITBLT)mr;
+ HDC hdcSrc = CreateCompatibleDC(hdc);
+ HBRUSH hBrush, hBrushOld;
+ HBITMAP hBmp, hBmpOld;
+ 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, hBmpOld;
+ 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;
+ }
+
case EMR_MASKBLT:
+ {
+ PEMRMASKBLT pMaskBlt= (PEMRMASKBLT)mr;
+ HDC hdcSrc = CreateCompatibleDC(hdc);
+ HBRUSH hBrush, hBrushOld;
+ HBITMAP hBmp, hBmpOld, hBmpMask;
+ BITMAPINFO *pbi;
+
+ SetWorldTransform(hdcSrc, &pMaskBlt->xformSrc);
+
+ hBrush = CreateSolidBrush(pMaskBlt->crBkColorSrc);
+ hBrushOld = SelectObject(hdcSrc, hBrush);
+ PatBlt(hdcSrc, pMaskBlt->rclBounds.left, pMaskBlt->rclBounds.top,
+ pMaskBlt->rclBounds.right - pMaskBlt->rclBounds.left,
+ pMaskBlt->rclBounds.bottom - pMaskBlt->rclBounds.top, PATCOPY);
+ SelectObject(hdcSrc, hBrushOld);
+ DeleteObject(hBrush);
+
+ pbi = (BITMAPINFO *)((BYTE *)mr + pMaskBlt->offBmiMask);
+ hBmpMask = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ (BYTE *)mr + pMaskBlt->offBitsMask, pbi, pMaskBlt->iUsageMask);
+
+ pbi = (BITMAPINFO *)((BYTE *)mr + pMaskBlt->offBmiSrc);
+ hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ (BYTE *)mr + pMaskBlt->offBitsSrc, pbi, pMaskBlt->iUsageSrc);
+ hBmpOld = SelectObject(hdcSrc, hBmp);
+ MaskBlt(hdc,
+ pMaskBlt->xDest,
+ pMaskBlt->yDest,
+ pMaskBlt->cxDest,
+ pMaskBlt->cyDest,
+ hdcSrc,
+ pMaskBlt->xSrc,
+ pMaskBlt->ySrc,
+ hBmpMask,
+ pMaskBlt->xMask,
+ pMaskBlt->yMask,
+ pMaskBlt->dwRop);
+ SelectObject(hdcSrc, hBmpOld);
+ DeleteObject(hBmp);
+ DeleteObject(hBmpMask);
+ DeleteDC(hdcSrc);
+ break;
+ }
+
case EMR_PLGBLT:
+ {
+ PEMRPLGBLT pPlgBlt= (PEMRPLGBLT)mr;
+ HDC hdcSrc = CreateCompatibleDC(hdc);
+ HBRUSH hBrush, hBrushOld;
+ HBITMAP hBmp, hBmpOld, hBmpMask;
+ BITMAPINFO *pbi;
+ POINT pts[3];
+
+ SetWorldTransform(hdcSrc, &pPlgBlt->xformSrc);
+
+ pts[0].x = pPlgBlt->aptlDst[0].x; pts[0].y = pPlgBlt->aptlDst[0].y;
+ pts[1].x = pPlgBlt->aptlDst[1].x; pts[1].y = pPlgBlt->aptlDst[1].y;
+ pts[2].x = pPlgBlt->aptlDst[2].x; pts[2].y = pPlgBlt->aptlDst[2].y;
+
+ hBrush = CreateSolidBrush(pPlgBlt->crBkColorSrc);
+ hBrushOld = SelectObject(hdcSrc, hBrush);
+ PatBlt(hdcSrc, pPlgBlt->rclBounds.left, pPlgBlt->rclBounds.top,
+ pPlgBlt->rclBounds.right - pPlgBlt->rclBounds.left,
+ pPlgBlt->rclBounds.bottom - pPlgBlt->rclBounds.top, PATCOPY);
+ SelectObject(hdcSrc, hBrushOld);
+ DeleteObject(hBrush);
+
+ pbi = (BITMAPINFO *)((BYTE *)mr + pPlgBlt->offBmiMask);
+ hBmpMask = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ (BYTE *)mr + pPlgBlt->offBitsMask, pbi, pPlgBlt->iUsageMask);
+
+ pbi = (BITMAPINFO *)((BYTE *)mr + pPlgBlt->offBmiSrc);
+ hBmp = CreateDIBitmap(0, (BITMAPINFOHEADER *)pbi, CBM_INIT,
+ (BYTE *)mr + pPlgBlt->offBitsSrc, pbi, pPlgBlt->iUsageSrc);
+ hBmpOld = SelectObject(hdcSrc, hBmp);
+ PlgBlt(hdc,
+ pts,
+ hdcSrc,
+ pPlgBlt->xSrc,
+ pPlgBlt->ySrc,
+ pPlgBlt->cxSrc,
+ pPlgBlt->cySrc,
+ hBmpMask,
+ pPlgBlt->xMask,
+ pPlgBlt->yMask);
+ SelectObject(hdcSrc, hBmpOld);
+ DeleteObject(hBmp);
+ DeleteObject(hBmpMask);
+ DeleteDC(hdcSrc);
+ break;
+ }
+
case EMR_SETDIBITSTODEVICE:
- case EMR_POLYDRAW16:
+ {
+ PEMRSETDIBITSTODEVICE pSetDIBitsToDevice = (PEMRSETDIBITSTODEVICE)mr;
+
+ SetDIBitsToDevice(hdc,
+ pSetDIBitsToDevice->xDest,
+ pSetDIBitsToDevice->yDest,
+ pSetDIBitsToDevice->cxSrc,
+ pSetDIBitsToDevice->cySrc,
+ pSetDIBitsToDevice->xSrc,
+ pSetDIBitsToDevice->ySrc,
+ pSetDIBitsToDevice->iStartScan,
+ pSetDIBitsToDevice->cScans,
+ (BYTE *)mr + pSetDIBitsToDevice->offBitsSrc,
+ (BITMAPINFO *)((BYTE *)mr + pSetDIBitsToDevice->offBmiSrc),
+ pSetDIBitsToDevice->iUsageSrc);
+ break;
+ }
+
case EMR_POLYTEXTOUTA:
+ {
+ PEMRPOLYTEXTOUTA pPolyTextOutA = (PEMRPOLYTEXTOUTA)mr;
+ POLYTEXTA *polytextA = HeapAlloc(GetProcessHeap(), 0, pPolyTextOutA->cStrings * sizeof(POLYTEXTA));
+ LONG i;
+ XFORM xform, xformOld;
+ int gModeOld;
+
+ gModeOld = SetGraphicsMode(hdc, pPolyTextOutA->iGraphicsMode);
+ GetWorldTransform(hdc, &xformOld);
+
+ xform.eM11 = pPolyTextOutA->exScale;
+ xform.eM12 = 0.0;
+ xform.eM21 = 0.0;
+ xform.eM22 = pPolyTextOutA->eyScale;
+ xform.eDx = 0.0;
+ xform.eDy = 0.0;
+ SetWorldTransform(hdc, &xform);
+
+ /* Set up POLYTEXTA structures */
+ for(i = 0; i < pPolyTextOutA->cStrings; i++)
+ {
+ polytextA[i].x = pPolyTextOutA->aemrtext[i].ptlReference.x;
+ polytextA[i].y = pPolyTextOutA->aemrtext[i].ptlReference.y;
+ polytextA[i].n = pPolyTextOutA->aemrtext[i].nChars;
+ polytextA[i].lpstr = (LPSTR)((BYTE *)mr + pPolyTextOutA->aemrtext[i].offString);
+ polytextA[i].uiFlags = pPolyTextOutA->aemrtext[i].fOptions;
+ polytextA[i].rcl.left = pPolyTextOutA->aemrtext[i].rcl.left;
+ polytextA[i].rcl.right = pPolyTextOutA->aemrtext[i].rcl.right;
+ polytextA[i].rcl.top = pPolyTextOutA->aemrtext[i].rcl.top;
+ polytextA[i].rcl.bottom = pPolyTextOutA->aemrtext[i].rcl.bottom;
+ polytextA[i].pdx = (int *)((BYTE *)mr + pPolyTextOutA->aemrtext[i].offDx);
+ }
+ PolyTextOutA(hdc, polytextA, pPolyTextOutA->cStrings);
+ HeapFree(GetProcessHeap(), 0, polytextA);
+
+ SetWorldTransform(hdc, &xformOld);
+ SetGraphicsMode(hdc, gModeOld);
+ break;
+ }
+
case EMR_POLYTEXTOUTW:
+ {
+ PEMRPOLYTEXTOUTW pPolyTextOutW = (PEMRPOLYTEXTOUTW)mr;
+ POLYTEXTW *polytextW = HeapAlloc(GetProcessHeap(), 0, pPolyTextOutW->cStrings * sizeof(POLYTEXTW));
+ LONG i;
+ XFORM xform, xformOld;
+ int gModeOld;
+
+ gModeOld = SetGraphicsMode(hdc, pPolyTextOutW->iGraphicsMode);
+ GetWorldTransform(hdc, &xformOld);
+
+ xform.eM11 = pPolyTextOutW->exScale;
+ xform.eM12 = 0.0;
+ xform.eM21 = 0.0;
+ xform.eM22 = pPolyTextOutW->eyScale;
+ xform.eDx = 0.0;
+ xform.eDy = 0.0;
+ SetWorldTransform(hdc, &xform);
+
+ /* Set up POLYTEXTW structures */
+ for(i = 0; i < pPolyTextOutW->cStrings; i++)
+ {
+ polytextW[i].x = pPolyTextOutW->aemrtext[i].ptlReference.x;
+ polytextW[i].y = pPolyTextOutW->aemrtext[i].ptlReference.y;
+ polytextW[i].n = pPolyTextOutW->aemrtext[i].nChars;
+ polytextW[i].lpstr = (LPWSTR)((BYTE *)mr + pPolyTextOutW->aemrtext[i].offString);
+ polytextW[i].uiFlags = pPolyTextOutW->aemrtext[i].fOptions;
+ polytextW[i].rcl.left = pPolyTextOutW->aemrtext[i].rcl.left;
+ polytextW[i].rcl.right = pPolyTextOutW->aemrtext[i].rcl.right;
+ polytextW[i].rcl.top = pPolyTextOutW->aemrtext[i].rcl.top;
+ polytextW[i].rcl.bottom = pPolyTextOutW->aemrtext[i].rcl.bottom;
+ polytextW[i].pdx = (int *)((BYTE *)mr + pPolyTextOutW->aemrtext[i].offDx);
+ }
+ PolyTextOutW(hdc, polytextW, pPolyTextOutW->cStrings);
+ HeapFree(GetProcessHeap(), 0, polytextW);
+
+ SetWorldTransform(hdc, &xformOld);
+ SetGraphicsMode(hdc, gModeOld);
+ break;
+ }
+
case EMR_FILLRGN:
+ {
+ PEMRFILLRGN pFillRgn = (PEMRFILLRGN)mr;
+ HRGN hRgn = ExtCreateRegion(NULL, pFillRgn->cbRgnData, (RGNDATA *)pFillRgn->RgnData);
+ FillRgn(hdc,
+ hRgn,
+ (handletable->objectHandle)[pFillRgn->ihBrush]);
+ DeleteObject(hRgn);
+ break;
+ }
+
case EMR_FRAMERGN:
+ {
+ PEMRFRAMERGN pFrameRgn = (PEMRFRAMERGN)mr;
+ HRGN hRgn = ExtCreateRegion(NULL, pFrameRgn->cbRgnData, (RGNDATA *)pFrameRgn->RgnData);
+ FrameRgn(hdc,
+ hRgn,
+ (handletable->objectHandle)[pFrameRgn->ihBrush],
+ pFrameRgn->szlStroke.cx,
+ pFrameRgn->szlStroke.cy);
+ DeleteObject(hRgn);
+ break;
+ }
+
case EMR_INVERTRGN:
+ {
+ PEMRINVERTRGN pInvertRgn = (PEMRINVERTRGN)mr;
+ HRGN hRgn = ExtCreateRegion(NULL, pInvertRgn->cbRgnData, (RGNDATA *)pInvertRgn->RgnData);
+ InvertRgn(hdc, hRgn);
+ DeleteObject(hRgn);
+ break;
+ }
+
case EMR_PAINTRGN:
+ {
+ PEMRPAINTRGN pPaintRgn = (PEMRPAINTRGN)mr;
+ HRGN hRgn = ExtCreateRegion(NULL, pPaintRgn->cbRgnData, (RGNDATA *)pPaintRgn->RgnData);
+ PaintRgn(hdc, hRgn);
+ DeleteObject(hRgn);
+ break;
+ }
+
+ case EMR_POLYDRAW16:
case EMR_GLSRECORD:
case EMR_GLSBOUNDEDRECORD:
default: