Removed trailing whitespace.
[wine] / dlls / wineps / bitmap.c
1 /*
2  *      PostScript driver bitmap functions
3  *
4  * Copyright 1998  Huw D M Davies
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "psdrv.h"
22 #include "winbase.h"
23 #include "wine/debug.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
26
27
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 )
30 {
31     int words;
32
33     switch(depth)
34     {
35     case 1:  words = (width + 31) / 32; break;
36     case 4:  words = (width + 7) / 8; break;
37     case 8:  words = (width + 3) / 4; break;
38     case 15:
39     case 16: words = (width + 1) / 2; break;
40     case 24: words = (width * 3 + 3)/4; break;
41     default:
42         WARN("(%d): Unsupported depth\n", depth );
43         /* fall through */
44     case 32: words = width; break;
45     }
46     return 4 * words;
47 }
48
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 )
51 {
52     const BITMAPINFOHEADER *header = ptr;
53
54     switch(header->biSize)
55     {
56     case sizeof(BITMAPCOREHEADER):
57         {
58             const BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
59             *width  = core->bcWidth;
60             *height = core->bcHeight;
61             *bpp    = core->bcBitCount;
62             *compr  = 0;
63         }
64         return TRUE;
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;
73         return TRUE;
74     default:
75         ERR("(%ld): unknown/wrong size for header\n", header->biSize );
76         return FALSE;
77     }
78 }
79
80
81 /***************************************************************************
82  *                PSDRV_WriteImageHeader
83  *
84  * Helper for PSDRV_StretchDIBits
85  *
86  * BUGS
87  *  Uses level 2 PostScript
88  */
89
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)
93 {
94     COLORREF map[256];
95     int i;
96
97     switch(info->bmiHeader.biBitCount) {
98     case 8:
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;
104         }
105         PSDRV_WriteRGB(physDev, map, 256);
106         PSDRV_WriteIndexColorSpaceEnd(physDev);
107         break;
108
109     case 4:
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;
115         }
116         PSDRV_WriteRGB(physDev, map, 16);
117         PSDRV_WriteIndexColorSpaceEnd(physDev);
118         break;
119
120     case 1:
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;
126         }
127         PSDRV_WriteRGB(physDev, map, 2);
128         PSDRV_WriteIndexColorSpaceEnd(physDev);
129         break;
130
131     case 15:
132     case 16:
133     case 24:
134     case 32:
135       {
136         PSCOLOR pscol;
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);
140         break;
141       }
142
143     default:
144         FIXME("Not implemented yet\n");
145         return FALSE;
146         break;
147     }
148
149     PSDRV_WriteImageDict(physDev, info->bmiHeader.biBitCount, xDst, yDst,
150                           widthDst, heightDst, widthSrc, heightSrc, NULL);
151     return TRUE;
152 }
153
154
155 /***************************************************************************
156  *
157  *      PSDRV_StretchDIBits
158  *
159  * BUGS
160  *  Doesn't work correctly if xSrc isn't byte aligned - this affects 1 and 4
161  *  bit depths.
162  *  Compression not implemented.
163  */
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 )
168 {
169     LONG fullSrcWidth, fullSrcHeight;
170     INT widthbytes;
171     WORD bpp, compression;
172     const char *ptr;
173     INT line;
174     POINT pt[2];
175
176     TRACE("%08x (%d,%d %dx%d) -> (%d,%d %dx%d)\n", physDev->hdc,
177           xSrc, ySrc, widthSrc, heightSrc, xDst, yDst, widthDst, heightDst);
178
179     if (!get_bitmap_info( info, &fullSrcWidth, &fullSrcHeight, &bpp, &compression )) return FALSE;
180
181     widthbytes = get_dib_width_bytes(fullSrcWidth, bpp);
182
183     TRACE("full size=%ldx%ld bpp=%d compression=%d\n", fullSrcWidth,
184           fullSrcHeight, bpp, compression);
185
186
187     if(compression != BI_RGB) {
188         FIXME("Compression not supported\n");
189         return FALSE;
190     }
191
192     pt[0].x = xDst;
193     pt[0].y = yDst;
194     pt[1].x = xDst + widthDst;
195     pt[1].y = yDst + heightDst;
196     LPtoDP( physDev->hdc, pt, 2 );
197     xDst = pt[0].x;
198     yDst = pt[0].y;
199     widthDst = pt[1].x - pt[0].x;
200     heightDst = pt[1].y - pt[0].y;
201
202     switch(bpp) {
203
204     case 1:
205         PSDRV_WriteGSave(physDev);
206         PSDRV_WriteImageHeader(physDev, info, xDst, yDst, widthDst, heightDst,
207                                widthSrc, heightSrc);
208         ptr = bits;
209         ptr += (ySrc * widthbytes);
210         if(xSrc & 7)
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);
214         break;
215
216     case 4:
217         PSDRV_WriteGSave(physDev);
218         PSDRV_WriteImageHeader(physDev, info, xDst, yDst, widthDst, heightDst,
219                                widthSrc, heightSrc);
220         ptr = bits;
221         ptr += (ySrc * widthbytes);
222         if(xSrc & 1)
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);
226         break;
227
228     case 8:
229         PSDRV_WriteGSave(physDev);
230         PSDRV_WriteImageHeader(physDev, info, xDst, yDst, widthDst, heightDst,
231                                widthSrc, heightSrc);
232         ptr = bits;
233         ptr += (ySrc * widthbytes);
234         for(line = 0; line < heightSrc; line++, ptr += widthbytes)
235             PSDRV_WriteBytes(physDev, ptr + xSrc, widthSrc);
236         break;
237
238     case 15:
239     case 16:
240         PSDRV_WriteGSave(physDev);
241         PSDRV_WriteImageHeader(physDev, info, xDst, yDst, widthDst, heightDst,
242                                widthSrc, heightSrc);
243
244         ptr = bits;
245         ptr += (ySrc * widthbytes);
246         for(line = 0; line < heightSrc; line++, ptr += widthbytes)
247             PSDRV_WriteDIBits16(physDev, (WORD *)ptr + xSrc, widthSrc);
248         break;
249
250     case 24:
251         PSDRV_WriteGSave(physDev);
252         PSDRV_WriteImageHeader(physDev, info, xDst, yDst, widthDst, heightDst,
253                                widthSrc, heightSrc);
254
255         ptr = bits;
256         ptr += (ySrc * widthbytes);
257         for(line = 0; line < heightSrc; line++, ptr += widthbytes)
258             PSDRV_WriteDIBits24(physDev, ptr + xSrc * 3, widthSrc);
259         break;
260
261     case 32:
262         PSDRV_WriteGSave(physDev);
263         PSDRV_WriteImageHeader(physDev, info, xDst, yDst, widthDst, heightDst,
264                                widthSrc, heightSrc);
265
266         ptr = bits;
267         ptr += (ySrc * widthbytes);
268         for(line = 0; line < heightSrc; line++, ptr += widthbytes)
269             PSDRV_WriteDIBits32(physDev, ptr + xSrc * 3, widthSrc);
270         break;
271
272     default:
273         FIXME("Unsupported depth\n");
274         return FALSE;
275
276     }
277     PSDRV_WriteSpool(physDev, ">\n", 2);  /* End-of-Data for /HexASCIIDecodeFilter */
278     PSDRV_WriteGRestore(physDev);
279     return TRUE;
280 }
281
282
283
284
285
286