DIB Engine: implement most engine functions
[wine/hacks.git] / dlls / winedib.drv / primitives_line.c
blobaf41e2d9fba32d5d876d0fbbd9a72656881fb551
1 /*
2 * DIB Engine line Primitives
4 * Copyright 2009 Massimo Del Fedele
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
21 #include "config.h"
22 #include "wine/port.h"
24 #include "dibdrv.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
28 /* ------------------------------------------------------------*/
29 /* HORIZONTAL LINES */
30 void _DIBDRV_SolidHLine32(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
32 DWORD *ptr;
33 int i;
35 ptr = dib->funcs->GetPixelPointer(dib, start, row);
37 for(i = start; i < end; i++)
38 _DIBDRV_rop32(ptr++, and, xor);
41 void _DIBDRV_SolidHLine24(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
43 BYTE *ptr;
44 int i;
45 BYTE and_bytes[3], xor_bytes[3];
47 and_bytes[0] = and & 0xff;
48 and_bytes[1] = (and >> 8) & 0xff;
49 and_bytes[2] = (and >> 16) & 0xff;
50 xor_bytes[0] = xor & 0xff;
51 xor_bytes[1] = (xor >> 8) & 0xff;
52 xor_bytes[2] = (xor >> 16) & 0xff;
54 ptr = dib->funcs->GetPixelPointer(dib, start, row);
56 for(i = start; i < end; i++)
58 _DIBDRV_rop8(ptr++, and_bytes[0], xor_bytes[0]);
59 _DIBDRV_rop8(ptr++, and_bytes[1], xor_bytes[1]);
60 _DIBDRV_rop8(ptr++, and_bytes[2], xor_bytes[2]);
64 void _DIBDRV_SolidHLine16(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
66 WORD *ptr;
67 int i;
69 ptr = dib->funcs->GetPixelPointer(dib, start, row);
71 for(i = start; i < end; i++)
72 _DIBDRV_rop16(ptr++, and, xor);
75 void _DIBDRV_SolidHLine8(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
77 BYTE *ptr;
78 int i;
80 ptr = dib->funcs->GetPixelPointer(dib, start, row);
82 for(i = start; i < end; i++)
83 _DIBDRV_rop8(ptr++, and, xor);
86 void _DIBDRV_SolidHLine4(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
88 BYTE *ptr;
89 int i;
90 BYTE byte_and, byte_xor;
92 ptr = dib->funcs->GetPixelPointer(dib, start, row);
93 byte_and = (and & 0xf) | ((and << 4) & 0xf0);
94 byte_xor = (xor & 0xf) | ((xor << 4) & 0xf0);
96 if(start & 1) /* upper nibble untouched */
97 _DIBDRV_rop8(ptr++, byte_and | 0xf0, byte_xor & 0x0f);
99 for(i = (start + 1) / 2; i < end / 2; i++)
100 _DIBDRV_rop8(ptr++, byte_and, byte_xor);
102 if(end & 1) /* lower nibble untouched */
103 _DIBDRV_rop8(ptr, byte_and | 0x0f, byte_xor & 0xf0);
106 void _DIBDRV_SolidHLine1(DIBDRVBITMAP *dib, int start, int end, int row, DWORD and, DWORD xor)
108 BYTE *ptr;
109 int i;
110 BYTE byte_and = 0, byte_xor = 0, mask;
112 ptr = dib->funcs->GetPixelPointer(dib, start, row);
114 if(and & 1) byte_and = 0xff;
115 if(xor & 1) byte_xor = 0xff;
117 if((start & ~7) == (end & ~7)) /* special case run inside one byte */
119 mask = ((1L << ((end & 7) - (start & 7))) - 1) << (8 - (end & 7));
120 _DIBDRV_rop8(ptr, byte_and | ~mask, byte_xor & mask);
121 return;
124 if(start & 7)
126 mask = (1 << (8 - (start & 7))) - 1;
127 _DIBDRV_rop8(ptr++, byte_and | ~mask, byte_xor & mask);
130 for(i = (start + 7) / 8; i < end / 8; i++)
131 _DIBDRV_rop8(ptr++, byte_and, byte_xor);
133 if(end & 7)
135 mask = ~((1 << (8 - (end & 7))) - 1);
136 _DIBDRV_rop8(ptr++, byte_and | ~mask, byte_xor & mask);
140 void _DIBDRV_PatternHLine32(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
142 DWORD *ptr;
143 const DWORD *and_ptr = and, *xor_ptr = xor;
144 int i;
146 ptr = dib->funcs->GetPixelPointer(dib, start, row);
148 and_ptr += offset;
149 xor_ptr += offset;
150 for(i = start; i < end; i++)
152 _DIBDRV_rop32(ptr++, *and_ptr++, *xor_ptr++);
153 if(++offset == count)
155 offset = 0;
156 and_ptr = and;
157 xor_ptr = xor;
162 void _DIBDRV_PatternHLine24(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
164 BYTE *ptr;
165 const BYTE *and_ptr = and, *xor_ptr = xor;
166 int i;
168 ptr = dib->funcs->GetPixelPointer(dib, start, row);
170 and_ptr += offset * 3;
171 xor_ptr += offset * 3;
173 for(i = start; i < end; i++)
175 _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
176 _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
177 _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
178 if(++offset == count)
180 offset = 0;
181 and_ptr = and;
182 xor_ptr = xor;
187 void _DIBDRV_PatternHLine16(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
189 WORD *ptr;
190 const WORD *and_ptr = and, *xor_ptr = xor;
191 int i;
193 ptr = dib->funcs->GetPixelPointer(dib, start, row);
195 and_ptr += offset;
196 xor_ptr += offset;
198 for(i = start; i < end; i++)
200 _DIBDRV_rop16(ptr++, *and_ptr++, *xor_ptr++);
201 if(++offset == count)
203 offset = 0;
204 and_ptr = and;
205 xor_ptr = xor;
210 void _DIBDRV_PatternHLine8(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
212 BYTE *ptr;
213 const BYTE *and_ptr = and, *xor_ptr = xor;
214 int i;
216 ptr = dib->funcs->GetPixelPointer(dib, start, row);
218 and_ptr += offset;
219 xor_ptr += offset;
221 for(i = start; i < end; i++)
223 _DIBDRV_rop8(ptr++, *and_ptr++, *xor_ptr++);
224 if(++offset == count)
226 offset = 0;
227 and_ptr = and;
228 xor_ptr = xor;
233 void _DIBDRV_PatternHLine4(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
235 BYTE *ptr;
236 const BYTE *and_ptr = and, *xor_ptr = xor;
237 int i;
238 BYTE byte_and, byte_xor;
240 ptr = dib->funcs->GetPixelPointer(dib, start, row);
242 and_ptr += offset / 2;
243 xor_ptr += offset / 2;
245 for(i = start; i < end; i++)
247 if(offset & 1)
249 byte_and = *and_ptr++ & 0x0f;
250 byte_xor = *xor_ptr++ & 0x0f;
252 else
254 byte_and = (*and_ptr & 0xf0) >> 4;
255 byte_xor = (*xor_ptr & 0xf0) >> 4;
258 if(i & 1)
259 byte_and |= 0xf0;
260 else
262 byte_and = (byte_and << 4) | 0x0f;
263 byte_xor <<= 4;
266 _DIBDRV_rop8(ptr, byte_and, byte_xor);
268 if(i & 1) ptr++;
270 if(++offset == count)
272 offset = 0;
273 and_ptr = and;
274 xor_ptr = xor;
279 void _DIBDRV_PatternHLine1(DIBDRVBITMAP *dib, int start, int end, int row, const void *and, const void *xor, DWORD count, DWORD offset)
281 BYTE *ptr;
282 const BYTE *and_ptr = and, *xor_ptr = xor;
283 int i;
284 BYTE byte_and, byte_xor, dst_mask, brush_mask;
286 ptr = dib->funcs->GetPixelPointer(dib, start, row);
288 and_ptr += offset / 8;
289 xor_ptr += offset / 8;
291 for(i = start; i < end; i++)
293 dst_mask = 1 << (7 - (i & 7));
294 brush_mask = 1 << (7 - (offset & 7));
296 byte_and = (*and_ptr & brush_mask) ? 0xff : 0;
297 byte_xor = (*xor_ptr & brush_mask) ? 0xff : 0;
299 byte_and |= ~dst_mask;
300 byte_xor &= dst_mask;
302 _DIBDRV_rop8(ptr, byte_and, byte_xor);
304 if((i & 7) == 7) ptr++;
305 if(++offset == count)
307 offset = 0;
308 and_ptr = and;
309 xor_ptr = xor;
311 else if((offset & 7) == 7)
313 and_ptr++;
314 xor_ptr++;
319 /* ------------------------------------------------------------*/
320 /* VERTICAL LINES */
321 void _DIBDRV_SolidVLine32(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
323 BYTE *ptr;
324 int i;
326 ptr = dib->funcs->GetPixelPointer(dib, col, start);
328 for(i = start; i < end; i++)
330 _DIBDRV_rop32((DWORD*)ptr, and, xor);
331 ptr += dib->stride;
335 void _DIBDRV_SolidVLine24(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
337 BYTE *ptr;
338 int i;
339 BYTE and_bytes[3], xor_bytes[3];
341 and_bytes[0] = and & 0xff;
342 and_bytes[1] = (and >> 8) & 0xff;
343 and_bytes[2] = (and >> 16) & 0xff;
344 xor_bytes[0] = xor & 0xff;
345 xor_bytes[1] = (xor >> 8) & 0xff;
346 xor_bytes[2] = (xor >> 16) & 0xff;
348 ptr = dib->funcs->GetPixelPointer(dib, col, start);
350 for(i = start; i < end; i++)
352 _DIBDRV_rop8(ptr, and_bytes[0], xor_bytes[0]);
353 _DIBDRV_rop8(ptr + 1, and_bytes[1], xor_bytes[1]);
354 _DIBDRV_rop8(ptr + 2, and_bytes[2], xor_bytes[2]);
355 ptr += dib->stride;
359 void _DIBDRV_SolidVLine16(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
361 BYTE *ptr;
362 int i;
364 ptr = dib->funcs->GetPixelPointer(dib, col, start);
366 for(i = start; i < end; i++)
368 _DIBDRV_rop16((WORD*)ptr, and, xor);
369 ptr += dib->stride;
373 void _DIBDRV_SolidVLine8(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
375 BYTE *ptr;
376 int i;
378 ptr = dib->funcs->GetPixelPointer(dib, col, start);
380 for(i = start; i < end; i++)
382 _DIBDRV_rop8(ptr, and, xor);
383 ptr += dib->stride;
387 void _DIBDRV_SolidVLine4(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
389 BYTE *ptr;
390 int i;
391 BYTE byte_and, byte_xor;
393 if(col & 1) /* upper nibble untouched */
395 byte_and = (and & 0xf) | 0xf0;
396 byte_xor = (xor & 0xf);
398 else
400 byte_and = ((and << 4) & 0xf0) | 0x0f;
401 byte_xor = ((xor << 4) & 0xf0);
404 ptr = dib->funcs->GetPixelPointer(dib, col, start);
406 for(i = start; i < end; i++)
408 _DIBDRV_rop8(ptr, byte_and, byte_xor);
409 ptr += dib->stride;
413 void _DIBDRV_SolidVLine1(DIBDRVBITMAP *dib, int col, int start, int end, DWORD and, DWORD xor)
415 BYTE *ptr;
416 int i;
417 BYTE byte_and = 0, byte_xor = 0, mask;
419 if(and & 1) byte_and = 0xff;
420 if(xor & 1) byte_xor = 0xff;
422 mask = 1 << (7 - (col & 7));
424 byte_and |= ~mask;
425 byte_xor &= mask;
427 ptr = dib->funcs->GetPixelPointer(dib, col, start);
429 for(i = start; i < end; i++)
431 _DIBDRV_rop8(ptr, byte_and, byte_xor);
432 ptr += dib->stride;