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