2 * GDI bit-blit operations
4 * Copyright 1993, 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "mfdrv/metafiledrv.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
28 /***********************************************************************
31 BOOL
MFDRV_PatBlt( PHYSDEV dev
, struct bitblt_coords
*dst
, DWORD rop
)
33 MFDRV_MetaParam6( dev
, META_PATBLT
, dst
->log_x
, dst
->log_y
, dst
->log_width
, dst
->log_height
,
34 HIWORD(rop
), LOWORD(rop
) );
39 /***********************************************************************
41 * this function contains TWO ways for processing StretchBlt in metafiles,
42 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
43 * via #define STRETCH_VIA_DIB
45 #define STRETCH_VIA_DIB
47 BOOL
MFDRV_StretchBlt( PHYSDEV devDst
, struct bitblt_coords
*dst
,
48 PHYSDEV devSrc
, struct bitblt_coords
*src
, DWORD rop
)
54 #ifdef STRETCH_VIA_DIB
55 LPBITMAPINFOHEADER lpBMI
;
58 HBITMAP hBitmap
= GetCurrentObject(devSrc
->hdc
, OBJ_BITMAP
);
60 if (devSrc
->funcs
== devDst
->funcs
) return FALSE
; /* can't use a metafile DC as source */
62 if (GetObjectW(hBitmap
, sizeof(BITMAP
), &BM
) != sizeof(BITMAP
))
64 WARN("bad bitmap object %p passed for hdc %p\n", hBitmap
, devSrc
->hdc
);
67 #ifdef STRETCH_VIA_DIB
68 nBPP
= BM
.bmPlanes
* BM
.bmBitsPixel
;
69 if(nBPP
> 8) nBPP
= 24; /* FIXME Can't get 16bpp to work for some reason */
70 len
= sizeof(METARECORD
) + 10 * sizeof(INT16
)
71 + sizeof(BITMAPINFOHEADER
) + (nBPP
<= 8 ? 1 << nBPP
: 0) * sizeof(RGBQUAD
)
72 + get_dib_stride( BM
.bmWidth
, nBPP
) * BM
.bmHeight
;
73 if (!(mr
= HeapAlloc( GetProcessHeap(), 0, len
)))
75 mr
->rdFunction
= META_DIBSTRETCHBLT
;
76 lpBMI
=(LPBITMAPINFOHEADER
)(mr
->rdParm
+10);
77 lpBMI
->biSize
= sizeof(BITMAPINFOHEADER
);
78 lpBMI
->biWidth
= BM
.bmWidth
;
79 lpBMI
->biHeight
= BM
.bmHeight
;
81 lpBMI
->biBitCount
= nBPP
;
82 lpBMI
->biSizeImage
= get_dib_image_size( (BITMAPINFO
*)lpBMI
);
83 lpBMI
->biClrUsed
= nBPP
<= 8 ? 1 << nBPP
: 0;
84 lpBMI
->biCompression
= BI_RGB
;
85 lpBMI
->biXPelsPerMeter
= MulDiv(GetDeviceCaps(devSrc
->hdc
,LOGPIXELSX
),3937,100);
86 lpBMI
->biYPelsPerMeter
= MulDiv(GetDeviceCaps(devSrc
->hdc
,LOGPIXELSY
),3937,100);
87 lpBMI
->biClrImportant
= 0; /* 1 meter = 39.37 inch */
89 TRACE("MF_StretchBltViaDIB->len = %d rop=%x PixYPM=%d Caps=%d\n",
90 len
,rop
,lpBMI
->biYPelsPerMeter
,GetDeviceCaps(devSrc
->hdc
, LOGPIXELSY
));
92 if (GetDIBits(devSrc
->hdc
, hBitmap
, 0, (UINT
)lpBMI
->biHeight
,
93 (LPSTR
)lpBMI
+ get_dib_info_size( (BITMAPINFO
*)lpBMI
, DIB_RGB_COLORS
),
94 (LPBITMAPINFO
)lpBMI
, DIB_RGB_COLORS
))
96 len
= sizeof(METARECORD
) + 15 * sizeof(INT16
) + BM
.bmWidthBytes
* BM
.bmHeight
;
97 if (!(mr
= HeapAlloc( GetProcessHeap(), 0, len
)))
99 mr
->rdFunction
= META_STRETCHBLT
;
100 *(mr
->rdParm
+10) = BM
.bmWidth
;
101 *(mr
->rdParm
+11) = BM
.bmHeight
;
102 *(mr
->rdParm
+12) = BM
.bmWidthBytes
;
103 *(mr
->rdParm
+13) = BM
.bmPlanes
;
104 *(mr
->rdParm
+14) = BM
.bmBitsPixel
;
105 TRACE("len = %ld rop=%lx\n", len
, rop
);
106 if (GetBitmapBits( hBitmap
, BM
.bmWidthBytes
* BM
.bmHeight
, mr
->rdParm
+ 15))
109 mr
->rdSize
= len
/ sizeof(INT16
);
110 *(mr
->rdParm
) = LOWORD(rop
);
111 *(mr
->rdParm
+ 1) = HIWORD(rop
);
112 *(mr
->rdParm
+ 2) = src
->log_height
;
113 *(mr
->rdParm
+ 3) = src
->log_width
;
114 *(mr
->rdParm
+ 4) = src
->log_y
;
115 *(mr
->rdParm
+ 5) = src
->log_x
;
116 *(mr
->rdParm
+ 6) = dst
->log_height
;
117 *(mr
->rdParm
+ 7) = dst
->log_width
;
118 *(mr
->rdParm
+ 8) = dst
->log_y
;
119 *(mr
->rdParm
+ 9) = dst
->log_x
;
120 ret
= MFDRV_WriteRecord( devDst
, mr
, mr
->rdSize
* 2);
124 HeapFree( GetProcessHeap(), 0, mr
);
129 /***********************************************************************
130 * MFDRV_StretchDIBits
132 INT
MFDRV_StretchDIBits( PHYSDEV dev
, INT xDst
, INT yDst
, INT widthDst
,
133 INT heightDst
, INT xSrc
, INT ySrc
, INT widthSrc
,
134 INT heightSrc
, const void *bits
,
135 BITMAPINFO
*info
, UINT wUsage
, DWORD dwRop
)
137 DWORD infosize
= get_dib_info_size(info
, wUsage
);
138 DWORD len
= sizeof(METARECORD
) + 10 * sizeof(WORD
) + infosize
+ info
->bmiHeader
.biSizeImage
;
139 METARECORD
*mr
= HeapAlloc( GetProcessHeap(), 0, len
);
142 mr
->rdSize
= len
/ 2;
143 mr
->rdFunction
= META_STRETCHDIB
;
144 mr
->rdParm
[0] = LOWORD(dwRop
);
145 mr
->rdParm
[1] = HIWORD(dwRop
);
146 mr
->rdParm
[2] = wUsage
;
147 mr
->rdParm
[3] = (INT16
)heightSrc
;
148 mr
->rdParm
[4] = (INT16
)widthSrc
;
149 mr
->rdParm
[5] = (INT16
)ySrc
;
150 mr
->rdParm
[6] = (INT16
)xSrc
;
151 mr
->rdParm
[7] = (INT16
)heightDst
;
152 mr
->rdParm
[8] = (INT16
)widthDst
;
153 mr
->rdParm
[9] = (INT16
)yDst
;
154 mr
->rdParm
[10] = (INT16
)xDst
;
155 memcpy(mr
->rdParm
+ 11, info
, infosize
);
156 memcpy(mr
->rdParm
+ 11 + infosize
/ 2, bits
, info
->bmiHeader
.biSizeImage
);
157 MFDRV_WriteRecord( dev
, mr
, mr
->rdSize
* 2 );
158 HeapFree( GetProcessHeap(), 0, mr
);
163 /***********************************************************************
164 * MFDRV_SetDIBitsToDeivce
166 INT
MFDRV_SetDIBitsToDevice( PHYSDEV dev
, INT xDst
, INT yDst
, DWORD cx
,
167 DWORD cy
, INT xSrc
, INT ySrc
, UINT startscan
,
168 UINT lines
, LPCVOID bits
, BITMAPINFO
*info
, UINT coloruse
)
171 DWORD infosize
= get_dib_info_size(info
, coloruse
);
172 DWORD len
= sizeof(METARECORD
) + 8 * sizeof(WORD
) + infosize
+ info
->bmiHeader
.biSizeImage
;
173 METARECORD
*mr
= HeapAlloc( GetProcessHeap(), 0, len
);
176 mr
->rdSize
= len
/ 2;
177 mr
->rdFunction
= META_SETDIBTODEV
;
178 mr
->rdParm
[0] = coloruse
;
179 mr
->rdParm
[1] = lines
;
180 mr
->rdParm
[2] = startscan
;
181 mr
->rdParm
[3] = (INT16
)ySrc
;
182 mr
->rdParm
[4] = (INT16
)xSrc
;
183 mr
->rdParm
[5] = (INT16
)cy
;
184 mr
->rdParm
[6] = (INT16
)cx
;
185 mr
->rdParm
[7] = (INT16
)yDst
;
186 mr
->rdParm
[8] = (INT16
)xDst
;
187 memcpy(mr
->rdParm
+ 9, info
, infosize
);
188 memcpy(mr
->rdParm
+ 9 + infosize
/ 2, bits
, info
->bmiHeader
.biSizeImage
);
189 MFDRV_WriteRecord( dev
, mr
, mr
->rdSize
* 2 );
190 HeapFree( GetProcessHeap(), 0, mr
);