/****************************************************************** * MFDRV_CreatePalette */ static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logPalette, int sizeofPalette) { int index; BOOL ret; METARECORD *mr; mr = HeapAlloc( GetProcessHeap(), 0, sizeof(METARECORD) + sizeofPalette - sizeof(WORD) ); mr->rdSize = (sizeof(METARECORD) + sizeofPalette - sizeof(WORD)) / sizeof(WORD); mr->rdFunction = META_CREATEPALETTE; memcpy(&(mr->rdParm), logPalette, sizeofPalette); if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) { HeapFree(GetProcessHeap(), 0, mr); return FALSE; } mr->rdSize = sizeof(METARECORD) / sizeof(WORD); mr->rdFunction = META_SELECTPALETTE; if ((index = MFDRV_AddHandle( dev, hPalette )) == -1) ret = FALSE; else { *(mr->rdParm) = index; ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)); } HeapFree(GetProcessHeap(), 0, mr); return ret; }
/*********************************************************************** * MFDRV_SetDIBitsToDeivce */ INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx, DWORD cy, INT xSrc, INT ySrc, UINT startscan, UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse ) { DWORD len, infosize, imagesize; METARECORD *mr; infosize = DIB_BitmapInfoSize(info, coloruse); imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount ); len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize; mr = HeapAlloc( GetProcessHeap(), 0, len ); if(!mr) return 0; mr->rdSize = len / 2; mr->rdFunction = META_SETDIBTODEV; mr->rdParm[0] = coloruse; mr->rdParm[1] = lines; mr->rdParm[2] = startscan; mr->rdParm[3] = (INT16)ySrc; mr->rdParm[4] = (INT16)xSrc; mr->rdParm[5] = (INT16)cy; mr->rdParm[6] = (INT16)cx; mr->rdParm[7] = (INT16)yDst; mr->rdParm[8] = (INT16)xDst; memcpy(mr->rdParm + 9, info, infosize); memcpy(mr->rdParm + 9 + infosize / 2, bits, imagesize); MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 ); HeapFree( GetProcessHeap(), 0, mr ); return lines; }
static UINT16 MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONTW *logfont) { char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)]; METARECORD *mr = (METARECORD *)&buffer; LOGFONT16 *font16; INT written; mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2; mr->rdFunction = META_CREATEFONTINDIRECT; font16 = (LOGFONT16 *)&mr->rdParm; font16->lfHeight = logfont->lfHeight; font16->lfWidth = logfont->lfWidth; font16->lfEscapement = logfont->lfEscapement; font16->lfOrientation = logfont->lfOrientation; font16->lfWeight = logfont->lfWeight; font16->lfItalic = logfont->lfItalic; font16->lfUnderline = logfont->lfUnderline; font16->lfStrikeOut = logfont->lfStrikeOut; font16->lfCharSet = logfont->lfCharSet; font16->lfOutPrecision = logfont->lfOutPrecision; font16->lfClipPrecision = logfont->lfClipPrecision; font16->lfQuality = logfont->lfQuality; font16->lfPitchAndFamily = logfont->lfPitchAndFamily; written = WideCharToMultiByte( CP_ACP, 0, logfont->lfFaceName, -1, font16->lfFaceName, LF_FACESIZE - 1, NULL, NULL ); /* Zero pad the facename buffer, so that we don't write uninitialized data to disk */ memset(font16->lfFaceName + written, 0, LF_FACESIZE - written); if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) return 0; return MFDRV_AddHandle( dev, hFont ); }
BOOL MFDRV_MetaParam0(PHYSDEV dev, short func) { char buffer[8]; METARECORD *mr = (METARECORD *)&buffer; mr->rdSize = 3; mr->rdFunction = func; return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); }
/*********************************************************************** * MFDRV_SelectObject */ static BOOL MFDRV_SelectObject( PHYSDEV dev, INT16 index) { METARECORD mr; mr.rdSize = sizeof mr / 2; mr.rdFunction = META_SELECTOBJECT; mr.rdParm[0] = index; return MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 ); }
/****************************************************************** * MFDRV_MetaParam1 */ BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1) { char buffer[8]; METARECORD *mr = (METARECORD *)&buffer; mr->rdSize = 4; mr->rdFunction = func; *(mr->rdParm) = param1; return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); }
/****************************************************************** * MFDRV_MetaParam2 */ BOOL MFDRV_MetaParam2(PHYSDEV dev, short func, short param1, short param2) { char buffer[10]; METARECORD *mr = (METARECORD *)&buffer; WORD *params = mr->rdParm; mr->rdSize = 5; mr->rdFunction = func; params[0] = param2; params[1] = param1; return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); }
/****************************************************************** * MFDRV_CreatePenIndirect */ static UINT16 MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen) { char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)]; METARECORD *mr = (METARECORD *)&buffer; mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2; mr->rdFunction = META_CREATEPENINDIRECT; memcpy(&(mr->rdParm), logpen, sizeof(*logpen)); if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) return 0; return MFDRV_AddHandle( dev, hPen ); }
BOOL MFDRV_MetaParam4(PHYSDEV dev, short func, short param1, short param2, short param3, short param4) { char buffer[14]; METARECORD *mr = (METARECORD *)&buffer; mr->rdSize = 7; mr->rdFunction = func; *(mr->rdParm) = param4; *(mr->rdParm + 1) = param3; *(mr->rdParm + 2) = param2; *(mr->rdParm + 3) = param1; return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); }
/********************************************************************** * MFDRV_PolyPolygon */ BOOL CDECL MFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polygons) { BOOL ret; DWORD len; METARECORD *mr; unsigned int i,j; POINTS *pts; INT16 totalpoint16 = 0; INT16 * pointcounts; for (i=0;i<polygons;i++) { totalpoint16 += counts[i]; } /* allocate space for all points */ pts=HeapAlloc( GetProcessHeap(), 0, sizeof(POINTS) * totalpoint16 ); pointcounts = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16) * totalpoint16 ); /* copy point counts */ for (i=0;i<polygons;i++) { pointcounts[i] = counts[i]; } /* convert all points */ for (j = totalpoint16; j--;){ pts[j].x = pt[j].x; pts[j].y = pt[j].y; } len = sizeof(METARECORD) + sizeof(WORD) + polygons*sizeof(INT16) + totalpoint16*sizeof(*pts); if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ))) { HeapFree( GetProcessHeap(), 0, pts ); HeapFree( GetProcessHeap(), 0, pointcounts ); return FALSE; } mr->rdSize = len /2; mr->rdFunction = META_POLYPOLYGON; *(mr->rdParm) = polygons; memcpy(mr->rdParm + 1, pointcounts, polygons*sizeof(INT16)); memcpy(mr->rdParm + 1+polygons, pts , totalpoint16*sizeof(*pts)); ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); HeapFree( GetProcessHeap(), 0, pts ); HeapFree( GetProcessHeap(), 0, pointcounts ); HeapFree( GetProcessHeap(), 0, mr); return ret; }
BOOL MFDRV_MetaParam6(PHYSDEV dev, short func, short param1, short param2, short param3, short param4, short param5, short param6) { char buffer[18]; METARECORD *mr = (METARECORD *)&buffer; WORD *params = mr->rdParm; mr->rdSize = 9; mr->rdFunction = func; params[0] = param6; params[1] = param5; params[2] = param4; params[3] = param3; params[4] = param2; params[5] = param1; return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); }
/*********************************************************************** * MFDRV_RealizePalette */ UINT MFDRV_RealizePalette(PHYSDEV dev, HPALETTE hPalette, BOOL dummy) { char buffer[sizeof(METARECORD) - sizeof(WORD)]; METARECORD *mr = (METARECORD *)&buffer; mr->rdSize = (sizeof(METARECORD) - sizeof(WORD)) / sizeof(WORD); mr->rdFunction = META_REALIZEPALETTE; if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * sizeof(WORD)))) return 0; /* The return value is suppose to be the number of entries in the logical palette mapped to the system palette or 0 if the function failed. Since it's not trivial here to get that kind of information and since it's of little use in the case of metafiles, we'll always return 1. */ return 1; }
/****************************************************************** * MFDRV_MetaPoly - implements Polygon and Polyline */ static BOOL MFDRV_MetaPoly(PHYSDEV dev, short func, POINTS *pt, short count) { BOOL ret; DWORD len; METARECORD *mr; len = sizeof(METARECORD) + (count * 4); if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ))) return FALSE; mr->rdSize = len / 2; mr->rdFunction = func; *(mr->rdParm) = count; memcpy(mr->rdParm + 1, pt, count * 4); ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); HeapFree( GetProcessHeap(), 0, mr); return ret; }
/****************************************************************** * MFDRV_MetaParam8 */ BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2, short param3, short param4, short param5, short param6, short param7, short param8) { char buffer[22]; METARECORD *mr = (METARECORD *)&buffer; mr->rdSize = 11; mr->rdFunction = func; *(mr->rdParm) = param8; *(mr->rdParm + 1) = param7; *(mr->rdParm + 2) = param6; *(mr->rdParm + 3) = param5; *(mr->rdParm + 4) = param4; *(mr->rdParm + 5) = param3; *(mr->rdParm + 6) = param2; *(mr->rdParm + 7) = param1; return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); }
/********************************************************************** * MFDRV_ExtEscape */ static INT MFDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data, INT cbOutput, LPVOID out_data ) { METARECORD *mr; DWORD len; INT ret; if (cbOutput) return 0; /* escapes that require output cannot work in metafiles */ len = sizeof(*mr) + sizeof(WORD) + ((cbInput + 1) & ~1); mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); mr->rdSize = len / 2; mr->rdFunction = META_ESCAPE; mr->rdParm[0] = nEscape; mr->rdParm[1] = cbInput; memcpy(&(mr->rdParm[2]), in_data, cbInput); ret = MFDRV_WriteRecord( dev, mr, len); HeapFree(GetProcessHeap(), 0, mr); return ret; }
/****************************************************************** * MFDRV_DeleteObject */ BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj ) { METARECORD mr; METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; INT16 index; BOOL ret = TRUE; index = MFDRV_FindObject(dev, obj); if( index < 0 ) return 0; mr.rdSize = sizeof mr / 2; mr.rdFunction = META_DELETEOBJECT; mr.rdParm[0] = index; if(!MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 )) ret = FALSE; physDev->handles[index] = 0; physDev->cur_handles--; return ret; }
/*********************************************************************** * MFDRV_StretchDIBits */ INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits, const BITMAPINFO *info, UINT wUsage, DWORD dwRop ) { DWORD len, infosize, imagesize; METARECORD *mr; infosize = DIB_BitmapInfoSize(info, wUsage); imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount ); len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize; mr = HeapAlloc( GetProcessHeap(), 0, len ); if(!mr) return 0; mr->rdSize = len / 2; mr->rdFunction = META_STRETCHDIB; mr->rdParm[0] = LOWORD(dwRop); mr->rdParm[1] = HIWORD(dwRop); mr->rdParm[2] = wUsage; mr->rdParm[3] = (INT16)heightSrc; mr->rdParm[4] = (INT16)widthSrc; mr->rdParm[5] = (INT16)ySrc; mr->rdParm[6] = (INT16)xSrc; mr->rdParm[7] = (INT16)heightDst; mr->rdParm[8] = (INT16)widthDst; mr->rdParm[9] = (INT16)yDst; mr->rdParm[10] = (INT16)xDst; memcpy(mr->rdParm + 11, info, infosize); memcpy(mr->rdParm + 11 + infosize / 2, bits, imagesize); MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 ); HeapFree( GetProcessHeap(), 0, mr ); return heightSrc; }
INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush ) { DWORD size; METARECORD *mr; LOGBRUSH logbrush; METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev; BOOL r; if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1; switch(logbrush.lbStyle) { case BS_SOLID: case BS_NULL: case BS_HATCHED: { LOGBRUSH16 lb16; lb16.lbStyle = logbrush.lbStyle; lb16.lbColor = logbrush.lbColor; lb16.lbHatch = logbrush.lbHatch; size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2; mr = HeapAlloc( GetProcessHeap(), 0, size ); mr->rdSize = size / 2; mr->rdFunction = META_CREATEBRUSHINDIRECT; memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16)); break; } case BS_PATTERN: { BITMAP bm; BITMAPINFO *info; DWORD bmSize; COLORREF cref; GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm); if(bm.bmBitsPixel != 1 || bm.bmPlanes != 1) { FIXME("Trying to store a colour pattern brush\n"); goto done; } bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, DIB_PAL_COLORS); size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) + sizeof(RGBQUAD) + bmSize; mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); if(!mr) goto done; mr->rdFunction = META_DIBCREATEPATTERNBRUSH; mr->rdSize = size / 2; mr->rdParm[0] = BS_PATTERN; mr->rdParm[1] = DIB_RGB_COLORS; info = (BITMAPINFO *)(mr->rdParm + 2); info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); info->bmiHeader.biWidth = bm.bmWidth; info->bmiHeader.biHeight = bm.bmHeight; info->bmiHeader.biPlanes = 1; info->bmiHeader.biBitCount = 1; info->bmiHeader.biSizeImage = bmSize; GetBitmapBits((HANDLE)logbrush.lbHatch, bm.bmHeight * BITMAP_GetWidthBytes (bm.bmWidth, bm.bmBitsPixel), (LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD)); /* Change the padding to be DIB compatible if needed */ if(bm.bmWidth & 31) MFDRV_PadTo32((LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD), bm.bmWidth, bm.bmHeight); /* BMP and DIB have opposite row order conventions */ MFDRV_Reverse((LPBYTE)info + sizeof(BITMAPINFO) + sizeof(RGBQUAD), bm.bmWidth, bm.bmHeight); cref = GetTextColor(physDev->hdc); info->bmiColors[0].rgbRed = GetRValue(cref); info->bmiColors[0].rgbGreen = GetGValue(cref); info->bmiColors[0].rgbBlue = GetBValue(cref); info->bmiColors[0].rgbReserved = 0; cref = GetBkColor(physDev->hdc); info->bmiColors[1].rgbRed = GetRValue(cref); info->bmiColors[1].rgbGreen = GetGValue(cref); info->bmiColors[1].rgbBlue = GetBValue(cref); info->bmiColors[1].rgbReserved = 0; break; } case BS_DIBPATTERN: { BITMAPINFO *info; DWORD bmSize, biSize; info = GlobalLock16((HGLOBAL16)logbrush.lbHatch); if (info->bmiHeader.biCompression) bmSize = info->bmiHeader.biSizeImage; else bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biBitCount); biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor)); size = sizeof(METARECORD) + biSize + bmSize + 2; mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); if(!mr) goto done; mr->rdFunction = META_DIBCREATEPATTERNBRUSH; mr->rdSize = size / 2; *(mr->rdParm) = logbrush.lbStyle; *(mr->rdParm + 1) = LOWORD(logbrush.lbColor); memcpy(mr->rdParm + 2, info, biSize + bmSize); break; } default: FIXME("Unkonwn brush style %x\n", logbrush.lbStyle); return 0; } r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); HeapFree(GetProcessHeap(), 0, mr); if( !r ) return -1; done: return MFDRV_AddHandle( dev, hBrush ); }
/****************************************************************** * MFDRV_CreateRegion * * For explanation of the format of the record see MF_Play_MetaCreateRegion in * objects/metafile.c */ static INT16 MFDRV_CreateRegion(PHYSDEV dev, HRGN hrgn) { DWORD len; METARECORD *mr; RGNDATA *rgndata; RECT *pCurRect, *pEndRect; WORD Bands = 0, MaxBands = 0; WORD *Param, *StartBand; BOOL ret; if (!(len = GetRegionData( hrgn, 0, NULL ))) return -1; if( !(rgndata = HeapAlloc( GetProcessHeap(), 0, len )) ) { WARN("Can't alloc rgndata buffer\n"); return -1; } GetRegionData( hrgn, len, rgndata ); /* Overestimate of length: * Assume every rect is a separate band -> 6 WORDs per rect */ len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12); if( !(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len )) ) { WARN("Can't alloc METARECORD buffer\n"); HeapFree( GetProcessHeap(), 0, rgndata ); return -1; } Param = mr->rdParm + 11; StartBand = NULL; pEndRect = (RECT *)rgndata->Buffer + rgndata->rdh.nCount; for(pCurRect = (RECT *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++) { if( StartBand && pCurRect->top == *(StartBand + 1) ) { *Param++ = pCurRect->left; *Param++ = pCurRect->right; } else { if(StartBand) { *StartBand = Param - StartBand - 3; *Param++ = *StartBand; if(*StartBand > MaxBands) MaxBands = *StartBand; Bands++; } StartBand = Param++; *Param++ = pCurRect->top; *Param++ = pCurRect->bottom; *Param++ = pCurRect->left; *Param++ = pCurRect->right; } } len = Param - (WORD *)mr; mr->rdParm[0] = 0; mr->rdParm[1] = 6; mr->rdParm[2] = 0x1234; mr->rdParm[3] = 0; mr->rdParm[4] = len * 2; mr->rdParm[5] = Bands; mr->rdParm[6] = MaxBands; mr->rdParm[7] = rgndata->rdh.rcBound.left; mr->rdParm[8] = rgndata->rdh.rcBound.top; mr->rdParm[9] = rgndata->rdh.rcBound.right; mr->rdParm[10] = rgndata->rdh.rcBound.bottom; mr->rdFunction = META_CREATEREGION; mr->rdSize = len / 2; ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2 ); HeapFree( GetProcessHeap(), 0, mr ); HeapFree( GetProcessHeap(), 0, rgndata ); if(!ret) { WARN("MFDRV_WriteRecord failed\n"); return -1; } return MFDRV_AddHandle( dev, hrgn ); }
BOOL MFDRV_StretchBlt( PHYSDEV devDst, INT xDst, INT yDst, INT widthDst, INT heightDst, PHYSDEV devSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop ) { BOOL ret; DWORD len; METARECORD *mr; BITMAP BM; METAFILEDRV_PDEVICE *physDevSrc = (METAFILEDRV_PDEVICE *)devSrc; #ifdef STRETCH_VIA_DIB LPBITMAPINFOHEADER lpBMI; WORD nBPP; #endif HBITMAP hBitmap = GetCurrentObject(physDevSrc->hdc, OBJ_BITMAP); if (GetObjectW(hBitmap, sizeof(BITMAP), &BM) != sizeof(BITMAP)) { WARN("bad bitmap object %p passed for hdc %p\n", hBitmap, physDevSrc->hdc); return FALSE; } #ifdef STRETCH_VIA_DIB nBPP = BM.bmPlanes * BM.bmBitsPixel; if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */ len = sizeof(METARECORD) + 10 * sizeof(INT16) + sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD) + DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight; if (!(mr = HeapAlloc( GetProcessHeap(), 0, len))) return FALSE; mr->rdFunction = META_DIBSTRETCHBLT; lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10); lpBMI->biSize = sizeof(BITMAPINFOHEADER); lpBMI->biWidth = BM.bmWidth; lpBMI->biHeight = BM.bmHeight; lpBMI->biPlanes = 1; lpBMI->biBitCount = nBPP; lpBMI->biSizeImage = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * lpBMI->biHeight; lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0; lpBMI->biCompression = BI_RGB; lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSX),3937,100); lpBMI->biYPelsPerMeter = MulDiv(GetDeviceCaps(physDevSrc->hdc,LOGPIXELSY),3937,100); lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */ TRACE("MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n", len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(physDevSrc->hdc, LOGPIXELSY)); if (GetDIBits(physDevSrc->hdc, hBitmap, 0, (UINT)lpBMI->biHeight, (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI, DIB_RGB_COLORS ), (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS)) #else len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight; if (!(mr = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE; mr->rdFunction = META_STRETCHBLT; *(mr->rdParm +10) = BM.bmWidth; *(mr->rdParm +11) = BM.bmHeight; *(mr->rdParm +12) = BM.bmWidthBytes; *(mr->rdParm +13) = BM.bmPlanes; *(mr->rdParm +14) = BM.bmBitsPixel; TRACE("len = %ld rop=%lx\n", len, rop); if (GetBitmapBits( hBitmap, BM.bmWidthBytes * BM.bmHeight, mr->rdParm + 15)) #endif { mr->rdSize = len / sizeof(INT16); *(mr->rdParm) = LOWORD(rop); *(mr->rdParm + 1) = HIWORD(rop); *(mr->rdParm + 2) = heightSrc; *(mr->rdParm + 3) = widthSrc; *(mr->rdParm + 4) = ySrc; *(mr->rdParm + 5) = xSrc; *(mr->rdParm + 6) = heightDst; *(mr->rdParm + 7) = widthDst; *(mr->rdParm + 8) = yDst; *(mr->rdParm + 9) = xDst; ret = MFDRV_WriteRecord( devDst, mr, mr->rdSize * 2); } else ret = FALSE; HeapFree( GetProcessHeap(), 0, mr); return ret; }
INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush ) { DWORD size; METARECORD *mr; LOGBRUSH logbrush; BOOL r; if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1; switch(logbrush.lbStyle) { case BS_SOLID: case BS_NULL: case BS_HATCHED: { LOGBRUSH16 lb16; lb16.lbStyle = logbrush.lbStyle; lb16.lbColor = logbrush.lbColor; lb16.lbHatch = logbrush.lbHatch; size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2; mr = HeapAlloc( GetProcessHeap(), 0, size ); mr->rdSize = size / 2; mr->rdFunction = META_CREATEBRUSHINDIRECT; memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16)); break; } case BS_PATTERN: { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer; struct gdi_image_bits bits; COLORREF cref; if (!get_bitmap_image( (HANDLE)logbrush.lbHatch, src_info, &bits )) goto done; if (src_info->bmiHeader.biBitCount != 1) { FIXME("Trying to store a colour pattern brush\n"); if (bits.free) bits.free( &bits ); goto done; } size = FIELD_OFFSET( METARECORD, rdParm[2] ) + FIELD_OFFSET( BITMAPINFO, bmiColors[2] ) + src_info->bmiHeader.biSizeImage; if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) { if (bits.free) bits.free( &bits ); goto done; } mr->rdFunction = META_DIBCREATEPATTERNBRUSH; mr->rdSize = size / 2; mr->rdParm[0] = BS_PATTERN; mr->rdParm[1] = DIB_RGB_COLORS; dst_info = (BITMAPINFO *)(mr->rdParm + 2); dst_info->bmiHeader = src_info->bmiHeader; dst_info->bmiHeader.biClrUsed = 0; cref = GetTextColor( dev->hdc ); dst_info->bmiColors[0].rgbRed = GetRValue(cref); dst_info->bmiColors[0].rgbGreen = GetGValue(cref); dst_info->bmiColors[0].rgbBlue = GetBValue(cref); dst_info->bmiColors[0].rgbReserved = 0; cref = GetBkColor( dev->hdc ); dst_info->bmiColors[1].rgbRed = GetRValue(cref); dst_info->bmiColors[1].rgbGreen = GetGValue(cref); dst_info->bmiColors[1].rgbBlue = GetBValue(cref); dst_info->bmiColors[1].rgbReserved = 0; /* always return a bottom-up DIB */ if (dst_info->bmiHeader.biHeight < 0) { int i, width_bytes = get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount ); char *dst_ptr = (char *)&dst_info->bmiColors[2]; dst_info->bmiHeader.biHeight = -dst_info->bmiHeader.biHeight; dst_ptr += (dst_info->bmiHeader.biHeight - 1) * width_bytes; for (i = 0; i < dst_info->bmiHeader.biHeight; i++, dst_ptr -= width_bytes) memcpy( dst_ptr, (char *)bits.ptr + i * width_bytes, width_bytes ); } else memcpy( &dst_info->bmiColors[2], bits.ptr, dst_info->bmiHeader.biSizeImage ); if (bits.free) bits.free( &bits ); break; } case BS_DIBPATTERN: { BITMAPINFO *info; DWORD bmSize, biSize; info = GlobalLock( (HGLOBAL)logbrush.lbHatch ); if (info->bmiHeader.biCompression) bmSize = info->bmiHeader.biSizeImage; else bmSize = get_dib_image_size( info ); biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor)); size = sizeof(METARECORD) + biSize + bmSize + 2; mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); if (!mr) { GlobalUnlock( (HGLOBAL)logbrush.lbHatch ); goto done; } mr->rdFunction = META_DIBCREATEPATTERNBRUSH; mr->rdSize = size / 2; *(mr->rdParm) = logbrush.lbStyle; *(mr->rdParm + 1) = LOWORD(logbrush.lbColor); memcpy(mr->rdParm + 2, info, biSize + bmSize); GlobalUnlock( (HGLOBAL)logbrush.lbHatch ); break; } default: FIXME("Unkonwn brush style %x\n", logbrush.lbStyle); return 0; } r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); HeapFree(GetProcessHeap(), 0, mr); if( !r ) return -1; done: return MFDRV_AddHandle( dev, hBrush ); }
INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush ) { DWORD size; METARECORD *mr; LOGBRUSH logbrush; BOOL r; if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1; switch(logbrush.lbStyle) { case BS_SOLID: case BS_NULL: case BS_HATCHED: { LOGBRUSH16 lb16; lb16.lbStyle = logbrush.lbStyle; lb16.lbColor = logbrush.lbColor; lb16.lbHatch = logbrush.lbHatch; size = sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2; mr = HeapAlloc( GetProcessHeap(), 0, size ); mr->rdSize = size / 2; mr->rdFunction = META_CREATEBRUSHINDIRECT; memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16)); break; } case BS_PATTERN: case BS_DIBPATTERN: { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer; DWORD info_size; char *dst_ptr; void *bits; UINT usage; if (!get_brush_bitmap_info( hBrush, src_info, &bits, &usage )) goto done; info_size = get_dib_info_size( src_info, usage ); size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + src_info->bmiHeader.biSizeImage; if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) goto done; mr->rdFunction = META_DIBCREATEPATTERNBRUSH; mr->rdSize = size / 2; mr->rdParm[0] = logbrush.lbStyle; mr->rdParm[1] = usage; dst_info = (BITMAPINFO *)(mr->rdParm + 2); memcpy( dst_info, src_info, info_size ); if (dst_info->bmiHeader.biClrUsed == 1 << dst_info->bmiHeader.biBitCount) dst_info->bmiHeader.biClrUsed = 0; dst_ptr = (char *)dst_info + info_size; /* always return a bottom-up DIB */ if (dst_info->bmiHeader.biHeight < 0) { int i, width_bytes = get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount ); dst_info->bmiHeader.biHeight = -dst_info->bmiHeader.biHeight; dst_ptr += (dst_info->bmiHeader.biHeight - 1) * width_bytes; for (i = 0; i < dst_info->bmiHeader.biHeight; i++, dst_ptr -= width_bytes) memcpy( dst_ptr, (char *)bits + i * width_bytes, width_bytes ); } else memcpy( dst_ptr, bits, src_info->bmiHeader.biSizeImage ); break; } default: FIXME("Unkonwn brush style %x\n", logbrush.lbStyle); return 0; } r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2); HeapFree(GetProcessHeap(), 0, mr); if( !r ) return -1; done: return MFDRV_AddHandle( dev, hBrush ); }