1 | /* |
2 | * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. Oracle designates this |
8 | * particular file as subject to the "Classpath" exception as provided |
9 | * by Oracle in the LICENSE file that accompanied this code. |
10 | * |
11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | * version 2 for more details (a copy is included in the LICENSE file that |
15 | * accompanied this code). |
16 | * |
17 | * You should have received a copy of the GNU General Public License version |
18 | * 2 along with this work; if not, write to the Free Software Foundation, |
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
20 | * |
21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 | * or visit www.oracle.com if you need additional information or have any |
23 | * questions. |
24 | */ |
25 | |
26 | #ifndef LoopMacros_h_Included |
27 | #define LoopMacros_h_Included |
28 | |
29 | #include "j2d_md.h" |
30 | |
31 | #include "LineUtils.h" |
32 | |
33 | /* |
34 | * This file contains macros to aid in defining native graphics |
35 | * primitive functions. |
36 | * |
37 | * A number of useful building block macros are defined, but the |
38 | * vast majority of primitives are defined completely by a single |
39 | * macro expansion which uses macro names in the argument list to |
40 | * choose not only from a small number of strategies but also to |
41 | * choose macro packages specific to the source and destination |
42 | * pixel formats - greatly simplifying all aspects of creating |
43 | * a new loop. |
44 | * |
45 | * See the following macros which define entire functions with |
46 | * just one or two surface names and sometimes a strategy name: |
47 | * DEFINE_ISOCOPY_BLIT(ANYTYPE) |
48 | * DEFINE_ISOXOR_BLIT(ANYTYPE) |
49 | * DEFINE_CONVERT_BLIT(SRC, DST, CONV_METHOD) |
50 | * DEFINE_CONVERT_BLIT_LUT(SRC, DST, LUT_STRATEGY) |
51 | * DEFINE_XPAR_CONVERT_BLIT_LUT(SRC, DST, LUT_STRATEGY) |
52 | * DEFINE_XPAR_BLITBG_LUT(SRC, DST, LUT_STRATEGY) |
53 | * DEFINE_SOLID_FILLRECT(DST) |
54 | * DEFINE_SOLID_FILLSPANS(DST) |
55 | * DEFINE_SOLID_DRAWLINE(DST) |
56 | * |
57 | * Many of these loop macros take the name of a SurfaceType as |
58 | * an argument and use the ANSI CPP token concatenation operator |
59 | * "##" to reference macro and type definitions that are specific |
60 | * to that type of surface. |
61 | * |
62 | * A description of the various surface specific macro utilities |
63 | * that are used by these loop macros appears at the end of the |
64 | * file. The definitions of these surface-specific macros will |
65 | * usually appear in a header file named after the SurfaceType |
66 | * name (i.e. IntArgb.h, ByteGray.h, etc.). |
67 | */ |
68 | |
69 | /* |
70 | * This loop is the standard "while (--height > 0)" loop used by |
71 | * some of the blits below. |
72 | */ |
73 | #define BlitLoopHeight(SRCTYPE, SRCPTR, SRCBASE, SRCINFO, \ |
74 | DSTTYPE, DSTPTR, DSTBASE, DSTINFO, DSTPREFIX, \ |
75 | HEIGHT, BODY) \ |
76 | do { \ |
77 | SRCTYPE ## DataType *SRCPTR = (SRCTYPE ## DataType *) (SRCBASE); \ |
78 | DSTTYPE ## DataType *DSTPTR = (DSTTYPE ## DataType *) (DSTBASE); \ |
79 | jint srcScan = (SRCINFO)->scanStride; \ |
80 | jint dstScan = (DSTINFO)->scanStride; \ |
81 | Init ## DSTTYPE ## StoreVarsY(DSTPREFIX, DSTINFO); \ |
82 | do { \ |
83 | BODY; \ |
84 | SRCPTR = PtrAddBytes(SRCPTR, srcScan); \ |
85 | DSTPTR = PtrAddBytes(DSTPTR, dstScan); \ |
86 | Next ## DSTTYPE ## StoreVarsY(DSTPREFIX); \ |
87 | } while (--HEIGHT > 0); \ |
88 | } while (0) |
89 | |
90 | /* |
91 | * This loop is the standard nested "while (--width/height > 0)" loop |
92 | * used by most of the basic blits below. |
93 | */ |
94 | #define BlitLoopWidthHeight(SRCTYPE, SRCPTR, SRCBASE, SRCINFO, \ |
95 | DSTTYPE, DSTPTR, DSTBASE, DSTINFO, DSTPREFIX, \ |
96 | WIDTH, HEIGHT, BODY) \ |
97 | do { \ |
98 | SRCTYPE ## DataType *SRCPTR = (SRCTYPE ## DataType *) (SRCBASE); \ |
99 | DSTTYPE ## DataType *DSTPTR = (DSTTYPE ## DataType *) (DSTBASE); \ |
100 | jint srcScan = (SRCINFO)->scanStride; \ |
101 | jint dstScan = (DSTINFO)->scanStride; \ |
102 | Init ## DSTTYPE ## StoreVarsY(DSTPREFIX, DSTINFO); \ |
103 | srcScan -= (WIDTH) * SRCTYPE ## PixelStride; \ |
104 | dstScan -= (WIDTH) * DSTTYPE ## PixelStride; \ |
105 | do { \ |
106 | juint w = WIDTH; \ |
107 | Init ## DSTTYPE ## StoreVarsX(DSTPREFIX, DSTINFO); \ |
108 | do { \ |
109 | BODY; \ |
110 | SRCPTR = PtrAddBytes(SRCPTR, SRCTYPE ## PixelStride); \ |
111 | DSTPTR = PtrAddBytes(DSTPTR, DSTTYPE ## PixelStride); \ |
112 | Next ## DSTTYPE ## StoreVarsX(DSTPREFIX); \ |
113 | } while (--w > 0); \ |
114 | SRCPTR = PtrAddBytes(SRCPTR, srcScan); \ |
115 | DSTPTR = PtrAddBytes(DSTPTR, dstScan); \ |
116 | Next ## DSTTYPE ## StoreVarsY(DSTPREFIX); \ |
117 | } while (--HEIGHT > 0); \ |
118 | } while (0) |
119 | |
120 | /* |
121 | * This loop is the standard nested "while (--width/height > 0)" loop |
122 | * used by most of the scaled blits below. It calculates the proper |
123 | * X source variable |
124 | */ |
125 | #define BlitLoopScaleWidthHeight(SRCTYPE, SRCPTR, SRCBASE, SRCINFO, \ |
126 | DSTTYPE, DSTPTR, DSTBASE, DSTINFO, DSTPREFIX, \ |
127 | XVAR, WIDTH, HEIGHT, \ |
128 | SXLOC, SYLOC, SXINC, SYINC, SHIFT, \ |
129 | BODY) \ |
130 | do { \ |
131 | SRCTYPE ## DataType *SRCPTR; \ |
132 | DSTTYPE ## DataType *DSTPTR = (DSTTYPE ## DataType *) (DSTBASE); \ |
133 | jint srcScan = (SRCINFO)->scanStride; \ |
134 | jint dstScan = (DSTINFO)->scanStride; \ |
135 | Init ## DSTTYPE ## StoreVarsY(DSTPREFIX, DSTINFO); \ |
136 | dstScan -= (WIDTH) * DSTTYPE ## PixelStride; \ |
137 | do { \ |
138 | juint w = WIDTH; \ |
139 | jint tmpsxloc = SXLOC; \ |
140 | SRCPTR = PtrAddBytes(SRCBASE, ((SYLOC >> SHIFT) * srcScan)); \ |
141 | Init ## DSTTYPE ## StoreVarsX(DSTPREFIX, DSTINFO); \ |
142 | do { \ |
143 | jint XVAR = (tmpsxloc >> SHIFT); \ |
144 | BODY; \ |
145 | DSTPTR = PtrAddBytes(DSTPTR, DSTTYPE ## PixelStride); \ |
146 | Next ## DSTTYPE ## StoreVarsX(DSTPREFIX); \ |
147 | tmpsxloc += SXINC; \ |
148 | } while (--w > 0); \ |
149 | DSTPTR = PtrAddBytes(DSTPTR, dstScan); \ |
150 | Next ## DSTTYPE ## StoreVarsY(DSTPREFIX); \ |
151 | SYLOC += SYINC; \ |
152 | } while (--HEIGHT > 0); \ |
153 | } while (0) |
154 | |
155 | /* |
156 | * This loop is a standard horizontal loop iterating with a "relative" |
157 | * X coordinate (0 <= X < WIDTH) used primarily by the LUT conversion |
158 | * preprocessing loops below. |
159 | */ |
160 | #define BlitLoopXRel(DSTTYPE, DSTINFO, DSTPREFIX, \ |
161 | XVAR, WIDTH, BODY) \ |
162 | do { \ |
163 | juint XVAR = 0; \ |
164 | Init ## DSTTYPE ## StoreVarsX(DSTPREFIX, DSTINFO); \ |
165 | do { \ |
166 | BODY; \ |
167 | Next ## DSTTYPE ## StoreVarsX(DSTPREFIX); \ |
168 | } while (++XVAR < WIDTH); \ |
169 | } while (0) |
170 | |
171 | /* |
172 | * This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT |
173 | * macros. It converts from the source pixel format to the destination |
174 | * via an intermediate "jint rgb" format. |
175 | */ |
176 | #define ConvertVia1IntRgb(SRCPTR, SRCTYPE, SRCPREFIX, \ |
177 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
178 | SXVAR, DXVAR) \ |
179 | do { \ |
180 | int rgb; \ |
181 | Load ## SRCTYPE ## To1IntRgb(SRCPTR, SRCPREFIX, SXVAR, rgb); \ |
182 | Store ## DSTTYPE ## From1IntRgb(DSTPTR, DSTPREFIX, DXVAR, rgb); \ |
183 | } while (0) |
184 | |
185 | /* |
186 | * This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT |
187 | * macros. It converts from the source pixel format to the destination |
188 | * via an intermediate "jint argb" format. |
189 | */ |
190 | #define ConvertVia1IntArgb(SRCPTR, SRCTYPE, SRCPREFIX, \ |
191 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
192 | SXVAR, DXVAR) \ |
193 | do { \ |
194 | int argb; \ |
195 | Load ## SRCTYPE ## To1IntArgb(SRCPTR, SRCPREFIX, SXVAR, argb); \ |
196 | Store ## DSTTYPE ## From1IntArgb(DSTPTR, DSTPREFIX, DXVAR, argb); \ |
197 | } while (0) |
198 | |
199 | /* |
200 | * This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT |
201 | * macros. It converts from the source pixel format to the destination |
202 | * via an intermediate set of 3 component variables "jint r, g, b". |
203 | */ |
204 | #define ConvertVia3ByteRgb(SRCPTR, SRCTYPE, SRCPREFIX, \ |
205 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
206 | SXVAR, DXVAR) \ |
207 | do { \ |
208 | jint r, g, b; \ |
209 | Load ## SRCTYPE ## To3ByteRgb(SRCPTR, SRCPREFIX, SXVAR, r, g, b); \ |
210 | Store ## DSTTYPE ## From3ByteRgb(DSTPTR, DSTPREFIX, DXVAR, r, g, b); \ |
211 | } while (0) |
212 | |
213 | /* |
214 | * This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT |
215 | * macros. It converts from the source pixel format to the destination |
216 | * via an intermediate set of 4 component variables "jint a, r, g, b". |
217 | */ |
218 | #define ConvertVia4ByteArgb(SRCPTR, SRCTYPE, SRCPREFIX, \ |
219 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
220 | SXVAR, DXVAR) \ |
221 | do { \ |
222 | jint a, r, g, b; \ |
223 | Load ## SRCTYPE ## To4ByteArgb(SRCPTR, SRCPREFIX, SXVAR, a, r, g, b); \ |
224 | Store ## DSTTYPE ## From4ByteArgb(DSTPTR, DSTPREFIX, DXVAR, \ |
225 | a, r, g, b); \ |
226 | } while (0) |
227 | |
228 | /* |
229 | * This is a "conversion strategy" for use with the DEFINE_CONVERT_BLIT |
230 | * macros. It converts from the source pixel format to the destination |
231 | * via an intermediate "jint gray" format. |
232 | */ |
233 | #define ConvertVia1ByteGray(SRCPTR, SRCTYPE, SRCPREFIX, \ |
234 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
235 | SXVAR, DXVAR) \ |
236 | do { \ |
237 | jint gray; \ |
238 | Load ## SRCTYPE ## To1ByteGray(SRCPTR, SRCPREFIX, SXVAR, gray); \ |
239 | Store ## DSTTYPE ## From1ByteGray(DSTPTR, DSTPREFIX, DXVAR, gray); \ |
240 | } while (0) |
241 | |
242 | /* |
243 | * This is a "conversion strategy" for use with the DEFINE_XPAR_CONVERT_BLIT |
244 | * macros. It converts from the source pixel format to the destination |
245 | * via the specified intermediate format while testing for transparent pixels. |
246 | */ |
247 | #define ConvertXparVia1IntRgb(SRCPTR, SRCTYPE, SRCPREFIX, \ |
248 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
249 | SXVAR, DXVAR) \ |
250 | do { \ |
251 | Declare ## SRCTYPE ## Data(XparLoad); \ |
252 | Load ## SRCTYPE ## Data(SRCPTR, SRCPREFIX, SXVAR, XparLoad); \ |
253 | if (! (Is ## SRCTYPE ## DataTransparent(XparLoad))) { \ |
254 | int rgb; \ |
255 | Convert ## SRCTYPE ## DataTo1IntRgb(XparLoad, rgb); \ |
256 | Store ## DSTTYPE ## From1IntRgb(DSTPTR, DSTPREFIX, DXVAR, rgb); \ |
257 | } \ |
258 | } while (0) |
259 | |
260 | /* |
261 | * This is a "conversion strategy" for use with the DEFINE_XPAR_BLITBG |
262 | * macros. It converts from the source pixel format to the destination |
263 | * via the specified intermediate format while substituting the specified |
264 | * bgcolor for transparent pixels. |
265 | */ |
266 | #define BgCopyXparVia1IntRgb(SRCPTR, SRCTYPE, SRCPREFIX, \ |
267 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
268 | SXVAR, DXVAR, BGPIXEL, BGPREFIX) \ |
269 | do { \ |
270 | Declare ## SRCTYPE ## Data(XparLoad); \ |
271 | Load ## SRCTYPE ## Data(SRCPTR, SRCPREFIX, SXVAR, XparLoad); \ |
272 | if (Is ## SRCTYPE ## DataTransparent(XparLoad)) { \ |
273 | Store ## DSTTYPE ## PixelData(DSTPTR, DXVAR, BGPIXEL, BGPREFIX); \ |
274 | } else { \ |
275 | int rgb; \ |
276 | Convert ## SRCTYPE ## DataTo1IntRgb(XparLoad, rgb); \ |
277 | Store ## DSTTYPE ## From1IntRgb(DSTPTR, DSTPREFIX, DXVAR, rgb); \ |
278 | } \ |
279 | } while (0) |
280 | |
281 | /* |
282 | * This macro determines whether or not the given pixel is considered |
283 | * "transparent" for XOR purposes. The ARGB pixel is considered |
284 | * "transparent" if the alpha value is < 0.5. |
285 | */ |
286 | #define IsArgbTransparent(pixel) \ |
287 | (((jint) pixel) >= 0) |
288 | |
289 | /* |
290 | * This is a "conversion strategy" for use with the DEFINE_XOR_BLIT macro. It |
291 | * converts the source pixel to an intermediate ARGB value and then converts |
292 | * the ARGB value to the pixel representation for the destination surface. It |
293 | * then XORs the srcpixel, xorpixel, and destination pixel together and stores |
294 | * the result in the destination surface. |
295 | */ |
296 | #define XorVia1IntArgb(SRCPTR, SRCTYPE, SRCPREFIX, \ |
297 | DSTPTR, DSTTYPE, DSTANYTYPE, \ |
298 | XVAR, XORPIXEL, XORPREFIX, \ |
299 | MASK, MASKPREFIX, DSTINFOPTR) \ |
300 | do { \ |
301 | jint srcpixel; \ |
302 | Declare ## DSTANYTYPE ## PixelData(pix) \ |
303 | Load ## SRCTYPE ## To1IntArgb(SRCPTR, SRCPREFIX, XVAR, srcpixel); \ |
304 | \ |
305 | if (IsArgbTransparent(srcpixel)) { \ |
306 | break; \ |
307 | } \ |
308 | \ |
309 | DSTTYPE ## PixelFromArgb(srcpixel, srcpixel, DSTINFOPTR); \ |
310 | \ |
311 | Extract ## DSTANYTYPE ## PixelData(srcpixel, pix); \ |
312 | Xor ## DSTANYTYPE ## PixelData(srcpixel, pix, DSTPTR, XVAR, \ |
313 | XORPIXEL, XORPREFIX, \ |
314 | MASK, MASKPREFIX); \ |
315 | } while (0) |
316 | |
317 | /* |
318 | * "LUT_STRATEGY" macro sets. |
319 | * |
320 | * There are 2 major strategies for dealing with luts and 3 |
321 | * implementations of those strategies. |
322 | * |
323 | * The 2 strategies are "PreProcessLut" and "ConvertOnTheFly". |
324 | * |
325 | * For the "PreProcessLut" strategy, the raw ARGB lut supplied |
326 | * by the SD_LOCK_LUT flag is converted at the beginning into a |
327 | * form that is more suited for storing into the destination |
328 | * pixel format. The inner loop consists of a series of table |
329 | * lookups with very little conversion from that intermediate |
330 | * pixel format. |
331 | * |
332 | * For the "ConvertOnTheFly" strategy, the raw ARGB values are |
333 | * converted on a pixel by pixel basis in the inner loop itself. |
334 | * This strategy is most useful for formats which tend to use |
335 | * the ARGB color format as their pixel format also. |
336 | * |
337 | * Each of these strategies has 3 implementations which are needed |
338 | * for the special cases: |
339 | * - straight conversion (invoked from DEFINE_CONVERT_BLIT_LUT) |
340 | * - straight conversion with transparency handling (invoked from |
341 | * DEFINE_XPAR_CONVERT_BLIT_LUT) |
342 | * - straight conversion with a bgcolor for the transparent pixels |
343 | * (invoked from DEFINE_XPAR_BLITBG_LUT) |
344 | */ |
345 | |
346 | /*** |
347 | * Start of PreProcessLut strategy macros, CONVERT_BLIT implementation. |
348 | */ |
349 | #define LutSize(TYPE) \ |
350 | (1 << TYPE ## BitsPerPixel) |
351 | |
352 | #define DeclarePreProcessLutLut(SRC, DST, PIXLUT) \ |
353 | DST ## PixelType PIXLUT[LutSize(SRC)]; |
354 | |
355 | #define SetupPreProcessLutLut(SRC, DST, PIXLUT, SRCINFO, DSTINFO) \ |
356 | do { \ |
357 | jint *srcLut = (SRCINFO)->lutBase; \ |
358 | juint lutSize = (SRCINFO)->lutSize; \ |
359 | Declare ## DST ## StoreVars(PreLut) \ |
360 | Init ## DST ## StoreVarsY(PreLut, DSTINFO); \ |
361 | if (lutSize >= LutSize(SRC)) { \ |
362 | lutSize = LutSize(SRC); \ |
363 | } else { \ |
364 | DST ## PixelType *pPIXLUT = &PIXLUT[lutSize]; \ |
365 | do { \ |
366 | Store ## DST ## From1IntArgb(pPIXLUT, PreLut, 0, 0); \ |
367 | } while (++pPIXLUT < &PIXLUT[LutSize(SRC)]); \ |
368 | } \ |
369 | BlitLoopXRel(DST, DSTINFO, PreLut, x, lutSize, \ |
370 | do { \ |
371 | jint argb = srcLut[x]; \ |
372 | Store ## DST ## From1IntArgb(PIXLUT, PreLut, x, argb); \ |
373 | } while (0)); \ |
374 | } while (0) |
375 | |
376 | #define BodyPreProcessLutLut(SRCPTR, SRCTYPE, PIXLUT, \ |
377 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
378 | SXVAR, DXVAR) \ |
379 | DSTPTR[DXVAR] = PIXLUT[SRCPTR[SXVAR]] |
380 | |
381 | /* |
382 | * End of PreProcessLut/CONVERT_BLIT macros. |
383 | ***/ |
384 | |
385 | /*** |
386 | * Start of ConvertOnTheFly strategy macros, CONVERT_BLIT implementation. |
387 | */ |
388 | #define DeclareConvertOnTheFlyLut(SRC, DST, PIXLUT) \ |
389 | Declare ## SRC ## LoadVars(PIXLUT) |
390 | |
391 | #define SetupConvertOnTheFlyLut(SRC, DST, PIXLUT, SRCINFO, DSTINFO) \ |
392 | Init ## SRC ## LoadVars(PIXLUT, SRCINFO) |
393 | |
394 | #define BodyConvertOnTheFlyLut(SRCPTR, SRCTYPE, PIXLUT, \ |
395 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
396 | SXVAR, DXVAR) \ |
397 | ConvertVia1IntArgb(SRCPTR, SRCTYPE, PIXLUT, \ |
398 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
399 | SXVAR, DXVAR) |
400 | |
401 | /* |
402 | * End of ConvertOnTheFly/CONVERT_BLIT macros. |
403 | ***/ |
404 | |
405 | /*** |
406 | * Start of PreProcessLut strategy macros, XPAR_CONVERT_BLIT implementation. |
407 | */ |
408 | #define DeclarePreProcessLutXparLut(SRC, DST, PIXLUT) \ |
409 | jint PIXLUT[LutSize(SRC)]; |
410 | |
411 | #define SetupPreProcessLutXparLut(SRC, DST, PIXLUT, SRCINFO, DSTINFO) \ |
412 | do { \ |
413 | jint *srcLut = (SRCINFO)->lutBase; \ |
414 | juint lutSize = (SRCINFO)->lutSize; \ |
415 | Declare ## DST ## StoreVars(PreLut) \ |
416 | Init ## DST ## StoreVarsY(PreLut, DSTINFO); \ |
417 | if (lutSize >= LutSize(SRC)) { \ |
418 | lutSize = LutSize(SRC); \ |
419 | } else { \ |
420 | jint *pPIXLUT = &PIXLUT[lutSize]; \ |
421 | do { \ |
422 | pPIXLUT[0] = DST ## XparLutEntry; \ |
423 | } while (++pPIXLUT < &PIXLUT[LutSize(SRC)]); \ |
424 | } \ |
425 | BlitLoopXRel(DST, DSTINFO, PreLut, x, lutSize, \ |
426 | do { \ |
427 | jint argb = srcLut[x]; \ |
428 | if (argb < 0) { \ |
429 | Store ## DST ## NonXparFromArgb \ |
430 | (PIXLUT, PreLut, x, argb); \ |
431 | } else { \ |
432 | PIXLUT[x] = DST ## XparLutEntry; \ |
433 | } \ |
434 | } while (0)); \ |
435 | } while (0) |
436 | |
437 | #define BodyPreProcessLutXparLut(SRCPTR, SRCTYPE, PIXLUT, \ |
438 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
439 | SXVAR, DXVAR) \ |
440 | do { \ |
441 | jint pix = PIXLUT[SRCPTR[SXVAR]]; \ |
442 | if (! DSTTYPE ## IsXparLutEntry(pix)) { \ |
443 | DSTPTR[DXVAR] = (DSTTYPE ## PixelType) pix; \ |
444 | } \ |
445 | } while (0) |
446 | |
447 | /* |
448 | * End of PreProcessLut/XPAR_CONVERT_BLIT macros. |
449 | ***/ |
450 | |
451 | /*** |
452 | * Start of ConvertOnTheFly strategy macros, CONVERT_BLIT implementation. |
453 | */ |
454 | #define DeclareConvertOnTheFlyXparLut(SRC, DST, PIXLUT) \ |
455 | Declare ## SRC ## LoadVars(PIXLUT) |
456 | |
457 | #define SetupConvertOnTheFlyXparLut(SRC, DST, PIXLUT, SRCINFO, DSTINFO) \ |
458 | Init ## SRC ## LoadVars(PIXLUT, SRCINFO) |
459 | |
460 | #define BodyConvertOnTheFlyXparLut(SRCPTR, SRCTYPE, PIXLUT, \ |
461 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
462 | SXVAR, DXVAR) \ |
463 | do { \ |
464 | jint argb; \ |
465 | Load ## SRCTYPE ## To1IntArgb(SRCPTR, PIXLUT, SXVAR, argb); \ |
466 | if (argb < 0) { \ |
467 | Store ## DSTTYPE ## From1IntArgb(DSTPTR, DSTPREFIX, DXVAR, argb); \ |
468 | } \ |
469 | } while (0) |
470 | |
471 | /* |
472 | * End of ConvertOnTheFly/CONVERT_BLIT macros. |
473 | ***/ |
474 | |
475 | /*** |
476 | * Start of PreProcessLut strategy macros, BLITBG implementation. |
477 | */ |
478 | #define DeclarePreProcessLutBgLut(SRC, DST, PIXLUT) \ |
479 | jint PIXLUT[LutSize(SRC)]; |
480 | |
481 | #define SetupPreProcessLutBgLut(SRC, DST, PIXLUT, SRCINFO, DSTINFO, BGPIXEL) \ |
482 | do { \ |
483 | jint *srcLut = (SRCINFO)->lutBase; \ |
484 | juint lutSize = (SRCINFO)->lutSize; \ |
485 | Declare ## DST ## StoreVars(PreLut) \ |
486 | Init ## DST ## StoreVarsY(PreLut, DSTINFO); \ |
487 | if (lutSize >= LutSize(SRC)) { \ |
488 | lutSize = LutSize(SRC); \ |
489 | } else { \ |
490 | jint *pPIXLUT = &PIXLUT[lutSize]; \ |
491 | do { \ |
492 | pPIXLUT[0] = BGPIXEL; \ |
493 | } while (++pPIXLUT < &PIXLUT[LutSize(SRC)]); \ |
494 | } \ |
495 | BlitLoopXRel(DST, DSTINFO, PreLut, x, lutSize, \ |
496 | do { \ |
497 | jint argb = srcLut[x]; \ |
498 | if (argb < 0) { \ |
499 | Store ## DST ## From1IntArgb(PIXLUT, PreLut, \ |
500 | x, argb); \ |
501 | } else { \ |
502 | PIXLUT[x] = BGPIXEL; \ |
503 | } \ |
504 | } while (0)); \ |
505 | } while (0) |
506 | |
507 | #define BodyPreProcessLutBgLut(SRCPTR, SRCTYPE, PIXLUT, \ |
508 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
509 | SXVAR, DXVAR, BGPIXEL) \ |
510 | do { \ |
511 | jint pix = PIXLUT[SRCPTR[SXVAR]]; \ |
512 | Store ## DSTTYPE ## Pixel(DSTPTR, DXVAR, pix); \ |
513 | } while (0) |
514 | |
515 | /* |
516 | * End of PreProcessLut/BLITBG implementation. |
517 | ***/ |
518 | |
519 | /*** |
520 | * Start of ConvertOnTheFly strategy macros, BLITBG implementation. |
521 | */ |
522 | #define DeclareConvertOnTheFlyBgLut(SRC, DST, PIXLUT) \ |
523 | Declare ## SRC ## LoadVars(PIXLUT) \ |
524 | Declare ## DST ## PixelData(bgpix); |
525 | |
526 | #define SetupConvertOnTheFlyBgLut(SRC, DST, PIXLUT, SRCINFO, DSTINFO, BGPIXEL) \ |
527 | do { \ |
528 | Init ## SRC ## LoadVars(PIXLUT, SRCINFO); \ |
529 | Extract ## DST ## PixelData(BGPIXEL, bgpix); \ |
530 | } while (0) |
531 | |
532 | #define BodyConvertOnTheFlyBgLut(SRCPTR, SRCTYPE, PIXLUT, \ |
533 | DSTPTR, DSTTYPE, DSTPREFIX, \ |
534 | SXVAR, DXVAR, BGPIXEL) \ |
535 | do { \ |
536 | jint argb; \ |
537 | Load ## SRCTYPE ## To1IntArgb(SRCPTR, PIXLUT, SXVAR, argb); \ |
538 | if (argb < 0) { \ |
539 | Store ## DSTTYPE ## From1IntArgb(DSTPTR, DSTPREFIX, DXVAR, argb); \ |
540 | } else { \ |
541 | Store ## DSTTYPE ## PixelData(DSTPTR, DXVAR, BGPIXEL, bgpix); \ |
542 | } \ |
543 | } while (0) |
544 | |
545 | /* |
546 | * End of ConvertOnTheFly/BLITBG macros. |
547 | ***/ |
548 | |
549 | /* |
550 | * These macros provide consistent naming conventions for the |
551 | * various types of native primitive inner loop functions. |
552 | * The names are mechanically constructed from the SurfaceType names. |
553 | */ |
554 | #define NAME_CONVERT_BLIT(SRC, DST) SRC ## To ## DST ## Convert |
555 | |
556 | #define NAME_SCALE_BLIT(SRC, DST) SRC ## To ## DST ## ScaleConvert |
557 | |
558 | #define NAME_XPAR_CONVERT_BLIT(SRC, DST) SRC ## To ## DST ## XparOver |
559 | |
560 | #define NAME_XPAR_SCALE_BLIT(SRC, DST) SRC ## To ## DST ## ScaleXparOver |
561 | |
562 | #define NAME_XPAR_BLITBG(SRC, DST) SRC ## To ## DST ## XparBgCopy |
563 | |
564 | #define NAME_XOR_BLIT(SRC, DST) SRC ## To ## DST ## XorBlit |
565 | |
566 | #define NAME_ISOCOPY_BLIT(ANYTYPE) ANYTYPE ## IsomorphicCopy |
567 | |
568 | #define NAME_ISOSCALE_BLIT(ANYTYPE) ANYTYPE ## IsomorphicScaleCopy |
569 | |
570 | #define NAME_ISOXOR_BLIT(ANYTYPE) ANYTYPE ## IsomorphicXorCopy |
571 | |
572 | #define NAME_SOLID_FILLRECT(TYPE) TYPE ## SetRect |
573 | |
574 | #define NAME_SOLID_FILLSPANS(TYPE) TYPE ## SetSpans |
575 | |
576 | #define NAME_SOLID_DRAWLINE(TYPE) TYPE ## SetLine |
577 | |
578 | #define NAME_XOR_FILLRECT(TYPE) TYPE ## XorRect |
579 | |
580 | #define NAME_XOR_FILLSPANS(TYPE) TYPE ## XorSpans |
581 | |
582 | #define NAME_XOR_DRAWLINE(TYPE) TYPE ## XorLine |
583 | |
584 | #define NAME_SRC_MASKFILL(TYPE) TYPE ## SrcMaskFill |
585 | |
586 | #define NAME_SRCOVER_MASKFILL(TYPE) TYPE ## SrcOverMaskFill |
587 | |
588 | #define NAME_ALPHA_MASKFILL(TYPE) TYPE ## AlphaMaskFill |
589 | |
590 | #define NAME_SRCOVER_MASKBLIT(SRC, DST) SRC ## To ## DST ## SrcOverMaskBlit |
591 | |
592 | #define NAME_ALPHA_MASKBLIT(SRC, DST) SRC ## To ## DST ## AlphaMaskBlit |
593 | |
594 | #define NAME_SOLID_DRAWGLYPHLIST(TYPE) TYPE ## DrawGlyphList |
595 | |
596 | #define NAME_SOLID_DRAWGLYPHLISTAA(TYPE) TYPE ## DrawGlyphListAA |
597 | |
598 | #define NAME_SOLID_DRAWGLYPHLISTLCD(TYPE) TYPE ## DrawGlyphListLCD |
599 | |
600 | #define NAME_XOR_DRAWGLYPHLIST(TYPE) TYPE ## DrawGlyphListXor |
601 | |
602 | #define NAME_TRANSFORMHELPER(TYPE, MODE) TYPE ## MODE ## TransformHelper |
603 | |
604 | #define NAME_TRANSFORMHELPER_NN(TYPE) NAME_TRANSFORMHELPER(TYPE, NrstNbr) |
605 | #define NAME_TRANSFORMHELPER_BL(TYPE) NAME_TRANSFORMHELPER(TYPE, Bilinear) |
606 | #define NAME_TRANSFORMHELPER_BC(TYPE) NAME_TRANSFORMHELPER(TYPE, Bicubic) |
607 | |
608 | #define NAME_TRANSFORMHELPER_FUNCS(TYPE) TYPE ## TransformHelperFuncs |
609 | |
610 | #define NAME_SOLID_FILLPGRAM(TYPE) TYPE ## SetParallelogram |
611 | #define NAME_SOLID_PGRAM_FUNCS(TYPE) TYPE ## SetParallelogramFuncs |
612 | |
613 | #define NAME_XOR_FILLPGRAM(TYPE) TYPE ## XorParallelogram |
614 | #define NAME_XOR_PGRAM_FUNCS(TYPE) TYPE ## XorParallelogramFuncs |
615 | |
616 | /* |
617 | * These macros conveniently name and declare the indicated native |
618 | * primitive loop function for forward referencing. |
619 | */ |
620 | #define DECLARE_CONVERT_BLIT(SRC, DST) \ |
621 | BlitFunc NAME_CONVERT_BLIT(SRC, DST) |
622 | |
623 | #define DECLARE_SCALE_BLIT(SRC, DST) \ |
624 | ScaleBlitFunc NAME_SCALE_BLIT(SRC, DST) |
625 | |
626 | #define DECLARE_XPAR_CONVERT_BLIT(SRC, DST) \ |
627 | BlitFunc NAME_XPAR_CONVERT_BLIT(SRC, DST) |
628 | |
629 | #define DECLARE_XPAR_SCALE_BLIT(SRC, DST) \ |
630 | ScaleBlitFunc NAME_XPAR_SCALE_BLIT(SRC, DST) |
631 | |
632 | #define DECLARE_XPAR_BLITBG(SRC, DST) \ |
633 | BlitBgFunc NAME_XPAR_BLITBG(SRC, DST) |
634 | |
635 | #define DECLARE_XOR_BLIT(SRC, DST) \ |
636 | BlitFunc NAME_XOR_BLIT(SRC, DST) |
637 | |
638 | #define DECLARE_ISOCOPY_BLIT(ANYTYPE) \ |
639 | BlitFunc NAME_ISOCOPY_BLIT(ANYTYPE) |
640 | |
641 | #define DECLARE_ISOSCALE_BLIT(ANYTYPE) \ |
642 | ScaleBlitFunc NAME_ISOSCALE_BLIT(ANYTYPE) |
643 | |
644 | #define DECLARE_ISOXOR_BLIT(ANYTYPE) \ |
645 | BlitFunc NAME_ISOXOR_BLIT(ANYTYPE) |
646 | |
647 | #define DECLARE_SOLID_FILLRECT(TYPE) \ |
648 | FillRectFunc NAME_SOLID_FILLRECT(TYPE) |
649 | |
650 | #define DECLARE_SOLID_FILLSPANS(TYPE) \ |
651 | FillSpansFunc NAME_SOLID_FILLSPANS(TYPE) |
652 | |
653 | #define DECLARE_SOLID_DRAWLINE(TYPE) \ |
654 | DrawLineFunc NAME_SOLID_DRAWLINE(TYPE) |
655 | |
656 | #define DECLARE_XOR_FILLRECT(TYPE) \ |
657 | FillRectFunc NAME_XOR_FILLRECT(TYPE) |
658 | |
659 | #define DECLARE_XOR_FILLSPANS(TYPE) \ |
660 | FillSpansFunc NAME_XOR_FILLSPANS(TYPE) |
661 | |
662 | #define DECLARE_XOR_DRAWLINE(TYPE) \ |
663 | DrawLineFunc NAME_XOR_DRAWLINE(TYPE) |
664 | |
665 | #define DECLARE_ALPHA_MASKFILL(TYPE) \ |
666 | MaskFillFunc NAME_ALPHA_MASKFILL(TYPE) |
667 | |
668 | #define DECLARE_SRC_MASKFILL(TYPE) \ |
669 | MaskFillFunc NAME_SRC_MASKFILL(TYPE) |
670 | |
671 | #define DECLARE_SRCOVER_MASKFILL(TYPE) \ |
672 | MaskFillFunc NAME_SRCOVER_MASKFILL(TYPE) |
673 | |
674 | #define DECLARE_SRCOVER_MASKBLIT(SRC, DST) \ |
675 | MaskBlitFunc NAME_SRCOVER_MASKBLIT(SRC, DST) |
676 | |
677 | #define DECLARE_ALPHA_MASKBLIT(SRC, DST) \ |
678 | MaskBlitFunc NAME_ALPHA_MASKBLIT(SRC, DST) |
679 | |
680 | #define DECLARE_SOLID_DRAWGLYPHLIST(TYPE) \ |
681 | DrawGlyphListFunc NAME_SOLID_DRAWGLYPHLIST(TYPE) |
682 | |
683 | #define DECLARE_SOLID_DRAWGLYPHLISTAA(TYPE) \ |
684 | DrawGlyphListAAFunc NAME_SOLID_DRAWGLYPHLISTAA(TYPE) |
685 | |
686 | #define DECLARE_SOLID_DRAWGLYPHLISTLCD(TYPE) \ |
687 | DrawGlyphListLCDFunc NAME_SOLID_DRAWGLYPHLISTLCD(TYPE) |
688 | |
689 | #define DECLARE_XOR_DRAWGLYPHLIST(TYPE) \ |
690 | DrawGlyphListFunc NAME_XOR_DRAWGLYPHLIST(TYPE) |
691 | |
692 | #define DECLARE_TRANSFORMHELPER_FUNCS(TYPE) \ |
693 | TransformHelperFunc NAME_TRANSFORMHELPER_NN(TYPE); \ |
694 | TransformHelperFunc NAME_TRANSFORMHELPER_BL(TYPE); \ |
695 | TransformHelperFunc NAME_TRANSFORMHELPER_BC(TYPE); \ |
696 | TransformHelperFuncs NAME_TRANSFORMHELPER_FUNCS(TYPE) |
697 | |
698 | #define DECLARE_SOLID_PARALLELOGRAM(TYPE) \ |
699 | FillParallelogramFunc NAME_SOLID_FILLPGRAM(TYPE); \ |
700 | DECLARE_SOLID_DRAWLINE(TYPE); \ |
701 | DrawParallelogramFuncs NAME_SOLID_PGRAM_FUNCS(TYPE) |
702 | |
703 | #define DECLARE_XOR_PARALLELOGRAM(TYPE) \ |
704 | FillParallelogramFunc NAME_XOR_FILLPGRAM(TYPE); \ |
705 | DECLARE_XOR_DRAWLINE(TYPE); \ |
706 | DrawParallelogramFuncs NAME_XOR_PGRAM_FUNCS(TYPE) |
707 | |
708 | /* |
709 | * These macros construct the necessary NativePrimitive structure |
710 | * for the indicated native primitive loop function which will be |
711 | * declared somewhere prior and defined elsewhere (usually after). |
712 | */ |
713 | #define REGISTER_CONVERT_BLIT(SRC, DST) \ |
714 | REGISTER_BLIT(SRC, SrcNoEa, DST, NAME_CONVERT_BLIT(SRC, DST)) |
715 | |
716 | #define REGISTER_CONVERT_BLIT_FLAGS(SRC, DST, SFLAGS, DFLAGS) \ |
717 | REGISTER_BLIT_FLAGS(SRC, SrcNoEa, DST, NAME_CONVERT_BLIT(SRC, DST), \ |
718 | SFLAGS, DFLAGS) |
719 | |
720 | #define REGISTER_CONVERT_BLIT_EQUIV(SRC, DST, FUNC) \ |
721 | REGISTER_BLIT(SRC, SrcNoEa, DST, FUNC) |
722 | |
723 | #define REGISTER_SCALE_BLIT(SRC, DST) \ |
724 | REGISTER_SCALEBLIT(SRC, SrcNoEa, DST, NAME_SCALE_BLIT(SRC, DST)) |
725 | |
726 | #define REGISTER_SCALE_BLIT_FLAGS(SRC, DST, SFLAGS, DFLAGS) \ |
727 | REGISTER_SCALEBLIT_FLAGS(SRC, SrcNoEa, DST, NAME_SCALE_BLIT(SRC, DST), \ |
728 | SFLAGS, DFLAGS) |
729 | |
730 | #define REGISTER_SCALE_BLIT_EQUIV(SRC, DST, FUNC) \ |
731 | REGISTER_SCALEBLIT(SRC, SrcNoEa, DST, FUNC) |
732 | |
733 | #define REGISTER_XPAR_CONVERT_BLIT(SRC, DST) \ |
734 | REGISTER_BLIT(SRC, SrcOverBmNoEa, DST, NAME_XPAR_CONVERT_BLIT(SRC, DST)) |
735 | |
736 | #define REGISTER_XPAR_CONVERT_BLIT_EQUIV(SRC, DST, FUNC) \ |
737 | REGISTER_BLIT(SRC, SrcOverBmNoEa, DST, FUNC) |
738 | |
739 | #define REGISTER_XPAR_SCALE_BLIT(SRC, DST) \ |
740 | REGISTER_SCALEBLIT(SRC, SrcOverBmNoEa, DST, NAME_XPAR_SCALE_BLIT(SRC, DST)) |
741 | |
742 | #define REGISTER_XPAR_SCALE_BLIT_EQUIV(SRC, DST, FUNC) \ |
743 | REGISTER_SCALEBLIT(SRC, SrcOverBmNoEa, DST, FUNC) |
744 | |
745 | #define REGISTER_XPAR_BLITBG(SRC, DST) \ |
746 | REGISTER_BLITBG(SRC, SrcNoEa, DST, NAME_XPAR_BLITBG(SRC, DST)) |
747 | |
748 | #define REGISTER_XPAR_BLITBG_EQUIV(SRC, DST, FUNC) \ |
749 | REGISTER_BLITBG(SRC, SrcNoEa, DST, FUNC) |
750 | |
751 | #define REGISTER_XOR_BLIT(SRC, DST) \ |
752 | REGISTER_BLIT(SRC, Xor, DST, NAME_XOR_BLIT(SRC, DST)) |
753 | |
754 | #define REGISTER_ISOCOPY_BLIT(THISTYPE, ANYTYPE) \ |
755 | REGISTER_BLIT(THISTYPE, SrcNoEa, THISTYPE, NAME_ISOCOPY_BLIT(ANYTYPE)) |
756 | |
757 | #define REGISTER_ISOSCALE_BLIT(THISTYPE, ANYTYPE) \ |
758 | REGISTER_SCALEBLIT(THISTYPE, SrcNoEa, THISTYPE, NAME_ISOSCALE_BLIT(ANYTYPE)) |
759 | |
760 | #define REGISTER_ISOXOR_BLIT(THISTYPE, ANYTYPE) \ |
761 | REGISTER_BLIT(THISTYPE, Xor, THISTYPE, NAME_ISOXOR_BLIT(ANYTYPE)) |
762 | |
763 | #define REGISTER_SOLID_FILLRECT(TYPE) \ |
764 | REGISTER_FILLRECT(AnyColor, SrcNoEa, TYPE, NAME_SOLID_FILLRECT(TYPE)) |
765 | |
766 | #define REGISTER_SOLID_FILLSPANS(TYPE) \ |
767 | REGISTER_FILLSPANS(AnyColor, SrcNoEa, TYPE, NAME_SOLID_FILLSPANS(TYPE)) |
768 | |
769 | #define REGISTER_SOLID_LINE_PRIMITIVES(TYPE) \ |
770 | REGISTER_LINE_PRIMITIVES(AnyColor, SrcNoEa, TYPE, \ |
771 | NAME_SOLID_DRAWLINE(TYPE)) |
772 | |
773 | #define REGISTER_XOR_FILLRECT(TYPE) \ |
774 | REGISTER_FILLRECT(AnyColor, Xor, TYPE, NAME_XOR_FILLRECT(TYPE)) |
775 | |
776 | #define REGISTER_XOR_FILLSPANS(TYPE) \ |
777 | REGISTER_FILLSPANS(AnyColor, Xor, TYPE, NAME_XOR_FILLSPANS(TYPE)) |
778 | |
779 | #define REGISTER_XOR_LINE_PRIMITIVES(TYPE) \ |
780 | REGISTER_LINE_PRIMITIVES(AnyColor, Xor, TYPE, NAME_XOR_DRAWLINE(TYPE)) |
781 | |
782 | #define REGISTER_ALPHA_MASKFILL(TYPE) \ |
783 | REGISTER_MASKFILL(AnyColor, AnyAlpha, TYPE, NAME_ALPHA_MASKFILL(TYPE)) |
784 | |
785 | #define REGISTER_SRC_MASKFILL(TYPE) \ |
786 | REGISTER_MASKFILL(AnyColor, Src, TYPE, NAME_SRC_MASKFILL(TYPE)) |
787 | |
788 | #define REGISTER_SRCOVER_MASKFILL(TYPE) \ |
789 | REGISTER_MASKFILL(AnyColor, SrcOver, TYPE, NAME_SRCOVER_MASKFILL(TYPE)) |
790 | |
791 | #define REGISTER_SRCOVER_MASKBLIT(SRC, DST) \ |
792 | REGISTER_MASKBLIT(SRC, SrcOver, DST, NAME_SRCOVER_MASKBLIT(SRC, DST)) |
793 | |
794 | #define REGISTER_ALPHA_MASKBLIT(SRC, DST) \ |
795 | REGISTER_MASKBLIT(SRC, AnyAlpha, DST, NAME_ALPHA_MASKBLIT(SRC, DST)) |
796 | |
797 | #define REGISTER_SOLID_DRAWGLYPHLIST(TYPE) \ |
798 | REGISTER_DRAWGLYPHLIST(AnyColor, SrcNoEa, TYPE, \ |
799 | NAME_SOLID_DRAWGLYPHLIST(TYPE)) |
800 | |
801 | #define REGISTER_SOLID_DRAWGLYPHLISTAA(TYPE) \ |
802 | REGISTER_DRAWGLYPHLISTAA(AnyColor, SrcNoEa, TYPE, \ |
803 | NAME_SOLID_DRAWGLYPHLISTAA(TYPE)) |
804 | |
805 | #define REGISTER_SOLID_DRAWGLYPHLISTLCD(TYPE) \ |
806 | REGISTER_DRAWGLYPHLISTLCD(AnyColor, SrcNoEa, TYPE, \ |
807 | NAME_SOLID_DRAWGLYPHLISTLCD(TYPE)) |
808 | |
809 | #define REGISTER_XOR_DRAWGLYPHLIST(TYPE) \ |
810 | REGISTER_DRAWGLYPHLIST(AnyColor, Xor, TYPE, \ |
811 | NAME_XOR_DRAWGLYPHLIST(TYPE)), \ |
812 | REGISTER_DRAWGLYPHLISTAA(AnyColor, Xor, TYPE, \ |
813 | NAME_XOR_DRAWGLYPHLIST(TYPE)) |
814 | |
815 | #define REGISTER_TRANSFORMHELPER_FUNCS(TYPE) \ |
816 | REGISTER_PRIMITIVE(TransformHelper, TYPE, SrcNoEa, IntArgbPre, \ |
817 | (AnyFunc *) &NAME_TRANSFORMHELPER_FUNCS(TYPE)) |
818 | |
819 | #define REGISTER_SOLID_PARALLELOGRAM(TYPE) \ |
820 | REGISTER_PRIMITIVE(FillParallelogram, AnyColor, SrcNoEa, TYPE, \ |
821 | NAME_SOLID_FILLPGRAM(TYPE)), \ |
822 | REGISTER_PRIMITIVE(DrawParallelogram, AnyColor, SrcNoEa, TYPE, \ |
823 | (AnyFunc *) &NAME_SOLID_PGRAM_FUNCS(TYPE)) |
824 | |
825 | #define REGISTER_XOR_PARALLELOGRAM(TYPE) \ |
826 | REGISTER_PRIMITIVE(FillParallelogram, AnyColor, Xor, TYPE, \ |
827 | NAME_XOR_FILLPGRAM(TYPE)), \ |
828 | REGISTER_PRIMITIVE(DrawParallelogram, AnyColor, Xor, TYPE, \ |
829 | (AnyFunc *) &NAME_XOR_PGRAM_FUNCS(TYPE)) |
830 | |
831 | /* |
832 | * This macro defines an entire function to implement a Blit inner loop |
833 | * for copying pixels of a common type from one buffer to another. |
834 | */ |
835 | #define DEFINE_ISOCOPY_BLIT(ANYTYPE) \ |
836 | void NAME_ISOCOPY_BLIT(ANYTYPE)(void *srcBase, void *dstBase, \ |
837 | juint width, juint height, \ |
838 | SurfaceDataRasInfo *pSrcInfo, \ |
839 | SurfaceDataRasInfo *pDstInfo, \ |
840 | NativePrimitive *pPrim, \ |
841 | CompositeInfo *pCompInfo) \ |
842 | { \ |
843 | Declare ## ANYTYPE ## StoreVars(DstWrite) \ |
844 | BlitLoopHeight(ANYTYPE, pSrc, srcBase, pSrcInfo, \ |
845 | ANYTYPE, pDst, dstBase, pDstInfo, DstWrite, \ |
846 | height, \ |
847 | memcpy(pDst, pSrc, width * ANYTYPE ## PixelStride)); \ |
848 | } |
849 | |
850 | /* |
851 | * This macro defines an entire function to implement a ScaleBlit inner loop |
852 | * for scaling pixels of a common type from one buffer to another. |
853 | */ |
854 | #define DEFINE_ISOSCALE_BLIT(ANYTYPE) \ |
855 | void NAME_ISOSCALE_BLIT(ANYTYPE)(void *srcBase, void *dstBase, \ |
856 | juint width, juint height, \ |
857 | jint sxloc, jint syloc, \ |
858 | jint sxinc, jint syinc, jint shift, \ |
859 | SurfaceDataRasInfo *pSrcInfo, \ |
860 | SurfaceDataRasInfo *pDstInfo, \ |
861 | NativePrimitive *pPrim, \ |
862 | CompositeInfo *pCompInfo) \ |
863 | { \ |
864 | Declare ## ANYTYPE ## StoreVars(DstWrite) \ |
865 | BlitLoopScaleWidthHeight(ANYTYPE, pSrc, srcBase, pSrcInfo, \ |
866 | ANYTYPE, pDst, dstBase, pDstInfo, DstWrite, \ |
867 | x, width, height, \ |
868 | sxloc, syloc, sxinc, syinc, shift, \ |
869 | Copy ## ANYTYPE ## PixelData(pSrc, x, pDst, 0)); \ |
870 | } |
871 | |
872 | /* |
873 | * This macro defines an entire function to implement a Blit inner loop |
874 | * for XORing pixels of a common type from one buffer into another. |
875 | */ |
876 | #define DEFINE_ISOXOR_BLIT(ANYTYPE) \ |
877 | void NAME_ISOXOR_BLIT(ANYTYPE)(void *srcBase, void *dstBase, \ |
878 | juint width, juint height, \ |
879 | SurfaceDataRasInfo *pSrcInfo, \ |
880 | SurfaceDataRasInfo *pDstInfo, \ |
881 | NativePrimitive *pPrim, \ |
882 | CompositeInfo *pCompInfo) \ |
883 | { \ |
884 | jint xorpixel = pCompInfo->details.xorPixel; \ |
885 | Declare ## ANYTYPE ## PixelData(xor) \ |
886 | Declare ## ANYTYPE ## StoreVars(DstWrite) \ |
887 | \ |
888 | Extract ## ANYTYPE ## PixelData(xorpixel, xor); \ |
889 | \ |
890 | BlitLoopWidthHeight(ANYTYPE, pSrc, srcBase, pSrcInfo, \ |
891 | ANYTYPE, pDst, dstBase, pDstInfo, DstWrite, \ |
892 | width, height, \ |
893 | XorCopy ## ANYTYPE ## PixelData(pSrc, pDst, 0, \ |
894 | xorpixel, xor)); \ |
895 | } |
896 | |
897 | /* |
898 | * This macro defines an entire function to implement a Blit inner loop |
899 | * for converting pixels from a buffer of one type into a buffer of |
900 | * another type. No blending is done of the pixels. |
901 | */ |
902 | #define DEFINE_CONVERT_BLIT(SRC, DST, STRATEGY) \ |
903 | void NAME_CONVERT_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
904 | juint width, juint height, \ |
905 | SurfaceDataRasInfo *pSrcInfo, \ |
906 | SurfaceDataRasInfo *pDstInfo, \ |
907 | NativePrimitive *pPrim, \ |
908 | CompositeInfo *pCompInfo) \ |
909 | { \ |
910 | Declare ## SRC ## LoadVars(SrcRead) \ |
911 | Declare ## DST ## StoreVars(DstWrite) \ |
912 | \ |
913 | Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \ |
914 | BlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
915 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
916 | width, height, \ |
917 | ConvertVia ## STRATEGY(pSrc, SRC, SrcRead, \ |
918 | pDst, DST, DstWrite, \ |
919 | 0, 0)); \ |
920 | } |
921 | |
922 | /* |
923 | * This macro defines an entire function to implement a Blit inner loop |
924 | * for converting pixels from a buffer of byte pixels with a lookup |
925 | * table into a buffer of another type. No blending is done of the pixels. |
926 | */ |
927 | #define DEFINE_CONVERT_BLIT_LUT(SRC, DST, LUT_STRATEGY) \ |
928 | void NAME_CONVERT_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
929 | juint width, juint height, \ |
930 | SurfaceDataRasInfo *pSrcInfo, \ |
931 | SurfaceDataRasInfo *pDstInfo, \ |
932 | NativePrimitive *pPrim, \ |
933 | CompositeInfo *pCompInfo) \ |
934 | { \ |
935 | Declare ## DST ## StoreVars(DstWrite) \ |
936 | Declare ## LUT_STRATEGY ## Lut(SRC, DST, pixLut) \ |
937 | \ |
938 | Setup ## LUT_STRATEGY ## Lut(SRC, DST, pixLut,\ |
939 | pSrcInfo, pDstInfo); \ |
940 | BlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
941 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
942 | width, height, \ |
943 | Body ## LUT_STRATEGY ## Lut(pSrc, SRC, \ |
944 | pixLut, \ |
945 | pDst, DST, \ |
946 | DstWrite, 0, 0));\ |
947 | } |
948 | #define DEFINE_CONVERT_BLIT_LUT8(SRC, DST, LUT_STRATEGY) \ |
949 | DEFINE_CONVERT_BLIT_LUT(SRC, DST, LUT_STRATEGY) |
950 | |
951 | /* |
952 | * This macro defines an entire function to implement a ScaleBlit inner |
953 | * loop for scaling and converting pixels from a buffer of one type into |
954 | * a buffer of another type. No blending is done of the pixels. |
955 | */ |
956 | #define DEFINE_SCALE_BLIT(SRC, DST, STRATEGY) \ |
957 | void NAME_SCALE_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
958 | juint width, juint height, \ |
959 | jint sxloc, jint syloc, \ |
960 | jint sxinc, jint syinc, jint shift, \ |
961 | SurfaceDataRasInfo *pSrcInfo, \ |
962 | SurfaceDataRasInfo *pDstInfo, \ |
963 | NativePrimitive *pPrim, \ |
964 | CompositeInfo *pCompInfo) \ |
965 | { \ |
966 | Declare ## SRC ## LoadVars(SrcRead) \ |
967 | Declare ## DST ## StoreVars(DstWrite) \ |
968 | \ |
969 | Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \ |
970 | BlitLoopScaleWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
971 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
972 | x, width, height, \ |
973 | sxloc, syloc, sxinc, syinc, shift, \ |
974 | ConvertVia ## STRATEGY(pSrc, SRC, SrcRead, \ |
975 | pDst, DST, DstWrite, \ |
976 | x, 0)); \ |
977 | } |
978 | |
979 | /* |
980 | * This macro defines an entire function to implement a ScaleBlit inner |
981 | * loop for scaling and converting pixels from a buffer of byte pixels |
982 | * with a lookup table into a buffer of another type. No blending is |
983 | * done of the pixels. |
984 | */ |
985 | #define DEFINE_SCALE_BLIT_LUT(SRC, DST, LUT_STRATEGY) \ |
986 | void NAME_SCALE_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
987 | juint width, juint height, \ |
988 | jint sxloc, jint syloc, \ |
989 | jint sxinc, jint syinc, jint shift, \ |
990 | SurfaceDataRasInfo *pSrcInfo, \ |
991 | SurfaceDataRasInfo *pDstInfo, \ |
992 | NativePrimitive *pPrim, \ |
993 | CompositeInfo *pCompInfo) \ |
994 | { \ |
995 | Declare ## DST ## StoreVars(DstWrite) \ |
996 | Declare ## LUT_STRATEGY ## Lut(SRC, DST, pixLut) \ |
997 | \ |
998 | Setup ## LUT_STRATEGY ## Lut(SRC, DST, pixLut, pSrcInfo, pDstInfo); \ |
999 | BlitLoopScaleWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
1000 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
1001 | x, width, height, \ |
1002 | sxloc, syloc, sxinc, syinc, shift, \ |
1003 | Body ## LUT_STRATEGY ## Lut(pSrc, SRC, pixLut, \ |
1004 | pDst, DST, \ |
1005 | DstWrite, x, 0));\ |
1006 | } |
1007 | #define DEFINE_SCALE_BLIT_LUT8(SRC, DST, LUT_STRATEGY) \ |
1008 | DEFINE_SCALE_BLIT_LUT(SRC, DST, LUT_STRATEGY) |
1009 | |
1010 | /* |
1011 | * This macro defines an entire function to implement a Blit inner loop |
1012 | * for drawing opaque pixels from a buffer of one type onto a buffer of |
1013 | * another type, ignoring the transparent pixels in the source buffer. |
1014 | * No blending is done of the pixels - the converted pixel value is |
1015 | * either copied or the destination is left untouched. |
1016 | */ |
1017 | #define DEFINE_XPAR_CONVERT_BLIT(SRC, DST, STRATEGY) \ |
1018 | void NAME_XPAR_CONVERT_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
1019 | juint width, juint height, \ |
1020 | SurfaceDataRasInfo *pSrcInfo, \ |
1021 | SurfaceDataRasInfo *pDstInfo, \ |
1022 | NativePrimitive *pPrim, \ |
1023 | CompositeInfo *pCompInfo) \ |
1024 | { \ |
1025 | Declare ## SRC ## LoadVars(SrcRead) \ |
1026 | Declare ## DST ## StoreVars(DstWrite) \ |
1027 | \ |
1028 | Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \ |
1029 | BlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
1030 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
1031 | width, height, \ |
1032 | ConvertXparVia ## STRATEGY(pSrc, SRC, SrcRead, \ |
1033 | pDst, DST, DstWrite, \ |
1034 | 0, 0)); \ |
1035 | } |
1036 | |
1037 | /* |
1038 | * This macro defines an entire function to implement a Blit inner loop |
1039 | * for converting pixels from a buffer of byte pixels with a lookup |
1040 | * table containing transparent pixels into a buffer of another type. |
1041 | * No blending is done of the pixels - the converted pixel value is |
1042 | * either copied or the destination is left untouched. |
1043 | */ |
1044 | #define DEFINE_XPAR_CONVERT_BLIT_LUT(SRC, DST, LUT_STRATEGY) \ |
1045 | void NAME_XPAR_CONVERT_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
1046 | juint width, juint height, \ |
1047 | SurfaceDataRasInfo *pSrcInfo, \ |
1048 | SurfaceDataRasInfo *pDstInfo, \ |
1049 | NativePrimitive *pPrim, \ |
1050 | CompositeInfo *pCompInfo) \ |
1051 | { \ |
1052 | Declare ## DST ## StoreVars(DstWrite) \ |
1053 | Declare ## LUT_STRATEGY ## XparLut(SRC, DST, pixLut) \ |
1054 | \ |
1055 | Setup ## LUT_STRATEGY ## XparLut(SRC, DST, pixLut, pSrcInfo, pDstInfo); \ |
1056 | BlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
1057 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
1058 | width, height, \ |
1059 | Body ## LUT_STRATEGY ## XparLut(pSrc, SRC, pixLut, \ |
1060 | pDst, DST, \ |
1061 | DstWrite, 0, 0)); \ |
1062 | } |
1063 | #define DEFINE_XPAR_CONVERT_BLIT_LUT8(SRC, DST, LUT_STRATEGY) \ |
1064 | DEFINE_XPAR_CONVERT_BLIT_LUT(SRC, DST, LUT_STRATEGY) |
1065 | |
1066 | /* |
1067 | * This macro defines an entire function to implement a ScaleBlit inner |
1068 | * loop for scaling and converting pixels from a buffer of byte pixels |
1069 | * with a lookup table containing transparent pixels into a buffer of |
1070 | * another type. |
1071 | * No blending is done of the pixels - the converted pixel value is |
1072 | * either copied or the destination is left untouched. |
1073 | */ |
1074 | #define DEFINE_XPAR_SCALE_BLIT_LUT(SRC, DST, LUT_STRATEGY) \ |
1075 | void NAME_XPAR_SCALE_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
1076 | juint width, juint height, \ |
1077 | jint sxloc, jint syloc, \ |
1078 | jint sxinc, jint syinc, jint shift, \ |
1079 | SurfaceDataRasInfo *pSrcInfo, \ |
1080 | SurfaceDataRasInfo *pDstInfo, \ |
1081 | NativePrimitive *pPrim, \ |
1082 | CompositeInfo *pCompInfo) \ |
1083 | { \ |
1084 | Declare ## DST ## StoreVars(DstWrite) \ |
1085 | Declare ## LUT_STRATEGY ## XparLut(SRC, DST, pixLut) \ |
1086 | \ |
1087 | Setup ## LUT_STRATEGY ## XparLut(SRC, DST, pixLut, pSrcInfo, pDstInfo); \ |
1088 | BlitLoopScaleWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
1089 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
1090 | x, width, height, \ |
1091 | sxloc, syloc, sxinc, syinc, shift, \ |
1092 | Body ## LUT_STRATEGY ## XparLut(pSrc, SRC, pixLut, \ |
1093 | pDst, DST, \ |
1094 | DstWrite, \ |
1095 | x, 0)); \ |
1096 | } |
1097 | #define DEFINE_XPAR_SCALE_BLIT_LUT8(SRC, DST, LUT_STRATEGY) \ |
1098 | DEFINE_XPAR_SCALE_BLIT_LUT(SRC, DST, LUT_STRATEGY) |
1099 | |
1100 | /* |
1101 | * This macro defines an entire function to implement a ScaleBlit inner |
1102 | * loop for scaling and converting pixels from a buffer of one type |
1103 | * containing transparent pixels into a buffer of another type. |
1104 | * |
1105 | * No blending is done of the pixels - the converted pixel value is |
1106 | * either copied or the destination is left untouched. |
1107 | */ |
1108 | #define DEFINE_XPAR_SCALE_BLIT(SRC, DST, STRATEGY) \ |
1109 | void NAME_XPAR_SCALE_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
1110 | juint width, juint height, \ |
1111 | jint sxloc, jint syloc, \ |
1112 | jint sxinc, jint syinc, jint shift, \ |
1113 | SurfaceDataRasInfo *pSrcInfo, \ |
1114 | SurfaceDataRasInfo *pDstInfo, \ |
1115 | NativePrimitive *pPrim, \ |
1116 | CompositeInfo *pCompInfo) \ |
1117 | { \ |
1118 | Declare ## SRC ## LoadVars(SrcRead) \ |
1119 | Declare ## DST ## StoreVars(DstWrite) \ |
1120 | \ |
1121 | Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \ |
1122 | BlitLoopScaleWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
1123 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
1124 | x, width, height, \ |
1125 | sxloc, syloc, sxinc, syinc, shift, \ |
1126 | ConvertXparVia ## STRATEGY(pSrc, SRC, SrcRead, \ |
1127 | pDst, DST, DstWrite, \ |
1128 | x, 0)); \ |
1129 | } |
1130 | |
1131 | /* |
1132 | * This macro defines an entire function to implement a BlitBg inner loop |
1133 | * for converting pixels from a buffer of one type containing transparent |
1134 | * pixels into a buffer of another type with a specified bgcolor for the |
1135 | * transparent pixels. |
1136 | * No blending is done of the pixels other than to substitute the |
1137 | * bgcolor for any transparent pixels. |
1138 | */ |
1139 | #define DEFINE_XPAR_BLITBG(SRC, DST, STRATEGY) \ |
1140 | void NAME_XPAR_BLITBG(SRC, DST)(void *srcBase, void *dstBase, \ |
1141 | juint width, juint height, \ |
1142 | jint bgpixel, \ |
1143 | SurfaceDataRasInfo *pSrcInfo, \ |
1144 | SurfaceDataRasInfo *pDstInfo, \ |
1145 | NativePrimitive *pPrim, \ |
1146 | CompositeInfo *pCompInfo) \ |
1147 | { \ |
1148 | Declare ## SRC ## LoadVars(SrcRead) \ |
1149 | Declare ## DST ## StoreVars(DstWrite) \ |
1150 | Declare ## DST ## PixelData(bgdata) \ |
1151 | \ |
1152 | Extract ## DST ## PixelData(bgpixel, bgdata); \ |
1153 | BlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
1154 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
1155 | width, height, \ |
1156 | BgCopyXparVia ## STRATEGY(pSrc, SRC, SrcRead, \ |
1157 | pDst, DST, DstWrite, \ |
1158 | 0, 0, bgpixel, bgdata)); \ |
1159 | } |
1160 | |
1161 | /* |
1162 | * This macro defines an entire function to implement a BlitBg inner loop |
1163 | * for converting pixels from a buffer of byte pixels with a lookup |
1164 | * table containing transparent pixels into a buffer of another type |
1165 | * with a specified bgcolor for the transparent pixels. |
1166 | * No blending is done of the pixels other than to substitute the |
1167 | * bgcolor for any transparent pixels. |
1168 | */ |
1169 | #define DEFINE_XPAR_BLITBG_LUT(SRC, DST, LUT_STRATEGY) \ |
1170 | void NAME_XPAR_BLITBG(SRC, DST)(void *srcBase, void *dstBase, \ |
1171 | juint width, juint height, \ |
1172 | jint bgpixel, \ |
1173 | SurfaceDataRasInfo *pSrcInfo, \ |
1174 | SurfaceDataRasInfo *pDstInfo, \ |
1175 | NativePrimitive *pPrim, \ |
1176 | CompositeInfo *pCompInfo) \ |
1177 | { \ |
1178 | Declare ## DST ## StoreVars(DstWrite) \ |
1179 | Declare ## LUT_STRATEGY ## BgLut(SRC, DST, pixLut) \ |
1180 | \ |
1181 | Setup ## LUT_STRATEGY ## BgLut(SRC, DST, pixLut, pSrcInfo, pDstInfo, \ |
1182 | bgpixel); \ |
1183 | BlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
1184 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
1185 | width, height, \ |
1186 | Body ## LUT_STRATEGY ## BgLut(pSrc, SRC, pixLut, \ |
1187 | pDst, DST, \ |
1188 | DstWrite, 0, 0, \ |
1189 | bgpixel)); \ |
1190 | } |
1191 | #define DEFINE_XPAR_BLITBG_LUT8(SRC, DST, LUT_STRATEGY) \ |
1192 | DEFINE_XPAR_BLITBG_LUT(SRC, DST, LUT_STRATEGY) |
1193 | |
1194 | /* |
1195 | * This macro defines an entire function to implement a Blit inner loop |
1196 | * for converting pixels from a buffer of one type into a buffer of |
1197 | * another type. Each source pixel is XORed with the current XOR color value. |
1198 | * That result is then XORed with the destination pixel and the final |
1199 | * result is stored in the destination surface. |
1200 | */ |
1201 | #define DEFINE_XOR_BLIT(SRC, DST, DSTANYTYPE) \ |
1202 | void NAME_XOR_BLIT(SRC, DST)(void *srcBase, void *dstBase, \ |
1203 | juint width, juint height, \ |
1204 | SurfaceDataRasInfo *pSrcInfo, \ |
1205 | SurfaceDataRasInfo *pDstInfo, \ |
1206 | NativePrimitive *pPrim, \ |
1207 | CompositeInfo *pCompInfo) \ |
1208 | { \ |
1209 | jint xorpixel = pCompInfo->details.xorPixel; \ |
1210 | juint alphamask = pCompInfo->alphaMask; \ |
1211 | Declare ## DSTANYTYPE ## PixelData(xor) \ |
1212 | Declare ## DSTANYTYPE ## PixelData(mask) \ |
1213 | Declare ## SRC ## LoadVars(SrcRead) \ |
1214 | Declare ## DST ## StoreVars(DstWrite) \ |
1215 | \ |
1216 | Extract ## DSTANYTYPE ## PixelData(xorpixel, xor); \ |
1217 | Extract ## DSTANYTYPE ## PixelData(alphamask, mask); \ |
1218 | \ |
1219 | Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \ |
1220 | BlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, \ |
1221 | DST, pDst, dstBase, pDstInfo, DstWrite, \ |
1222 | width, height, \ |
1223 | XorVia1IntArgb(pSrc, SRC, SrcRead, \ |
1224 | pDst, DST, DSTANYTYPE, \ |
1225 | 0, xorpixel, xor, \ |
1226 | alphamask, mask, pDstInfo)); \ |
1227 | } |
1228 | |
1229 | /* |
1230 | * This macro defines an entire function to implement a FillRect inner loop |
1231 | * for setting a rectangular region of pixels to a specific pixel value. |
1232 | * No blending of the fill color is done with the pixels. |
1233 | */ |
1234 | #define DEFINE_SOLID_FILLRECT(DST) \ |
1235 | void NAME_SOLID_FILLRECT(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1236 | jint lox, jint loy, \ |
1237 | jint hix, jint hiy, \ |
1238 | jint pixel, \ |
1239 | NativePrimitive *pPrim, \ |
1240 | CompositeInfo *pCompInfo) \ |
1241 | { \ |
1242 | Declare ## DST ## PixelData(pix) \ |
1243 | DST ## DataType *pPix; \ |
1244 | jint scan = pRasInfo->scanStride; \ |
1245 | juint height = hiy - loy; \ |
1246 | juint width = hix - lox; \ |
1247 | \ |
1248 | pPix = PtrCoord(pRasInfo->rasBase, lox, DST ## PixelStride, loy, scan); \ |
1249 | Extract ## DST ## PixelData(pixel, pix); \ |
1250 | do { \ |
1251 | juint x = 0; \ |
1252 | do { \ |
1253 | Store ## DST ## PixelData(pPix, x, pixel, pix); \ |
1254 | } while (++x < width); \ |
1255 | pPix = PtrAddBytes(pPix, scan); \ |
1256 | } while (--height > 0); \ |
1257 | } |
1258 | |
1259 | /* |
1260 | * This macro defines an entire function to implement a FillSpans inner loop |
1261 | * for iterating through a list of spans and setting those regions of pixels |
1262 | * to a specific pixel value. No blending of the fill color is done with |
1263 | * the pixels. |
1264 | */ |
1265 | #define DEFINE_SOLID_FILLSPANS(DST) \ |
1266 | void NAME_SOLID_FILLSPANS(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1267 | SpanIteratorFuncs *pSpanFuncs, void *siData, \ |
1268 | jint pixel, NativePrimitive *pPrim, \ |
1269 | CompositeInfo *pCompInfo) \ |
1270 | { \ |
1271 | void *pBase = pRasInfo->rasBase; \ |
1272 | Declare ## DST ## PixelData(pix) \ |
1273 | jint scan = pRasInfo->scanStride; \ |
1274 | jint bbox[4]; \ |
1275 | \ |
1276 | Extract ## DST ## PixelData(pixel, pix); \ |
1277 | while ((*pSpanFuncs->nextSpan)(siData, bbox)) { \ |
1278 | jint x = bbox[0]; \ |
1279 | jint y = bbox[1]; \ |
1280 | juint w = bbox[2] - x; \ |
1281 | juint h = bbox[3] - y; \ |
1282 | DST ## DataType *pPix = PtrCoord(pBase, \ |
1283 | x, DST ## PixelStride, \ |
1284 | y, scan); \ |
1285 | do { \ |
1286 | juint relx; \ |
1287 | for (relx = 0; relx < w; relx++) { \ |
1288 | Store ## DST ## PixelData(pPix, relx, pixel, pix); \ |
1289 | } \ |
1290 | pPix = PtrAddBytes(pPix, scan); \ |
1291 | } while (--h > 0); \ |
1292 | } \ |
1293 | } |
1294 | |
1295 | /* |
1296 | * This macro defines an entire function to implement a FillParallelogram |
1297 | * inner loop for tracing 2 diagonal edges (left and right) and setting |
1298 | * those regions of pixels between them to a specific pixel value. |
1299 | * No blending of the fill color is done with the pixels. |
1300 | */ |
1301 | #define DEFINE_SOLID_FILLPGRAM(DST) \ |
1302 | void NAME_SOLID_FILLPGRAM(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1303 | jint lox, jint loy, jint hix, jint hiy, \ |
1304 | jlong leftx, jlong dleftx, \ |
1305 | jlong rightx, jlong drightx, \ |
1306 | jint pixel, struct _NativePrimitive *pPrim, \ |
1307 | CompositeInfo *pCompInfo) \ |
1308 | { \ |
1309 | Declare ## DST ## PixelData(pix) \ |
1310 | jint scan = pRasInfo->scanStride; \ |
1311 | DST ## DataType *pPix = PtrCoord(pRasInfo->rasBase, 0, 0, loy, scan); \ |
1312 | \ |
1313 | Extract ## DST ## PixelData(pixel, pix); \ |
1314 | while (loy < hiy) { \ |
1315 | jint lx = WholeOfLong(leftx); \ |
1316 | jint rx = WholeOfLong(rightx); \ |
1317 | if (lx < lox) lx = lox; \ |
1318 | if (rx > hix) rx = hix; \ |
1319 | while (lx < rx) { \ |
1320 | Store ## DST ## PixelData(pPix, lx, pixel, pix); \ |
1321 | lx++; \ |
1322 | } \ |
1323 | pPix = PtrAddBytes(pPix, scan); \ |
1324 | leftx += dleftx; \ |
1325 | rightx += drightx; \ |
1326 | loy++; \ |
1327 | } \ |
1328 | } |
1329 | |
1330 | #define DEFINE_SOLID_DRAWPARALLELOGRAM_FUNCS(DST) \ |
1331 | DrawParallelogramFuncs NAME_SOLID_PGRAM_FUNCS(DST) = { \ |
1332 | NAME_SOLID_FILLPGRAM(DST), \ |
1333 | NAME_SOLID_DRAWLINE(DST), \ |
1334 | }; |
1335 | |
1336 | #define DEFINE_SOLID_PARALLELOGRAM(DST) \ |
1337 | DEFINE_SOLID_FILLPGRAM(DST) \ |
1338 | DEFINE_SOLID_DRAWPARALLELOGRAM_FUNCS(DST) |
1339 | |
1340 | /* |
1341 | * This macro declares the bumpmajor and bumpminor variables used for the |
1342 | * DrawLine functions. |
1343 | */ |
1344 | #define DeclareBumps(BUMPMAJOR, BUMPMINOR) \ |
1345 | jint BUMPMAJOR, BUMPMINOR; |
1346 | |
1347 | /* |
1348 | * This macro extracts "instructions" from the bumpmajor and bumpminor masks |
1349 | * that determine the initial bumpmajor and bumpminor values. The bumpmajor |
1350 | * and bumpminor masks are laid out in the following format: |
1351 | * |
1352 | * bumpmajormask: bumpminormask: |
1353 | * bit0: bumpmajor = pixelStride bit0: bumpminor = pixelStride |
1354 | * bit1: bumpmajor = -pixelStride bit1: bumpminor = -pixelStride |
1355 | * bit2: bumpmajor = scanStride bit2: bumpminor = scanStride |
1356 | * bit3: bumpmajor = -scanStride bit3: bumpminor = -scanStride |
1357 | */ |
1358 | #define InitBumps(BUMPMAJOR, BUMPMINOR, \ |
1359 | BUMPMAJORMASK, BUMPMINORMASK, \ |
1360 | PIXELSTRIDE, SCANSTRIDE) \ |
1361 | BUMPMAJOR = (BUMPMAJORMASK & BUMP_POS_PIXEL) ? PIXELSTRIDE : \ |
1362 | (BUMPMAJORMASK & BUMP_NEG_PIXEL) ? -PIXELSTRIDE : \ |
1363 | (BUMPMAJORMASK & BUMP_POS_SCAN) ? SCANSTRIDE : \ |
1364 | -SCANSTRIDE; \ |
1365 | BUMPMINOR = (BUMPMINORMASK & BUMP_POS_PIXEL) ? PIXELSTRIDE : \ |
1366 | (BUMPMINORMASK & BUMP_NEG_PIXEL) ? -PIXELSTRIDE : \ |
1367 | (BUMPMINORMASK & BUMP_POS_SCAN) ? SCANSTRIDE : \ |
1368 | (BUMPMINORMASK & BUMP_NEG_SCAN) ? -SCANSTRIDE : \ |
1369 | 0; \ |
1370 | BUMPMINOR += BUMPMAJOR; |
1371 | |
1372 | /* |
1373 | * This macro defines an entire function to implement a DrawLine inner loop |
1374 | * for iterating along a horizontal or vertical line and setting the pixels |
1375 | * on that line to a specific pixel value. No blending of the fill color |
1376 | * is done with the pixels. |
1377 | */ |
1378 | #define DEFINE_SOLID_DRAWLINE(DST) \ |
1379 | void NAME_SOLID_DRAWLINE(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1380 | jint x1, jint y1, jint pixel, \ |
1381 | jint steps, jint error, \ |
1382 | jint bumpmajormask, jint errmajor, \ |
1383 | jint bumpminormask, jint errminor, \ |
1384 | NativePrimitive *pPrim, \ |
1385 | CompositeInfo *pCompInfo) \ |
1386 | { \ |
1387 | Declare ## DST ## PixelData(pix) \ |
1388 | jint scan = pRasInfo->scanStride; \ |
1389 | DST ## DataType *pPix = PtrCoord(pRasInfo->rasBase, \ |
1390 | x1, DST ## PixelStride, \ |
1391 | y1, scan); \ |
1392 | DeclareBumps(bumpmajor, bumpminor) \ |
1393 | \ |
1394 | InitBumps(bumpmajor, bumpminor, bumpmajormask, bumpminormask, \ |
1395 | DST ## PixelStride, scan); \ |
1396 | Extract ## DST ## PixelData(pixel, pix); \ |
1397 | if (errmajor == 0) { \ |
1398 | do { \ |
1399 | Store ## DST ## PixelData(pPix, 0, pixel, pix); \ |
1400 | pPix = PtrAddBytes(pPix, bumpmajor); \ |
1401 | } while (--steps > 0); \ |
1402 | } else { \ |
1403 | do { \ |
1404 | Store ## DST ## PixelData(pPix, 0, pixel, pix); \ |
1405 | if (error < 0) { \ |
1406 | pPix = PtrAddBytes(pPix, bumpmajor); \ |
1407 | error += errmajor; \ |
1408 | } else { \ |
1409 | pPix = PtrAddBytes(pPix, bumpminor); \ |
1410 | error -= errminor; \ |
1411 | } \ |
1412 | } while (--steps > 0); \ |
1413 | } \ |
1414 | } |
1415 | |
1416 | /* |
1417 | * This macro defines an entire function to implement a FillRect inner loop |
1418 | * for setting a rectangular region of pixels to a specific pixel value. |
1419 | * Each destination pixel is XORed with the current XOR mode color as well as |
1420 | * the current fill color. |
1421 | */ |
1422 | #define DEFINE_XOR_FILLRECT(DST) \ |
1423 | void NAME_XOR_FILLRECT(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1424 | jint lox, jint loy, \ |
1425 | jint hix, jint hiy, \ |
1426 | jint pixel, \ |
1427 | NativePrimitive *pPrim, \ |
1428 | CompositeInfo *pCompInfo) \ |
1429 | { \ |
1430 | jint xorpixel = pCompInfo->details.xorPixel; \ |
1431 | juint alphamask = pCompInfo->alphaMask; \ |
1432 | Declare ## DST ## PixelData(xor) \ |
1433 | Declare ## DST ## PixelData(pix) \ |
1434 | Declare ## DST ## PixelData(mask) \ |
1435 | DST ## DataType *pPix; \ |
1436 | jint scan = pRasInfo->scanStride; \ |
1437 | juint height = hiy - loy; \ |
1438 | juint width = hix - lox; \ |
1439 | \ |
1440 | pPix = PtrCoord(pRasInfo->rasBase, lox, DST ## PixelStride, loy, scan); \ |
1441 | Extract ## DST ## PixelData(xorpixel, xor); \ |
1442 | Extract ## DST ## PixelData(pixel, pix); \ |
1443 | Extract ## DST ## PixelData(alphamask, mask); \ |
1444 | \ |
1445 | do { \ |
1446 | juint x = 0; \ |
1447 | do { \ |
1448 | Xor ## DST ## PixelData(pixel, pix, pPix, x, \ |
1449 | xorpixel, xor, alphamask, mask); \ |
1450 | } while (++x < width); \ |
1451 | pPix = PtrAddBytes(pPix, scan); \ |
1452 | } while (--height > 0); \ |
1453 | } |
1454 | |
1455 | /* |
1456 | * This macro defines an entire function to implement a FillSpans inner loop |
1457 | * for iterating through a list of spans and setting those regions of pixels |
1458 | * to a specific pixel value. Each destination pixel is XORed with the |
1459 | * current XOR mode color as well as the current fill color. |
1460 | */ |
1461 | #define DEFINE_XOR_FILLSPANS(DST) \ |
1462 | void NAME_XOR_FILLSPANS(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1463 | SpanIteratorFuncs *pSpanFuncs, \ |
1464 | void *siData, jint pixel, \ |
1465 | NativePrimitive *pPrim, \ |
1466 | CompositeInfo *pCompInfo) \ |
1467 | { \ |
1468 | void *pBase = pRasInfo->rasBase; \ |
1469 | jint xorpixel = pCompInfo->details.xorPixel; \ |
1470 | juint alphamask = pCompInfo->alphaMask; \ |
1471 | Declare ## DST ## PixelData(xor) \ |
1472 | Declare ## DST ## PixelData(pix) \ |
1473 | Declare ## DST ## PixelData(mask) \ |
1474 | jint scan = pRasInfo->scanStride; \ |
1475 | jint bbox[4]; \ |
1476 | \ |
1477 | Extract ## DST ## PixelData(xorpixel, xor); \ |
1478 | Extract ## DST ## PixelData(pixel, pix); \ |
1479 | Extract ## DST ## PixelData(alphamask, mask); \ |
1480 | \ |
1481 | while ((*pSpanFuncs->nextSpan)(siData, bbox)) { \ |
1482 | jint x = bbox[0]; \ |
1483 | jint y = bbox[1]; \ |
1484 | juint w = bbox[2] - x; \ |
1485 | juint h = bbox[3] - y; \ |
1486 | DST ## DataType *pPix = PtrCoord(pBase, \ |
1487 | x, DST ## PixelStride, \ |
1488 | y, scan); \ |
1489 | do { \ |
1490 | juint relx; \ |
1491 | for (relx = 0; relx < w; relx++) { \ |
1492 | Xor ## DST ## PixelData(pixel, pix, pPix, relx, \ |
1493 | xorpixel, xor, alphamask, mask); \ |
1494 | } \ |
1495 | pPix = PtrAddBytes(pPix, scan); \ |
1496 | } while (--h > 0); \ |
1497 | } \ |
1498 | } |
1499 | |
1500 | /* |
1501 | * This macro defines an entire function to implement a DrawLine inner loop |
1502 | * for iterating along a horizontal or vertical line and setting the pixels |
1503 | * on that line to a specific pixel value. Each destination pixel is XORed |
1504 | * with the current XOR mode color as well as the current draw color. |
1505 | */ |
1506 | #define DEFINE_XOR_DRAWLINE(DST) \ |
1507 | void NAME_XOR_DRAWLINE(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1508 | jint x1, jint y1, jint pixel, \ |
1509 | jint steps, jint error, \ |
1510 | jint bumpmajormask, jint errmajor, \ |
1511 | jint bumpminormask, jint errminor, \ |
1512 | NativePrimitive *pPrim, \ |
1513 | CompositeInfo *pCompInfo) \ |
1514 | { \ |
1515 | jint xorpixel = pCompInfo->details.xorPixel; \ |
1516 | juint alphamask = pCompInfo->alphaMask; \ |
1517 | Declare ## DST ## PixelData(xor) \ |
1518 | Declare ## DST ## PixelData(pix) \ |
1519 | Declare ## DST ## PixelData(mask) \ |
1520 | jint scan = pRasInfo->scanStride; \ |
1521 | DST ## DataType *pPix = PtrCoord(pRasInfo->rasBase, \ |
1522 | x1, DST ## PixelStride, \ |
1523 | y1, scan); \ |
1524 | DeclareBumps(bumpmajor, bumpminor) \ |
1525 | \ |
1526 | InitBumps(bumpmajor, bumpminor, bumpmajormask, bumpminormask, \ |
1527 | DST ## PixelStride, scan); \ |
1528 | Extract ## DST ## PixelData(xorpixel, xor); \ |
1529 | Extract ## DST ## PixelData(pixel, pix); \ |
1530 | Extract ## DST ## PixelData(alphamask, mask); \ |
1531 | \ |
1532 | if (errmajor == 0) { \ |
1533 | do { \ |
1534 | Xor ## DST ## PixelData(pixel, pix, pPix, 0, \ |
1535 | xorpixel, xor, alphamask, mask); \ |
1536 | pPix = PtrAddBytes(pPix, bumpmajor); \ |
1537 | } while (--steps > 0); \ |
1538 | } else { \ |
1539 | do { \ |
1540 | Xor ## DST ## PixelData(pixel, pix, pPix, 0, \ |
1541 | xorpixel, xor, alphamask, mask); \ |
1542 | if (error < 0) { \ |
1543 | pPix = PtrAddBytes(pPix, bumpmajor); \ |
1544 | error += errmajor; \ |
1545 | } else { \ |
1546 | pPix = PtrAddBytes(pPix, bumpminor); \ |
1547 | error -= errminor; \ |
1548 | } \ |
1549 | } while (--steps > 0); \ |
1550 | } \ |
1551 | } |
1552 | |
1553 | /* |
1554 | * This macro is used to declare the variables needed by the glyph clipping |
1555 | * macro. |
1556 | */ |
1557 | #define DeclareDrawGlyphListClipVars(PIXELS, ROWBYTES, WIDTH, HEIGHT, \ |
1558 | LEFT, TOP, RIGHT, BOTTOM) \ |
1559 | const jubyte * PIXELS; \ |
1560 | int ROWBYTES; \ |
1561 | int LEFT, TOP; \ |
1562 | int WIDTH, HEIGHT; \ |
1563 | int RIGHT, BOTTOM; |
1564 | |
1565 | /* |
1566 | * This macro represents the glyph clipping code used in the various |
1567 | * DRAWGLYPHLIST macros. This macro is typically used within a loop. Note |
1568 | * that the body of this macro is NOT wrapped in a do..while block due to |
1569 | * the use of continue statements within the block (those continue statements |
1570 | * are intended skip the outer loop, not the do..while loop). To combat this |
1571 | * problem, pass in the code (typically a continue statement) that should be |
1572 | * executed when a null glyph is encountered. |
1573 | */ |
1574 | #define ClipDrawGlyphList(DST, PIXELS, BYTESPERPIXEL, ROWBYTES, WIDTH, HEIGHT,\ |
1575 | LEFT, TOP, RIGHT, BOTTOM, \ |
1576 | CLIPLEFT, CLIPTOP, CLIPRIGHT, CLIPBOTTOM, \ |
1577 | GLYPHS, GLYPHCOUNTER, NULLGLYPHCODE) \ |
1578 | PIXELS = (const jubyte *)GLYPHS[GLYPHCOUNTER].pixels; \ |
1579 | if (!PIXELS) { \ |
1580 | NULLGLYPHCODE; \ |
1581 | } \ |
1582 | ROWBYTES = GLYPHS[GLYPHCOUNTER].rowBytes; \ |
1583 | LEFT = GLYPHS[GLYPHCOUNTER].x; \ |
1584 | TOP = GLYPHS[GLYPHCOUNTER].y; \ |
1585 | WIDTH = GLYPHS[GLYPHCOUNTER].width; \ |
1586 | HEIGHT = GLYPHS[GLYPHCOUNTER].height; \ |
1587 | \ |
1588 | /* if any clipping required, modify parameters now */ \ |
1589 | RIGHT = LEFT + WIDTH; \ |
1590 | BOTTOM = TOP + HEIGHT; \ |
1591 | if (LEFT < CLIPLEFT) { \ |
1592 | /* Multiply needed for LCD text as PIXELS is really BYTES */ \ |
1593 | PIXELS += (CLIPLEFT - LEFT) * BYTESPERPIXEL ; \ |
1594 | LEFT = CLIPLEFT; \ |
1595 | } \ |
1596 | if (TOP < CLIPTOP) { \ |
1597 | PIXELS += (CLIPTOP - TOP) * ROWBYTES; \ |
1598 | TOP = CLIPTOP; \ |
1599 | } \ |
1600 | if (RIGHT > CLIPRIGHT) { \ |
1601 | RIGHT = CLIPRIGHT; \ |
1602 | } \ |
1603 | if (BOTTOM > CLIPBOTTOM) { \ |
1604 | BOTTOM = CLIPBOTTOM; \ |
1605 | } \ |
1606 | if (RIGHT <= LEFT || BOTTOM <= TOP) { \ |
1607 | NULLGLYPHCODE; \ |
1608 | } \ |
1609 | WIDTH = RIGHT - LEFT; \ |
1610 | HEIGHT = BOTTOM - TOP; |
1611 | |
1612 | #define DEFINE_SOLID_DRAWGLYPHLIST(DST) \ |
1613 | void NAME_SOLID_DRAWGLYPHLIST(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1614 | ImageRef *glyphs, \ |
1615 | jint totalGlyphs, jint fgpixel, \ |
1616 | jint argbcolor, \ |
1617 | jint clipLeft, jint clipTop, \ |
1618 | jint clipRight, jint clipBottom, \ |
1619 | NativePrimitive *pPrim, \ |
1620 | CompositeInfo *pCompInfo) \ |
1621 | { \ |
1622 | jint glyphCounter; \ |
1623 | jint scan = pRasInfo->scanStride; \ |
1624 | Declare ## DST ## PixelData(pix) \ |
1625 | DST ## DataType *pPix; \ |
1626 | \ |
1627 | Extract ## DST ## PixelData(fgpixel, pix); \ |
1628 | for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { \ |
1629 | DeclareDrawGlyphListClipVars(pixels, rowBytes, width, height, \ |
1630 | left, top, right, bottom) \ |
1631 | ClipDrawGlyphList(DST, pixels, 1, rowBytes, width, height, \ |
1632 | left, top, right, bottom, \ |
1633 | clipLeft, clipTop, clipRight, clipBottom, \ |
1634 | glyphs, glyphCounter, continue) \ |
1635 | pPix = PtrCoord(pRasInfo->rasBase,left,DST ## PixelStride,top,scan); \ |
1636 | \ |
1637 | do { \ |
1638 | int x = 0; \ |
1639 | do { \ |
1640 | if (pixels[x]) { \ |
1641 | Store ## DST ## PixelData(pPix, x, fgpixel, pix); \ |
1642 | } \ |
1643 | } while (++x < width); \ |
1644 | pPix = PtrAddBytes(pPix, scan); \ |
1645 | pixels += rowBytes; \ |
1646 | } while (--height > 0); \ |
1647 | } \ |
1648 | } |
1649 | |
1650 | #define GlyphListAABlend3ByteRgb(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ |
1651 | FG_PIXEL, PREFIX, SRC_PREFIX) \ |
1652 | do { \ |
1653 | DeclareCompVarsFor3ByteRgb(dst) \ |
1654 | jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ |
1655 | if (mixValSrc) { \ |
1656 | if (mixValSrc < 255) { \ |
1657 | jint mixValDst = 255 - mixValSrc; \ |
1658 | Load ## DST ## To3ByteRgb(DST_PTR, pix, PIXEL_INDEX, \ |
1659 | dstR, dstG, dstB); \ |
1660 | MultMultAddAndStore3ByteRgbComps(dst, mixValDst, dst, \ |
1661 | mixValSrc, SRC_PREFIX); \ |
1662 | Store ## DST ## From3ByteRgb(DST_PTR, pix, PIXEL_INDEX, \ |
1663 | dstR, dstG, dstB); \ |
1664 | } else { \ |
1665 | Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ |
1666 | FG_PIXEL, PREFIX); \ |
1667 | } \ |
1668 | } \ |
1669 | } while (0); |
1670 | |
1671 | /* |
1672 | * Antialiased glyph drawing results in artifacts around the character edges |
1673 | * when text is drawn ontop of translucent background color. The standard |
1674 | * blending equation for two colors: |
1675 | * destColor = srcColor * glyphAlpha + destColor * (1 - glyphAlpha) |
1676 | * works only when srcColor and destColor are opaque. For translucent srcColor |
1677 | * and destColor, the respective alpha components in each color will influence |
1678 | * the visibility of the color and the visibility of the color below it. Hence |
1679 | * the equation for blending is given as: |
1680 | * resA = srcAlpha + dstAlpha * (1 - srcAlpha) |
1681 | * resCol = (srcColor * srcAlpha + destColor * destAlpha * (1- srcAlpha))/resA |
1682 | * In addition, srcAlpha is multiplied with the glyphAlpha- that indicates the |
1683 | * grayscale mask value of the glyph being drawn. The combined result provides |
1684 | * smooth antialiased text on the buffer without any artifacts. Since the |
1685 | * logic is executed for every pixel in a glyph, the implementation is further |
1686 | * optimized to reduce computation and improve execution time. |
1687 | */ |
1688 | #define GlyphListAABlend4ByteArgb(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ |
1689 | FG_PIXEL, PREFIX, SRC_PREFIX) \ |
1690 | do { \ |
1691 | DeclareAlphaVarFor4ByteArgb(resA) \ |
1692 | DeclareCompVarsFor4ByteArgb(res) \ |
1693 | jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ |
1694 | if (mixValSrc) { \ |
1695 | if (mixValSrc != 0xff) { \ |
1696 | PromoteByteAlphaFor4ByteArgb(mixValSrc); \ |
1697 | resA = MultiplyAlphaFor4ByteArgb(mixValSrc, SRC_PREFIX ## A); \ |
1698 | } else { \ |
1699 | resA = SRC_PREFIX ## A; \ |
1700 | } \ |
1701 | if (resA != MaxValFor4ByteArgb) { \ |
1702 | DeclareAndInvertAlphaVarFor4ByteArgb(dstF, resA) \ |
1703 | DeclareAndClearAlphaVarFor4ByteArgb(dstA) \ |
1704 | DeclareCompVarsFor4ByteArgb(dst) \ |
1705 | DeclareCompVarsFor4ByteArgb(tmp) \ |
1706 | MultiplyAndStore4ByteArgbComps(res, resA, SRC_PREFIX); \ |
1707 | if (!(DST ## IsPremultiplied)) { \ |
1708 | Load ## DST ## To4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \ |
1709 | dstA, dstR, dstG, dstB); \ |
1710 | Store4ByteArgbCompsUsingOp(tmp, =, dst); \ |
1711 | } else { \ |
1712 | Declare ## DST ## AlphaLoadData(DstPix) \ |
1713 | jint pixelOffset = PIXEL_INDEX * (DST ## PixelStride); \ |
1714 | DST ## DataType *pixelAddress = PtrAddBytes(DST_PTR, \ |
1715 | pixelOffset); \ |
1716 | LoadAlphaFrom ## DST ## For4ByteArgb(pixelAddress, \ |
1717 | DstPix, \ |
1718 | dst); \ |
1719 | Postload4ByteArgbFrom ## DST(pixelAddress, \ |
1720 | DstPix, \ |
1721 | tmp); \ |
1722 | } \ |
1723 | if (dstA) { \ |
1724 | DeclareAlphaVarFor4ByteArgb(blendF) \ |
1725 | dstA = MultiplyAlphaFor4ByteArgb(dstF, dstA); \ |
1726 | resA += dstA; \ |
1727 | blendF = SrcOver ## DST ## BlendFactor(dstF, dstA); \ |
1728 | if (blendF != MaxValFor4ByteArgb) { \ |
1729 | MultiplyAndStore4ByteArgbComps(tmp, \ |
1730 | blendF, \ |
1731 | tmp); \ |
1732 | } \ |
1733 | Store4ByteArgbCompsUsingOp(res, +=, tmp); \ |
1734 | } \ |
1735 | } else { \ |
1736 | Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ |
1737 | FG_PIXEL, PREFIX); \ |
1738 | break; \ |
1739 | } \ |
1740 | if (!(DST ## IsOpaque) && \ |
1741 | !(DST ## IsPremultiplied) && resA && \ |
1742 | resA < MaxValFor4ByteArgb) \ |
1743 | { \ |
1744 | DivideAndStore4ByteArgbComps(res, res, resA); \ |
1745 | } \ |
1746 | Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \ |
1747 | PIXEL_INDEX, res); \ |
1748 | } \ |
1749 | } while (0); |
1750 | |
1751 | #define GlyphListAABlend1ByteGray(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ |
1752 | FG_PIXEL, PREFIX, SRC_PREFIX) \ |
1753 | do { \ |
1754 | DeclareCompVarsFor1ByteGray(dst) \ |
1755 | jint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ |
1756 | if (mixValSrc) { \ |
1757 | if (mixValSrc < 255) { \ |
1758 | jint mixValDst = 255 - mixValSrc; \ |
1759 | Load ## DST ## To1ByteGray(DST_PTR, pix, PIXEL_INDEX, \ |
1760 | dstG); \ |
1761 | MultMultAddAndStore1ByteGrayComps(dst, mixValDst, dst, \ |
1762 | mixValSrc, SRC_PREFIX); \ |
1763 | Store ## DST ## From1ByteGray(DST_PTR, pix, PIXEL_INDEX, \ |
1764 | dstG); \ |
1765 | } else { \ |
1766 | Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ |
1767 | FG_PIXEL, PREFIX); \ |
1768 | } \ |
1769 | } \ |
1770 | } while (0); |
1771 | |
1772 | #define GlyphListAABlend1ShortGray(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ |
1773 | FG_PIXEL, PREFIX, SRC_PREFIX) \ |
1774 | do { \ |
1775 | DeclareCompVarsFor1ShortGray(dst) \ |
1776 | juint mixValSrc = GLYPH_PIXELS[PIXEL_INDEX]; \ |
1777 | if (mixValSrc) { \ |
1778 | if (mixValSrc < 255) { \ |
1779 | juint mixValDst; \ |
1780 | PromoteByteAlphaFor1ShortGray(mixValSrc); \ |
1781 | mixValDst = 0xffff - mixValSrc; \ |
1782 | Load ## DST ## To1ShortGray(DST_PTR, pix, PIXEL_INDEX, \ |
1783 | dstG); \ |
1784 | MultMultAddAndStore1ShortGrayComps(dst, mixValDst, dst, \ |
1785 | mixValSrc, SRC_PREFIX); \ |
1786 | Store ## DST ## From1ShortGray(DST_PTR, pix, PIXEL_INDEX, \ |
1787 | dstG); \ |
1788 | } else { \ |
1789 | Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ |
1790 | FG_PIXEL, PREFIX); \ |
1791 | } \ |
1792 | } \ |
1793 | } while (0); |
1794 | |
1795 | #define DEFINE_SOLID_DRAWGLYPHLISTAA(DST, STRATEGY) \ |
1796 | void NAME_SOLID_DRAWGLYPHLISTAA(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1797 | ImageRef *glyphs, \ |
1798 | jint totalGlyphs, jint fgpixel, \ |
1799 | jint argbcolor, \ |
1800 | jint clipLeft, jint clipTop, \ |
1801 | jint clipRight, jint clipBottom, \ |
1802 | NativePrimitive *pPrim, \ |
1803 | CompositeInfo *pCompInfo) \ |
1804 | { \ |
1805 | jint glyphCounter; \ |
1806 | jint scan = pRasInfo->scanStride; \ |
1807 | DST ## DataType *pPix; \ |
1808 | Declare ## DST ## PixelData(solidpix) \ |
1809 | DeclareAlphaVarFor ## STRATEGY(srcA) \ |
1810 | DeclareCompVarsFor ## STRATEGY(src) \ |
1811 | \ |
1812 | Declare ## DST ## LoadVars(pix) \ |
1813 | Declare ## DST ## StoreVars(pix) \ |
1814 | \ |
1815 | Init ## DST ## LoadVars(pix, pRasInfo); \ |
1816 | Init ## DST ## StoreVarsY(pix, pRasInfo); \ |
1817 | Init ## DST ## StoreVarsX(pix, pRasInfo); \ |
1818 | Extract ## STRATEGY ## CompsAndAlphaFromArgb(argbcolor, src); \ |
1819 | Extract ## DST ## PixelData(fgpixel, solidpix); \ |
1820 | \ |
1821 | for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { \ |
1822 | DeclareDrawGlyphListClipVars(pixels, rowBytes, width, height, \ |
1823 | left, top, right, bottom) \ |
1824 | ClipDrawGlyphList(DST, pixels, 1, rowBytes, width, height, \ |
1825 | left, top, right, bottom, \ |
1826 | clipLeft, clipTop, clipRight, clipBottom, \ |
1827 | glyphs, glyphCounter, continue) \ |
1828 | pPix = PtrCoord(pRasInfo->rasBase,left,DST ## PixelStride,top,scan); \ |
1829 | \ |
1830 | Set ## DST ## StoreVarsYPos(pix, pRasInfo, top); \ |
1831 | do { \ |
1832 | int x = 0; \ |
1833 | Set ## DST ## StoreVarsXPos(pix, pRasInfo, left); \ |
1834 | do { \ |
1835 | GlyphListAABlend ## STRATEGY(DST, pixels, x, pPix, \ |
1836 | fgpixel, solidpix, src); \ |
1837 | Next ## DST ## StoreVarsX(pix); \ |
1838 | } while (++x < width); \ |
1839 | pPix = PtrAddBytes(pPix, scan); \ |
1840 | pixels += rowBytes; \ |
1841 | Next ## DST ## StoreVarsY(pix); \ |
1842 | } while (--height > 0); \ |
1843 | } \ |
1844 | } |
1845 | |
1846 | |
1847 | #define GlyphListLCDBlend3ByteRgb(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ |
1848 | FG_PIXEL, PREFIX, SRC_PREFIX) \ |
1849 | do { \ |
1850 | DeclareCompVarsFor3ByteRgb(dst) \ |
1851 | jint mixValSrcG = GLYPH_PIXELS[PIXEL_INDEX*3+1]; \ |
1852 | jint mixValSrcR, mixValSrcB; \ |
1853 | if (rgbOrder) { \ |
1854 | mixValSrcR = GLYPH_PIXELS[PIXEL_INDEX*3]; \ |
1855 | mixValSrcB = GLYPH_PIXELS[PIXEL_INDEX*3+2]; \ |
1856 | } else { \ |
1857 | mixValSrcR = GLYPH_PIXELS[PIXEL_INDEX*3+2]; \ |
1858 | mixValSrcB = GLYPH_PIXELS[PIXEL_INDEX*3]; \ |
1859 | } \ |
1860 | if ((mixValSrcR | mixValSrcG | mixValSrcB) != 0) { \ |
1861 | if ((mixValSrcR & mixValSrcG & mixValSrcB) < 255) { \ |
1862 | jint mixValDstR = 255 - mixValSrcR; \ |
1863 | jint mixValDstG = 255 - mixValSrcG; \ |
1864 | jint mixValDstB = 255 - mixValSrcB; \ |
1865 | Load ## DST ## To3ByteRgb(DST_PTR, pix, PIXEL_INDEX, \ |
1866 | dstR, dstG, dstB); \ |
1867 | dstR = invGammaLut[dstR]; \ |
1868 | dstG = invGammaLut[dstG]; \ |
1869 | dstB = invGammaLut[dstB]; \ |
1870 | MultMultAddAndStoreLCD3ByteRgbComps(dst, mixValDst, dst, \ |
1871 | mixValSrc, SRC_PREFIX); \ |
1872 | dstR = gammaLut[dstR]; \ |
1873 | dstG = gammaLut[dstG]; \ |
1874 | dstB = gammaLut[dstB]; \ |
1875 | Store ## DST ## From3ByteRgb(DST_PTR, pix, PIXEL_INDEX, \ |
1876 | dstR, dstG, dstB); \ |
1877 | } else { \ |
1878 | Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ |
1879 | FG_PIXEL, PREFIX); \ |
1880 | } \ |
1881 | } \ |
1882 | } while (0) |
1883 | |
1884 | |
1885 | /* There is no alpha channel in the glyph data with which to interpolate |
1886 | * between the src and dst alphas, but a reasonable approximation is to |
1887 | * sum the coverage alphas of the colour channels and divide by 3. |
1888 | * We can approximate division by 3 using mult and shift. See |
1889 | * sun/font/scalerMethods.c for a detailed explanation of why "21931" |
1890 | */ |
1891 | #define GlyphListLCDBlend4ByteArgb(DST, GLYPH_PIXELS, PIXEL_INDEX, DST_PTR, \ |
1892 | FG_PIXEL, PREFIX, SRC_PREFIX) \ |
1893 | do { \ |
1894 | DeclareAlphaVarFor4ByteArgb(dstA) \ |
1895 | DeclareCompVarsFor4ByteArgb(dst) \ |
1896 | jint mixValSrcG = GLYPH_PIXELS[PIXEL_INDEX*3+1]; \ |
1897 | jint mixValSrcR, mixValSrcB; \ |
1898 | if (rgbOrder) { \ |
1899 | mixValSrcR = GLYPH_PIXELS[PIXEL_INDEX*3]; \ |
1900 | mixValSrcB = GLYPH_PIXELS[PIXEL_INDEX*3+2]; \ |
1901 | } else { \ |
1902 | mixValSrcR = GLYPH_PIXELS[PIXEL_INDEX*3+2]; \ |
1903 | mixValSrcB = GLYPH_PIXELS[PIXEL_INDEX*3]; \ |
1904 | } \ |
1905 | if ((mixValSrcR | mixValSrcG | mixValSrcB) != 0) { \ |
1906 | if ((mixValSrcR & mixValSrcG & mixValSrcB) < 255) { \ |
1907 | jint mixValDstR = 255 - mixValSrcR; \ |
1908 | jint mixValDstG = 255 - mixValSrcG; \ |
1909 | jint mixValDstB = 255 - mixValSrcB; \ |
1910 | jint mixValSrcA = ((mixValSrcR + mixValSrcG + mixValSrcB) \ |
1911 | * 21931) >> 16;\ |
1912 | jint mixValDstA = 255 - mixValSrcA; \ |
1913 | Load ## DST ## To4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \ |
1914 | dstA, dstR, dstG, dstB); \ |
1915 | dstR = invGammaLut[dstR]; \ |
1916 | dstG = invGammaLut[dstG]; \ |
1917 | dstB = invGammaLut[dstB]; \ |
1918 | dstA = MUL8(dstA, mixValDstA) + \ |
1919 | MUL8(SRC_PREFIX ## A, mixValSrcA); \ |
1920 | MultMultAddAndStoreLCD4ByteArgbComps(dst, mixValDst, dst, \ |
1921 | mixValSrc, SRC_PREFIX); \ |
1922 | dstR = gammaLut[dstR]; \ |
1923 | dstG = gammaLut[dstG]; \ |
1924 | dstB = gammaLut[dstB]; \ |
1925 | if (!(DST ## IsOpaque) && \ |
1926 | !(DST ## IsPremultiplied) && dstA && dstA < 255) { \ |
1927 | DivideAndStore4ByteArgbComps(dst, dst, dstA); \ |
1928 | } \ |
1929 | Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \ |
1930 | PIXEL_INDEX, dst); \ |
1931 | } else { \ |
1932 | Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \ |
1933 | FG_PIXEL, PREFIX); \ |
1934 | } \ |
1935 | } \ |
1936 | } while (0); |
1937 | |
1938 | #define DEFINE_SOLID_DRAWGLYPHLISTLCD(DST, STRATEGY) \ |
1939 | void NAME_SOLID_DRAWGLYPHLISTLCD(DST)(SurfaceDataRasInfo *pRasInfo, \ |
1940 | ImageRef *glyphs, \ |
1941 | jint totalGlyphs, jint fgpixel, \ |
1942 | jint argbcolor, \ |
1943 | jint clipLeft, jint clipTop, \ |
1944 | jint clipRight, jint clipBottom, \ |
1945 | jint rgbOrder, \ |
1946 | unsigned char *gammaLut, \ |
1947 | unsigned char * invGammaLut, \ |
1948 | NativePrimitive *pPrim, \ |
1949 | CompositeInfo *pCompInfo) \ |
1950 | { \ |
1951 | jint glyphCounter, bpp; \ |
1952 | jint scan = pRasInfo->scanStride; \ |
1953 | DST ## DataType *pPix; \ |
1954 | Declare ## DST ## PixelData(solidpix) \ |
1955 | DeclareAlphaVarFor ## STRATEGY(srcA) \ |
1956 | DeclareCompVarsFor ## STRATEGY(src) \ |
1957 | \ |
1958 | Declare ## DST ## LoadVars(pix) \ |
1959 | Declare ## DST ## StoreVars(pix) \ |
1960 | \ |
1961 | Init ## DST ## LoadVars(pix, pRasInfo); \ |
1962 | Init ## DST ## StoreVarsY(pix, pRasInfo); \ |
1963 | Init ## DST ## StoreVarsX(pix, pRasInfo); \ |
1964 | Extract ## STRATEGY ## CompsAndAlphaFromArgb(argbcolor, src); \ |
1965 | Extract ## DST ## PixelData(fgpixel, solidpix); \ |
1966 | srcR = invGammaLut[srcR]; \ |
1967 | srcG = invGammaLut[srcG]; \ |
1968 | srcB = invGammaLut[srcB]; \ |
1969 | \ |
1970 | for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { \ |
1971 | DeclareDrawGlyphListClipVars(pixels, rowBytes, width, height, \ |
1972 | left, top, right, bottom) \ |
1973 | bpp = \ |
1974 | (glyphs[glyphCounter].rowBytes == glyphs[glyphCounter].width) ? 1 : 3;\ |
1975 | ClipDrawGlyphList(DST, pixels, bpp, rowBytes, width, height, \ |
1976 | left, top, right, bottom, \ |
1977 | clipLeft, clipTop, clipRight, clipBottom, \ |
1978 | glyphs, glyphCounter, continue) \ |
1979 | pPix = PtrCoord(pRasInfo->rasBase,left,DST ## PixelStride,top,scan); \ |
1980 | \ |
1981 | Set ## DST ## StoreVarsYPos(pix, pRasInfo, top); \ |
1982 | if (bpp!=1) { \ |
1983 | /* subpixel positioning adjustment */ \ |
1984 | pixels += glyphs[glyphCounter].rowBytesOffset; \ |
1985 | } \ |
1986 | do { \ |
1987 | int x = 0; \ |
1988 | Set ## DST ## StoreVarsXPos(pix, pRasInfo, left); \ |
1989 | if (bpp==1) { \ |
1990 | do { \ |
1991 | if (pixels[x]) { \ |
1992 | Store ## DST ## PixelData(pPix, x, fgpixel, solidpix);\ |
1993 | } \ |
1994 | } while (++x < width); \ |
1995 | } else { \ |
1996 | do { \ |
1997 | GlyphListLCDBlend ## STRATEGY(DST, pixels, x, pPix, \ |
1998 | fgpixel, solidpix, src); \ |
1999 | Next ## DST ## StoreVarsX(pix); \ |
2000 | } while (++x < width); \ |
2001 | } \ |
2002 | pPix = PtrAddBytes(pPix, scan); \ |
2003 | pixels += rowBytes; \ |
2004 | Next ## DST ## StoreVarsY(pix); \ |
2005 | } while (--height > 0); \ |
2006 | } \ |
2007 | } |
2008 | |
2009 | #define DEFINE_XOR_DRAWGLYPHLIST(DST) \ |
2010 | void NAME_XOR_DRAWGLYPHLIST(DST)(SurfaceDataRasInfo *pRasInfo, \ |
2011 | ImageRef *glyphs, \ |
2012 | jint totalGlyphs, jint fgpixel, \ |
2013 | jint argbcolor, \ |
2014 | jint clipLeft, jint clipTop, \ |
2015 | jint clipRight, jint clipBottom, \ |
2016 | NativePrimitive *pPrim, \ |
2017 | CompositeInfo *pCompInfo) \ |
2018 | { \ |
2019 | jint glyphCounter; \ |
2020 | jint scan = pRasInfo->scanStride; \ |
2021 | jint xorpixel = pCompInfo->details.xorPixel; \ |
2022 | juint alphamask = pCompInfo->alphaMask; \ |
2023 | Declare ## DST ## PixelData(xor) \ |
2024 | Declare ## DST ## PixelData(pix) \ |
2025 | Declare ## DST ## PixelData(mask) \ |
2026 | DST ## DataType *pPix; \ |
2027 | \ |
2028 | Extract ## DST ## PixelData(xorpixel, xor); \ |
2029 | Extract ## DST ## PixelData(fgpixel, pix); \ |
2030 | Extract ## DST ## PixelData(alphamask, mask); \ |
2031 | for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { \ |
2032 | DeclareDrawGlyphListClipVars(pixels, rowBytes, width, height, \ |
2033 | left, top, right, bottom) \ |
2034 | ClipDrawGlyphList(DST, pixels, 1, rowBytes, width, height, \ |
2035 | left, top, right, bottom, \ |
2036 | clipLeft, clipTop, clipRight, clipBottom, \ |
2037 | glyphs, glyphCounter, continue) \ |
2038 | pPix = PtrCoord(pRasInfo->rasBase,left,DST ## PixelStride,top,scan); \ |
2039 | \ |
2040 | do { \ |
2041 | int x = 0; \ |
2042 | do { \ |
2043 | if (pixels[x]) { \ |
2044 | Xor ## DST ## PixelData(fgpixel, pix, pPix, x, \ |
2045 | xorpixel, xor, alphamask, mask); \ |
2046 | } \ |
2047 | } while (++x < width); \ |
2048 | pPix = PtrAddBytes(pPix, scan); \ |
2049 | pixels += rowBytes; \ |
2050 | } while (--height > 0); \ |
2051 | } \ |
2052 | } |
2053 | |
2054 | #define DEFINE_TRANSFORMHELPER_NN(SRC) \ |
2055 | void NAME_TRANSFORMHELPER_NN(SRC)(SurfaceDataRasInfo *pSrcInfo, \ |
2056 | jint *pRGB, jint numpix, \ |
2057 | jlong xlong, jlong dxlong, \ |
2058 | jlong ylong, jlong dylong) \ |
2059 | { \ |
2060 | Declare ## SRC ## LoadVars(SrcRead) \ |
2061 | SRC ## DataType *pBase = pSrcInfo->rasBase; \ |
2062 | jint scan = pSrcInfo->scanStride; \ |
2063 | jint *pEnd = pRGB + numpix; \ |
2064 | \ |
2065 | xlong += IntToLong(pSrcInfo->bounds.x1); \ |
2066 | ylong += IntToLong(pSrcInfo->bounds.y1); \ |
2067 | \ |
2068 | Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \ |
2069 | while (pRGB < pEnd) { \ |
2070 | SRC ## DataType *pRow = PtrAddBytes(pBase, WholeOfLong(ylong) * scan); \ |
2071 | Copy ## SRC ## ToIntArgbPre(pRGB, 0, \ |
2072 | SrcRead, pRow, WholeOfLong(xlong)); \ |
2073 | pRGB++; \ |
2074 | xlong += dxlong; \ |
2075 | ylong += dylong; \ |
2076 | } \ |
2077 | } |
2078 | |
2079 | #define DEFINE_TRANSFORMHELPER_BL(SRC) \ |
2080 | void NAME_TRANSFORMHELPER_BL(SRC)(SurfaceDataRasInfo *pSrcInfo, \ |
2081 | jint *pRGB, jint numpix, \ |
2082 | jlong xlong, jlong dxlong, \ |
2083 | jlong ylong, jlong dylong) \ |
2084 | { \ |
2085 | Declare ## SRC ## LoadVars(SrcRead) \ |
2086 | jint scan = pSrcInfo->scanStride; \ |
2087 | jint cx, cy, cw, ch; \ |
2088 | jint *pEnd = pRGB + numpix*4; \ |
2089 | \ |
2090 | cx = pSrcInfo->bounds.x1; \ |
2091 | cw = pSrcInfo->bounds.x2-cx; \ |
2092 | \ |
2093 | cy = pSrcInfo->bounds.y1; \ |
2094 | ch = pSrcInfo->bounds.y2-cy; \ |
2095 | \ |
2096 | xlong -= LongOneHalf; \ |
2097 | ylong -= LongOneHalf; \ |
2098 | \ |
2099 | Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \ |
2100 | while (pRGB < pEnd) { \ |
2101 | jint xwhole = WholeOfLong(xlong); \ |
2102 | jint ywhole = WholeOfLong(ylong); \ |
2103 | jint xdelta, ydelta, isneg; \ |
2104 | SRC ## DataType *pRow; \ |
2105 | \ |
2106 | xdelta = ((juint) (xwhole + 1 - cw)) >> 31; \ |
2107 | isneg = xwhole >> 31; \ |
2108 | xwhole -= isneg; \ |
2109 | xdelta += isneg; \ |
2110 | \ |
2111 | ydelta = ((ywhole + 1 - ch) >> 31); \ |
2112 | isneg = ywhole >> 31; \ |
2113 | ywhole -= isneg; \ |
2114 | ydelta -= isneg; \ |
2115 | ydelta &= scan; \ |
2116 | \ |
2117 | xwhole += cx; \ |
2118 | pRow = PtrAddBytes(pSrcInfo->rasBase, (ywhole + cy) * scan); \ |
2119 | Copy ## SRC ## ToIntArgbPre(pRGB, 0, SrcRead, pRow, xwhole); \ |
2120 | Copy ## SRC ## ToIntArgbPre(pRGB, 1, SrcRead, pRow, xwhole+xdelta); \ |
2121 | pRow = PtrAddBytes(pRow, ydelta); \ |
2122 | Copy ## SRC ## ToIntArgbPre(pRGB, 2, SrcRead, pRow, xwhole); \ |
2123 | Copy ## SRC ## ToIntArgbPre(pRGB, 3, SrcRead, pRow, xwhole+xdelta); \ |
2124 | \ |
2125 | pRGB += 4; \ |
2126 | xlong += dxlong; \ |
2127 | ylong += dylong; \ |
2128 | } \ |
2129 | } |
2130 | |
2131 | #define DEFINE_TRANSFORMHELPER_BC(SRC) \ |
2132 | void NAME_TRANSFORMHELPER_BC(SRC)(SurfaceDataRasInfo *pSrcInfo, \ |
2133 | jint *pRGB, jint numpix, \ |
2134 | jlong xlong, jlong dxlong, \ |
2135 | jlong ylong, jlong dylong) \ |
2136 | { \ |
2137 | Declare ## SRC ## LoadVars(SrcRead) \ |
2138 | jint scan = pSrcInfo->scanStride; \ |
2139 | jint cx, cy, cw, ch; \ |
2140 | jint *pEnd = pRGB + numpix*16; \ |
2141 | \ |
2142 | cx = pSrcInfo->bounds.x1; \ |
2143 | cw = pSrcInfo->bounds.x2-cx; \ |
2144 | \ |
2145 | cy = pSrcInfo->bounds.y1; \ |
2146 | ch = pSrcInfo->bounds.y2-cy; \ |
2147 | \ |
2148 | xlong -= LongOneHalf; \ |
2149 | ylong -= LongOneHalf; \ |
2150 | \ |
2151 | Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \ |
2152 | while (pRGB < pEnd) { \ |
2153 | jint xwhole = WholeOfLong(xlong); \ |
2154 | jint ywhole = WholeOfLong(ylong); \ |
2155 | jint xdelta0, xdelta1, xdelta2; \ |
2156 | jint ydelta0, ydelta1, ydelta2; \ |
2157 | jint isneg; \ |
2158 | SRC ## DataType *pRow; \ |
2159 | \ |
2160 | xdelta0 = (-xwhole) >> 31; \ |
2161 | xdelta1 = ((juint) (xwhole + 1 - cw)) >> 31; \ |
2162 | xdelta2 = ((juint) (xwhole + 2 - cw)) >> 31; \ |
2163 | isneg = xwhole >> 31; \ |
2164 | xwhole -= isneg; \ |
2165 | xdelta1 += isneg; \ |
2166 | xdelta2 += xdelta1; \ |
2167 | \ |
2168 | ydelta0 = ((-ywhole) >> 31) & (-scan); \ |
2169 | ydelta1 = ((ywhole + 1 - ch) >> 31) & scan; \ |
2170 | ydelta2 = ((ywhole + 2 - ch) >> 31) & scan; \ |
2171 | isneg = ywhole >> 31; \ |
2172 | ywhole -= isneg; \ |
2173 | ydelta1 += (isneg & -scan); \ |
2174 | \ |
2175 | xwhole += cx; \ |
2176 | pRow = PtrAddBytes(pSrcInfo->rasBase, (ywhole + cy) * scan); \ |
2177 | pRow = PtrAddBytes(pRow, ydelta0); \ |
2178 | Copy ## SRC ## ToIntArgbPre(pRGB, 0, SrcRead, pRow, xwhole+xdelta0); \ |
2179 | Copy ## SRC ## ToIntArgbPre(pRGB, 1, SrcRead, pRow, xwhole ); \ |
2180 | Copy ## SRC ## ToIntArgbPre(pRGB, 2, SrcRead, pRow, xwhole+xdelta1); \ |
2181 | Copy ## SRC ## ToIntArgbPre(pRGB, 3, SrcRead, pRow, xwhole+xdelta2); \ |
2182 | pRow = PtrAddBytes(pRow, -ydelta0); \ |
2183 | Copy ## SRC ## ToIntArgbPre(pRGB, 4, SrcRead, pRow, xwhole+xdelta0); \ |
2184 | Copy ## SRC ## ToIntArgbPre(pRGB, 5, SrcRead, pRow, xwhole ); \ |
2185 | Copy ## SRC ## ToIntArgbPre(pRGB, 6, SrcRead, pRow, xwhole+xdelta1); \ |
2186 | Copy ## SRC ## ToIntArgbPre(pRGB, 7, SrcRead, pRow, xwhole+xdelta2); \ |
2187 | pRow = PtrAddBytes(pRow, ydelta1); \ |
2188 | Copy ## SRC ## ToIntArgbPre(pRGB, 8, SrcRead, pRow, xwhole+xdelta0); \ |
2189 | Copy ## SRC ## ToIntArgbPre(pRGB, 9, SrcRead, pRow, xwhole ); \ |
2190 | Copy ## SRC ## ToIntArgbPre(pRGB, 10, SrcRead, pRow, xwhole+xdelta1); \ |
2191 | Copy ## SRC ## ToIntArgbPre(pRGB, 11, SrcRead, pRow, xwhole+xdelta2); \ |
2192 | pRow = PtrAddBytes(pRow, ydelta2); \ |
2193 | Copy ## SRC ## ToIntArgbPre(pRGB, 12, SrcRead, pRow, xwhole+xdelta0); \ |
2194 | Copy ## SRC ## ToIntArgbPre(pRGB, 13, SrcRead, pRow, xwhole ); \ |
2195 | Copy ## SRC ## ToIntArgbPre(pRGB, 14, SrcRead, pRow, xwhole+xdelta1); \ |
2196 | Copy ## SRC ## ToIntArgbPre(pRGB, 15, SrcRead, pRow, xwhole+xdelta2); \ |
2197 | \ |
2198 | pRGB += 16; \ |
2199 | xlong += dxlong; \ |
2200 | ylong += dylong; \ |
2201 | } \ |
2202 | } |
2203 | |
2204 | #define DEFINE_TRANSFORMHELPER_FUNCS(SRC) \ |
2205 | TransformHelperFuncs NAME_TRANSFORMHELPER_FUNCS(SRC) = { \ |
2206 | NAME_TRANSFORMHELPER_NN(SRC), \ |
2207 | NAME_TRANSFORMHELPER_BL(SRC), \ |
2208 | NAME_TRANSFORMHELPER_BC(SRC), \ |
2209 | }; |
2210 | |
2211 | #define DEFINE_TRANSFORMHELPERS(SRC) \ |
2212 | DEFINE_TRANSFORMHELPER_NN(SRC) \ |
2213 | DEFINE_TRANSFORMHELPER_BL(SRC) \ |
2214 | DEFINE_TRANSFORMHELPER_BC(SRC) \ |
2215 | DEFINE_TRANSFORMHELPER_FUNCS(SRC) |
2216 | |
2217 | /* |
2218 | * The macros defined above use the following macro definitions supplied |
2219 | * for the various surface types to manipulate pixels and pixel data. |
2220 | * The surface-specific macros are typically supplied by header files |
2221 | * named after the SurfaceType name (i.e. IntArgb.h, ByteGray.h, etc.). |
2222 | * |
2223 | * In the macro names in the following definitions, the string <stype> |
2224 | * is used as a place holder for the SurfaceType name (i.e. IntArgb). |
2225 | * The macros above access these type specific macros using the ANSI |
2226 | * CPP token concatenation operator "##". |
2227 | * |
2228 | * <stype>DataType A typedef for the type of the pointer |
2229 | * that is used to access the raster data |
2230 | * for the given surface type. |
2231 | * <stype>PixelStride Pixel stride for the surface type. |
2232 | * |
2233 | * Declare<stype>LoadVars Declare the variables needed to control |
2234 | * loading color information from an stype |
2235 | * raster (i.e. lookup tables). |
2236 | * Init<stype>LoadVars Init the lookup table variables. |
2237 | * Declare<stype>StoreVars Declare the storage variables needed to |
2238 | * control storing pixel data based on the |
2239 | * pixel coordinate (i.e. dithering variables). |
2240 | * Init<stype>StoreVarsY Init the dither variables for starting Y. |
2241 | * Next<stype>StoreVarsY Increment the dither variables for next Y. |
2242 | * Init<stype>StoreVarsX Init the dither variables for starting X. |
2243 | * Next<stype>StoreVarsX Increment the dither variables for next X. |
2244 | * |
2245 | * Load<stype>To1IntRgb Load a pixel and form an INT_RGB integer. |
2246 | * Store<stype>From1IntRgb Store a pixel from an INT_RGB integer. |
2247 | * Load<stype>To1IntArgb Load a pixel and form an INT_ARGB integer. |
2248 | * Store<stype>From1IntArgb Store a pixel from an INT_ARGB integer. |
2249 | * Load<stype>To3ByteRgb Load a pixel into R, G, and B components. |
2250 | * Store<stype>From3ByteRgb Store a pixel from R, G, and B components. |
2251 | * Load<stype>To4ByteArgb Load a pixel into A, R, G, and B components. |
2252 | * Store<stype>From4ByteArgb Store a pixel from A, R, G, and B components. |
2253 | * Load<stype>To1ByteGray Load a pixel and form a BYTE_GRAY byte. |
2254 | * Store<stype>From1ByteGray Store a pixel from a BYTE_GRAY byte. |
2255 | * |
2256 | * <stype>PixelType Typedef for a "single quantity pixel" (SQP) |
2257 | * that can hold the data for one stype pixel. |
2258 | * <stype>XparLutEntry An SQP that can be used to represent a |
2259 | * transparent pixel for stype. |
2260 | * Store<stype>NonXparFromArgb Store an SQP from an INT_ARGB integer in |
2261 | * such a way that it would not be confused |
2262 | * with the XparLutEntry value for stype. |
2263 | * <stype>IsXparLutEntry Test an SQP for the XparLutEntry value. |
2264 | * Store<stype>Pixel Store the pixel data from an SQP. |
2265 | * <stype>PixelFromArgb Converts an INT_ARGB value into the specific |
2266 | * pixel representation for the surface type. |
2267 | * |
2268 | * Declare<stype>PixelData Declare the pixel data variables (PDV) needed |
2269 | * to hold the elements of pixel data ready to |
2270 | * store into an stype raster (may be empty for |
2271 | * stypes whose SQP format is their data format). |
2272 | * Extract<stype>PixelData Extract an SQP value into the PDVs. |
2273 | * Store<stype>PixelData Store the PDVs into an stype raster. |
2274 | * XorCopy<stype>PixelData Xor the PDVs into an stype raster. |
2275 | */ |
2276 | #endif /* LoopMacros_h_Included */ |
2277 | |