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