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.
This commit is contained in:
Dmitry Timoshkov 2001-02-12 19:34:07 +00:00 committed by Alexandre Julliard
parent 935677ab04
commit c5276fd37f
1 changed files with 301 additions and 2 deletions

View File

@ -1185,7 +1185,7 @@ BOOL WINAPI PlayEnhMetaFileRecord(
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 @@ BOOL WINAPI PlayEnhMetaFileRecord(
}
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: