2 * PostScript driver bitmap functions
4 * Copyright 1998 Huw D M Davies
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(psdrv
);
28 /* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned. */
29 inline static int get_dib_width_bytes( int width
, int depth
)
35 case 1: words
= (width
+ 31) / 32; break;
36 case 4: words
= (width
+ 7) / 8; break;
37 case 8: words
= (width
+ 3) / 4; break;
39 case 16: words
= (width
+ 1) / 2; break;
40 case 24: words
= (width
* 3 + 3)/4; break;
42 WARN("(%d): Unsupported depth\n", depth
);
44 case 32: words
= width
; break;
49 /* get the bitmap info from either an INFOHEADER or COREHEADER bitmap */
50 static BOOL
get_bitmap_info( const void *ptr
, LONG
*width
, LONG
*height
, WORD
*bpp
, WORD
*compr
)
52 const BITMAPINFOHEADER
*header
= ptr
;
54 switch(header
->biSize
)
56 case sizeof(BITMAPCOREHEADER
):
58 const BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)header
;
59 *width
= core
->bcWidth
;
60 *height
= core
->bcHeight
;
61 *bpp
= core
->bcBitCount
;
65 case sizeof(BITMAPINFOHEADER
):
66 case sizeof(BITMAPV4HEADER
):
67 case sizeof(BITMAPV5HEADER
):
68 /* V4 and V5 structures are a superset of the INFOHEADER structure */
69 *width
= header
->biWidth
;
70 *height
= header
->biHeight
;
71 *bpp
= header
->biBitCount
;
72 *compr
= header
->biCompression
;
75 ERR("(%ld): unknown/wrong size for header\n", header
->biSize
);
81 /***************************************************************************
82 * PSDRV_WriteImageHeader
84 * Helper for PSDRV_StretchDIBits
87 * Uses level 2 PostScript
90 static BOOL
PSDRV_WriteImageHeader(PSDRV_PDEVICE
*physDev
, const BITMAPINFO
*info
, INT xDst
,
91 INT yDst
, INT widthDst
, INT heightDst
,
92 INT widthSrc
, INT heightSrc
)
97 switch(info
->bmiHeader
.biBitCount
) {
99 PSDRV_WriteIndexColorSpaceBegin(physDev
, 255);
100 for(i
= 0; i
< 256; i
++) {
101 map
[i
] = info
->bmiColors
[i
].rgbRed
|
102 info
->bmiColors
[i
].rgbGreen
<< 8 |
103 info
->bmiColors
[i
].rgbBlue
<< 16;
105 PSDRV_WriteRGB(physDev
, map
, 256);
106 PSDRV_WriteIndexColorSpaceEnd(physDev
);
110 PSDRV_WriteIndexColorSpaceBegin(physDev
, 15);
111 for(i
= 0; i
< 16; i
++) {
112 map
[i
] = info
->bmiColors
[i
].rgbRed
|
113 info
->bmiColors
[i
].rgbGreen
<< 8 |
114 info
->bmiColors
[i
].rgbBlue
<< 16;
116 PSDRV_WriteRGB(physDev
, map
, 16);
117 PSDRV_WriteIndexColorSpaceEnd(physDev
);
121 PSDRV_WriteIndexColorSpaceBegin(physDev
, 1);
122 for(i
= 0; i
< 2; i
++) {
123 map
[i
] = info
->bmiColors
[i
].rgbRed
|
124 info
->bmiColors
[i
].rgbGreen
<< 8 |
125 info
->bmiColors
[i
].rgbBlue
<< 16;
127 PSDRV_WriteRGB(physDev
, map
, 2);
128 PSDRV_WriteIndexColorSpaceEnd(physDev
);
137 pscol
.type
= PSCOLOR_RGB
;
138 pscol
.value
.rgb
.r
= pscol
.value
.rgb
.g
= pscol
.value
.rgb
.b
= 0.0;
139 PSDRV_WriteSetColor(physDev
, &pscol
);
144 FIXME("Not implemented yet\n");
149 PSDRV_WriteImageDict(physDev
, info
->bmiHeader
.biBitCount
, xDst
, yDst
,
150 widthDst
, heightDst
, widthSrc
, heightSrc
, NULL
);
155 /***************************************************************************
157 * PSDRV_StretchDIBits
160 * Doesn't work correctly if xSrc isn't byte aligned - this affects 1 and 4
162 * Compression not implemented.
164 INT
PSDRV_StretchDIBits( PSDRV_PDEVICE
*physDev
, INT xDst
, INT yDst
, INT widthDst
,
165 INT heightDst
, INT xSrc
, INT ySrc
,
166 INT widthSrc
, INT heightSrc
, const void *bits
,
167 const BITMAPINFO
*info
, UINT wUsage
, DWORD dwRop
)
169 LONG fullSrcWidth
, fullSrcHeight
;
171 WORD bpp
, compression
;
176 TRACE("%p (%d,%d %dx%d) -> (%d,%d %dx%d)\n", physDev
->hdc
,
177 xSrc
, ySrc
, widthSrc
, heightSrc
, xDst
, yDst
, widthDst
, heightDst
);
179 if (!get_bitmap_info( info
, &fullSrcWidth
, &fullSrcHeight
, &bpp
, &compression
)) return FALSE
;
181 widthbytes
= get_dib_width_bytes(fullSrcWidth
, bpp
);
183 TRACE("full size=%ldx%ld bpp=%d compression=%d\n", fullSrcWidth
,
184 fullSrcHeight
, bpp
, compression
);
187 if(compression
!= BI_RGB
) {
188 FIXME("Compression not supported\n");
194 pt
[1].x
= xDst
+ widthDst
;
195 pt
[1].y
= yDst
+ heightDst
;
196 LPtoDP( physDev
->hdc
, pt
, 2 );
199 widthDst
= pt
[1].x
- pt
[0].x
;
200 heightDst
= pt
[1].y
- pt
[0].y
;
205 PSDRV_WriteGSave(physDev
);
206 PSDRV_WriteImageHeader(physDev
, info
, xDst
, yDst
, widthDst
, heightDst
,
207 widthSrc
, heightSrc
);
209 ptr
+= (ySrc
* widthbytes
);
211 FIXME("This won't work...\n");
212 for(line
= 0; line
< heightSrc
; line
++, ptr
+= widthbytes
)
213 PSDRV_WriteBytes(physDev
, ptr
+ xSrc
/8, (widthSrc
+7)/8);
217 PSDRV_WriteGSave(physDev
);
218 PSDRV_WriteImageHeader(physDev
, info
, xDst
, yDst
, widthDst
, heightDst
,
219 widthSrc
, heightSrc
);
221 ptr
+= (ySrc
* widthbytes
);
223 FIXME("This won't work...\n");
224 for(line
= 0; line
< heightSrc
; line
++, ptr
+= widthbytes
)
225 PSDRV_WriteBytes(physDev
, ptr
+ xSrc
/2, (widthSrc
+1)/2);
229 PSDRV_WriteGSave(physDev
);
230 PSDRV_WriteImageHeader(physDev
, info
, xDst
, yDst
, widthDst
, heightDst
,
231 widthSrc
, heightSrc
);
233 ptr
+= (ySrc
* widthbytes
);
234 for(line
= 0; line
< heightSrc
; line
++, ptr
+= widthbytes
)
235 PSDRV_WriteBytes(physDev
, ptr
+ xSrc
, widthSrc
);
240 PSDRV_WriteGSave(physDev
);
241 PSDRV_WriteImageHeader(physDev
, info
, xDst
, yDst
, widthDst
, heightDst
,
242 widthSrc
, heightSrc
);
245 ptr
+= (ySrc
* widthbytes
);
246 for(line
= 0; line
< heightSrc
; line
++, ptr
+= widthbytes
)
247 PSDRV_WriteDIBits16(physDev
, (WORD
*)ptr
+ xSrc
, widthSrc
);
251 PSDRV_WriteGSave(physDev
);
252 PSDRV_WriteImageHeader(physDev
, info
, xDst
, yDst
, widthDst
, heightDst
,
253 widthSrc
, heightSrc
);
256 ptr
+= (ySrc
* widthbytes
);
257 for(line
= 0; line
< heightSrc
; line
++, ptr
+= widthbytes
)
258 PSDRV_WriteDIBits24(physDev
, ptr
+ xSrc
* 3, widthSrc
);
262 PSDRV_WriteGSave(physDev
);
263 PSDRV_WriteImageHeader(physDev
, info
, xDst
, yDst
, widthDst
, heightDst
,
264 widthSrc
, heightSrc
);
267 ptr
+= (ySrc
* widthbytes
);
268 for(line
= 0; line
< heightSrc
; line
++, ptr
+= widthbytes
)
269 PSDRV_WriteDIBits32(physDev
, ptr
+ xSrc
* 3, widthSrc
);
273 FIXME("Unsupported depth\n");
277 PSDRV_WriteSpool(physDev
, ">\n", 2); /* End-of-Data for /HexASCIIDecodeFilter */
278 PSDRV_WriteGRestore(physDev
);