2 * DIB driver primitives.
4 * Copyright 2011 Huw 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "gdi_private.h"
24 static inline DWORD
*get_pixel_ptr_32(const dib_info
*dib
, int x
, int y
)
26 return (DWORD
*)((BYTE
*)dib
->bits
+ y
* dib
->stride
+ x
* 4);
29 static inline WORD
*get_pixel_ptr_16(const dib_info
*dib
, int x
, int y
)
31 return (WORD
*)((BYTE
*)dib
->bits
+ y
* dib
->stride
+ x
* 2);
34 static inline void do_rop_32(DWORD
*ptr
, DWORD
and, DWORD
xor)
36 *ptr
= (*ptr
& and) ^ xor;
39 static inline void do_rop_16(WORD
*ptr
, WORD
and, WORD
xor)
41 *ptr
= (*ptr
& and) ^ xor;
44 static void solid_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
49 for(i
= 0; i
< num
; i
++, rc
++)
51 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
52 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
53 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
54 do_rop_32(ptr
++, and, xor);
58 static void solid_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
63 for(i
= 0; i
< num
; i
++, rc
++)
65 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
66 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
67 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
68 do_rop_16(ptr
++, and, xor);
72 static void solid_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, DWORD
and, DWORD
xor)
77 static inline INT
calc_offset(INT edge
, INT size
, INT origin
)
81 if(edge
- origin
>= 0)
82 offset
= (edge
- origin
) % size
;
85 offset
= (origin
- edge
) % size
;
86 if(offset
) offset
= size
- offset
;
91 static inline POINT
calc_brush_offset(const RECT
*rc
, const dib_info
*brush
, const POINT
*origin
)
95 offset
.x
= calc_offset(rc
->left
, brush
->width
, origin
->x
);
96 offset
.y
= calc_offset(rc
->top
, brush
->height
, origin
->y
);
101 static void pattern_rects_32(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
102 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
104 DWORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
108 for(i
= 0; i
< num
; i
++, rc
++)
110 offset
= calc_brush_offset(rc
, brush
, origin
);
112 start
= get_pixel_ptr_32(dib
, rc
->left
, rc
->top
);
113 start_and
= (DWORD
*)and_bits
+ offset
.y
* brush
->stride
/ 4;
114 start_xor
= (DWORD
*)xor_bits
+ offset
.y
* brush
->stride
/ 4;
116 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 4)
118 and_ptr
= start_and
+ offset
.x
;
119 xor_ptr
= start_xor
+ offset
.x
;
121 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
123 do_rop_32(ptr
++, *and_ptr
++, *xor_ptr
++);
124 if(and_ptr
== start_and
+ brush
->width
)
132 if(offset
.y
== brush
->height
)
134 start_and
= and_bits
;
135 start_xor
= xor_bits
;
140 start_and
+= brush
->stride
/ 4;
141 start_xor
+= brush
->stride
/ 4;
147 static void pattern_rects_16(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
148 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
150 WORD
*ptr
, *start
, *start_and
, *and_ptr
, *start_xor
, *xor_ptr
;
154 for(i
= 0; i
< num
; i
++, rc
++)
156 offset
= calc_brush_offset(rc
, brush
, origin
);
158 start
= get_pixel_ptr_16(dib
, rc
->left
, rc
->top
);
159 start_and
= (WORD
*)and_bits
+ offset
.y
* brush
->stride
/ 2;
160 start_xor
= (WORD
*)xor_bits
+ offset
.y
* brush
->stride
/ 2;
162 for(y
= rc
->top
; y
< rc
->bottom
; y
++, start
+= dib
->stride
/ 2)
164 and_ptr
= start_and
+ offset
.x
;
165 xor_ptr
= start_xor
+ offset
.x
;
167 for(x
= rc
->left
, ptr
= start
; x
< rc
->right
; x
++)
169 do_rop_16(ptr
++, *and_ptr
++, *xor_ptr
++);
170 if(and_ptr
== start_and
+ brush
->width
)
178 if(offset
.y
== brush
->height
)
180 start_and
= and_bits
;
181 start_xor
= xor_bits
;
186 start_and
+= brush
->stride
/ 2;
187 start_xor
+= brush
->stride
/ 2;
193 static void pattern_rects_null(const dib_info
*dib
, int num
, const RECT
*rc
, const POINT
*origin
,
194 const dib_info
*brush
, void *and_bits
, void *xor_bits
)
199 static DWORD
colorref_to_pixel_888(const dib_info
*dib
, COLORREF color
)
201 return ( ((color
>> 16) & 0xff) | (color
& 0xff00) | ((color
<< 16) & 0xff0000) );
204 static inline DWORD
put_field(DWORD field
, int shift
, int len
)
206 shift
= shift
- (8 - len
);
208 field
&= (((1 << len
) - 1) << (8 - len
));
216 static DWORD
colorref_to_pixel_masks(const dib_info
*dib
, COLORREF colour
)
220 r
= GetRValue(colour
);
221 g
= GetGValue(colour
);
222 b
= GetBValue(colour
);
224 return put_field(r
, dib
->red_shift
, dib
->red_len
) |
225 put_field(g
, dib
->green_shift
, dib
->green_len
) |
226 put_field(b
, dib
->blue_shift
, dib
->blue_len
);
229 static DWORD
colorref_to_pixel_555(const dib_info
*dib
, COLORREF color
)
231 return ( ((color
>> 19) & 0x1f) | ((color
>> 6) & 0x03e0) | ((color
<< 7) & 0x7c00) );
235 static DWORD
colorref_to_pixel_null(const dib_info
*dib
, COLORREF color
)
240 const primitive_funcs funcs_8888
=
244 colorref_to_pixel_888
247 const primitive_funcs funcs_32
=
251 colorref_to_pixel_masks
254 const primitive_funcs funcs_555
=
258 colorref_to_pixel_555
261 const primitive_funcs funcs_16
=
265 colorref_to_pixel_masks
268 const primitive_funcs funcs_null
=
272 colorref_to_pixel_null