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) \
836void 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) \
855void 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) \
877void 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) \
903void 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) \
928void 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) \
957void 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) \
986void 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) \
1018void 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) \
1045void 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) \
1075void 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) \
1109void 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) \
1140void 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) \
1170void 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) \
1202void 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) \
1235void 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) \
1266void 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) \
1302void 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) \
1379void 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) \
1423void 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) \
1462void 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) \
1507void 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) \
1613void 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) \
1796void 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) \
1939void 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) \
2010void 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) \
2055void 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) \
2080void 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) \
2132void 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