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 = PtrPixelsRow(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 = PtrPixelsRow(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 = PtrPixelsRow(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 = PtrPixelsRow(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