1 /*
2  * Copyright (c) 2000, 2013, 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 AnyByteBinary_h_Included
27 #define AnyByteBinary_h_Included
28 
29 #include <string.h>
30 
31 #include "AlphaMacros.h"
32 #include "GraphicsPrimitiveMgr.h"
33 #include "LoopMacros.h"
34 #include "LineUtils.h"
35 
36 /*
37  * This file contains macros that are similar to those found in LoopMacros.h
38  * and AlphaMacros.h, yet have been specialized to manipulate any one of the
39  * surfaces in the "ByteBinary" family.  It also contains generalized versions
40  * of some macros that are used by the more specific ByteBinary surfaces.
41  */
42 
43 /* REMIND: the ByteBinary store macros should probably do ordered dithering */
44 #define DeclareByteBinaryLoadVars(PREFIX) \
45     jint *PREFIX ## Lut;
46 
47 #define DeclareByteBinaryStoreVars(PREFIX) \
48     unsigned char *PREFIX ## InvLut;
49 
50 #define SetByteBinaryStoreVarsYPos(PREFIX, pRasInfo, LOC)
51 #define SetByteBinaryStoreVarsXPos(PREFIX, pRasInfo, LOC)
52 
53 #define InitByteBinaryLoadVars(PREFIX, pRasInfo) \
54     PREFIX ## Lut = (pRasInfo)->lutBase
55 
56 #define InitByteBinaryStoreVarsY(PREFIX, pRasInfo) \
57     PREFIX ## InvLut = (pRasInfo)->invColorTable
58 
59 #define InitByteBinaryStoreVarsX(PREFIX, pRasInfo)
60 #define NextByteBinaryStoreVarsX(PREFIX)
61 #define NextByteBinaryStoreVarsY(PREFIX)
62 
63 
64 #define DeclareByteBinaryInitialLoadVars(TYPE, INFO, pRas, PREFIX, x) \
65     int PREFIX ## adjx = (x) + (INFO)->pixelBitOffset / TYPE ## BitsPerPixel; \
66     int PREFIX ## index = (PREFIX ## adjx) / TYPE ## PixelsPerByte; \
67     int PREFIX ## bits = TYPE ## MaxBitOffset - \
68                              (((PREFIX ## adjx) % TYPE ## PixelsPerByte) * \
69                               TYPE ## BitsPerPixel); \
70     int PREFIX ## bbpix = (pRas)[PREFIX ## index];
71 
72 #define InitialLoadByteBinary(TYPE, pRas, PREFIX) \
73     do { \
74         if (PREFIX ## bits < 0) { \
75             (pRas)[PREFIX ## index] = (jubyte) PREFIX ## bbpix; \
76             PREFIX ## bbpix = (pRas)[++(PREFIX ## index)]; \
77             PREFIX ## bits = TYPE ## MaxBitOffset; \
78         } \
79     } while (0)
80 
81 #define ShiftBitsByteBinary(TYPE, PREFIX) \
82     PREFIX ## bits -= TYPE ## BitsPerPixel
83 
84 #define FinalStoreByteBinary(TYPE, pRas, PREFIX) \
85     (pRas)[PREFIX ## index] = (jubyte) PREFIX ## bbpix
86 
87 #define CurrentPixelByteBinary(TYPE, PREFIX) \
88     ((PREFIX ## bbpix >> PREFIX ## bits) & TYPE ## PixelMask)
89 
90 
91 #define StoreByteBinaryPixel(TYPE, pRas, x, pixel)
92 
93 #define StoreByteBinaryPixelData(TYPE, pPix, x, pixel, PREFIX) \
94     do { \
95         PREFIX ## bbpix &= ~(TYPE ## PixelMask << PREFIX ## bits); \
96         PREFIX ## bbpix |= (pixel << PREFIX ## bits); \
97     } while (0)
98 
99 #define ByteBinaryPixelFromArgb(TYPE, pixel, rgb, pRasInfo) \
100     do { \
101         jint r, g, b; \
102         ExtractIntDcmComponentsX123(rgb, r, g, b); \
103         (pixel) = SurfaceData_InvColorMap((pRasInfo)->invColorTable, \
104                                           r, g, b); \
105     } while (0)
106 
107 #define XorByteBinaryPixelData(TYPE, pDst, x, PREFIX, \
108                                srcpixel, xorpixel, mask) \
109     PREFIX ## bbpix ^= ((((srcpixel) ^ (xorpixel)) & TYPE ## PixelMask) \
110                            << PREFIX ## bits)
111 
112 
113 #define LoadByteBinaryTo1IntRgb(TYPE, pRas, PREFIX, x, rgb) \
114     (rgb) = PREFIX ## Lut[CurrentPixelByteBinary(TYPE, PREFIX)]
115 
116 #define LoadByteBinaryTo1IntArgb(TYPE, pRas, PREFIX, x, argb) \
117     (argb) = PREFIX ## Lut[CurrentPixelByteBinary(TYPE, PREFIX)]
118 
119 #define LoadByteBinaryTo3ByteRgb(TYPE, pRas, PREFIX, x, r, g, b) \
120     do { \
121         jint rgb = PREFIX ## Lut[CurrentPixelByteBinary(TYPE, PREFIX)]; \
122         ExtractIntDcmComponentsX123(rgb, r, g, b); \
123     } while (0)
124 
125 #define LoadByteBinaryTo4ByteArgb(TYPE, pRas, PREFIX, x, a, r, g, b) \
126     do { \
127         jint argb = PREFIX ## Lut[CurrentPixelByteBinary(TYPE, PREFIX)]; \
128         ExtractIntDcmComponents1234(argb, a, r, g, b); \
129     } while (0)
130 
131 #define StoreByteBinaryFrom1IntRgb(TYPE, pRas, PREFIX, x, rgb) \
132     do { \
133         int r, g, b; \
134         ExtractIntDcmComponentsX123(rgb, r, g, b); \
135         StoreByteBinaryFrom3ByteRgb(TYPE, pRas, PREFIX, x, r, g, b); \
136     } while (0)
137 
138 #define StoreByteBinaryFrom1IntArgb(TYPE, pRas, PREFIX, x, argb) \
139     StoreByteBinaryFrom1IntRgb(TYPE, pRas, PREFIX, x, argb)
140 
141 #define StoreByteBinaryFrom3ByteRgb(TYPE, pRas, PREFIX, x, r, g, b) \
142     StoreByteBinaryPixelData(TYPE, pRas, x, \
143                              SurfaceData_InvColorMap(PREFIX ## InvLut, \
144                                                      r, g, b), \
145                              PREFIX)
146 
147 #define StoreByteBinaryFrom4ByteArgb(TYPE, pRas, PREFIX, x, a, r, g, b) \
148     StoreByteBinaryFrom3ByteRgb(TYPE, pRas, PREFIX, x, r, g, b)
149 
150 
151 #define DeclareByteBinaryAlphaLoadData(TYPE, PREFIX) \
152     jint *PREFIX ## Lut; \
153     jint PREFIX ## rgb;
154 
155 #define InitByteBinaryAlphaLoadData(TYPE, PREFIX, pRasInfo) \
156     do { \
157         PREFIX ## Lut = (pRasInfo)->lutBase; \
158         PREFIX ## rgb = 0; \
159     } while (0)
160 
161 #define LoadAlphaFromByteBinaryFor4ByteArgb(TYPE, pRas, PREFIX, COMP_PREFIX) \
162     do { \
163         PREFIX ## rgb = PREFIX ## Lut[CurrentPixelByteBinary(TYPE, PREFIX)]; \
164         COMP_PREFIX ## A = ((juint) PREFIX ## rgb) >> 24; \
165     } while (0)
166 
167 #define Postload4ByteArgbFromByteBinary(TYPE, pRas, PREFIX, COMP_PREFIX) \
168     do { \
169         COMP_PREFIX ## R = (PREFIX ## rgb >> 16) & 0xff; \
170         COMP_PREFIX ## G = (PREFIX ## rgb >>  8) & 0xff; \
171         COMP_PREFIX ## B = (PREFIX ## rgb >>  0) & 0xff; \
172     } while (0)
173 
174 
175 #define ByteBinaryIsPremultiplied       0
176 
177 #define StoreByteBinaryFrom4ByteArgbComps(TYPE, pRas, PREFIX, x, COMP_PREFIX)\
178     StoreByteBinaryFrom4ByteArgb(TYPE, pRas, PREFIX, x, \
179                                  COMP_PREFIX ## A, COMP_PREFIX ## R, \
180                                  COMP_PREFIX ## G, COMP_PREFIX ## B)
181 
182 
183 
184 
185 #define BBBlitLoopWidthHeight(SRCTYPE, SRCPTR, SRCBASE, SRCINFO, SRCPREFIX, \
186                               DSTTYPE, DSTPTR, DSTBASE, DSTINFO, DSTPREFIX, \
187                               WIDTH, HEIGHT, BODY) \
188     do { \
189         SRCTYPE ## DataType *SRCPTR = (SRCTYPE ## DataType *) (SRCBASE); \
190         DSTTYPE ## DataType *DSTPTR = (DSTTYPE ## DataType *) (DSTBASE); \
191         jint srcScan = (SRCINFO)->scanStride; \
192         jint dstScan = (DSTINFO)->scanStride; \
193         jint srcx1 = (SRCINFO)->bounds.x1; \
194         jint dstx1 = (DSTINFO)->bounds.x1; \
195         Init ## DSTTYPE ## StoreVarsY(DSTPREFIX, DSTINFO); \
196         srcScan -= (WIDTH) * SRCTYPE ## PixelStride; \
197         dstScan -= (WIDTH) * DSTTYPE ## PixelStride; \
198         do { \
199             Declare ## SRCTYPE ## InitialLoadVars(SRCINFO, SRCPTR, SRCPREFIX, \
200                                                   srcx1) \
201             Declare ## DSTTYPE ## InitialLoadVars(DSTINFO, DSTPTR, DSTPREFIX, \
202                                                   dstx1) \
203             juint w = WIDTH; \
204             Init ## DSTTYPE ## StoreVarsX(DSTPREFIX, DSTINFO); \
205             do { \
206                 InitialLoad ## SRCTYPE(SRCPTR, SRCPREFIX); \
207                 InitialLoad ## DSTTYPE(DSTPTR, DSTPREFIX); \
208                 BODY; \
209                 ShiftBits ## SRCTYPE(SRCPREFIX); \
210                 ShiftBits ## DSTTYPE(DSTPREFIX); \
211                 SRCPTR = PtrAddBytes(SRCPTR, SRCTYPE ## PixelStride); \
212                 DSTPTR = PtrAddBytes(DSTPTR, DSTTYPE ## PixelStride); \
213                 Next ## DSTTYPE ## StoreVarsX(DSTPREFIX); \
214             } while (--w > 0); \
215             FinalStore ## DSTTYPE(DSTPTR, DSTPREFIX); \
216             SRCPTR = PtrAddBytes(SRCPTR, srcScan); \
217             DSTPTR = PtrAddBytes(DSTPTR, dstScan); \
218             Next ## DSTTYPE ## StoreVarsY(DSTPREFIX); \
219         } while (--HEIGHT > 0); \
220     } while (0)
221 
222 #define BBXorVia1IntArgb(SRCPTR, SRCTYPE, SRCPREFIX, \
223                          DSTPTR, DSTTYPE, DSTPREFIX, \
224                          XVAR, XORPIXEL, MASK, DSTINFOPTR) \
225     do { \
226         jint srcpixel; \
227         Load ## SRCTYPE ## To1IntArgb(SRCPTR, SRCPREFIX, XVAR, srcpixel); \
228  \
229         if (IsArgbTransparent(srcpixel)) { \
230             break; \
231         } \
232  \
233         DSTTYPE ## PixelFromArgb(srcpixel, srcpixel, DSTINFOPTR); \
234  \
235         Xor ## DSTTYPE ## PixelData(DSTPTR, XVAR, DSTPREFIX, srcpixel, \
236                                     XORPIXEL, MASK); \
237     } while (0)
238 
239 #define DEFINE_BYTE_BINARY_CONVERT_BLIT(SRC, DST, STRATEGY) \
240 void NAME_CONVERT_BLIT(SRC, DST)(void *srcBase, void *dstBase, \
241                                  juint width, juint height, \
242                                  SurfaceDataRasInfo *pSrcInfo, \
243                                  SurfaceDataRasInfo *pDstInfo, \
244                                  NativePrimitive *pPrim, \
245                                  CompositeInfo *pCompInfo) \
246 { \
247     Declare ## SRC ## LoadVars(SrcRead) \
248     Declare ## DST ## StoreVars(DstWrite) \
249  \
250     Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \
251     BBBlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, SrcRead, \
252                           DST, pDst, dstBase, pDstInfo, DstWrite, \
253                           width, height, \
254                           ConvertVia ## STRATEGY(pSrc, SRC, SrcRead, \
255                                                  pDst, DST, DstWrite, \
256                                                  0, 0)); \
257 }
258 
259 #define DEFINE_BYTE_BINARY_XOR_BLIT(SRC, DST) \
260 void NAME_XOR_BLIT(SRC, DST)(void *srcBase, void *dstBase, \
261                              juint width, juint height, \
262                              SurfaceDataRasInfo *pSrcInfo, \
263                              SurfaceDataRasInfo *pDstInfo, \
264                              NativePrimitive *pPrim, \
265                              CompositeInfo *pCompInfo) \
266 { \
267     jint xorpixel = pCompInfo->details.xorPixel; \
268     juint alphamask = pCompInfo->alphaMask; \
269     Declare ## SRC ## LoadVars(SrcRead) \
270     Declare ## DST ## StoreVars(DstWrite) \
271  \
272     Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \
273     BBBlitLoopWidthHeight(SRC, pSrc, srcBase, pSrcInfo, SrcRead, \
274                           DST, pDst, dstBase, pDstInfo, DstWrite, \
275                           width, height, \
276                           BBXorVia1IntArgb(pSrc, SRC, SrcRead, \
277                                            pDst, DST, DstWrite, \
278                                            0, xorpixel, \
279                                            alphamask, pDstInfo)); \
280 }
281 
282 #define DEFINE_BYTE_BINARY_SOLID_FILLRECT(DST) \
283 void NAME_SOLID_FILLRECT(DST)(SurfaceDataRasInfo *pRasInfo, \
284                               jint lox, jint loy, \
285                               jint hix, jint hiy, \
286                               jint pixel, \
287                               NativePrimitive *pPrim, \
288                               CompositeInfo *pCompInfo) \
289 { \
290     DST ## DataType *pPix; \
291     jint scan = pRasInfo->scanStride; \
292     juint height = hiy - loy; \
293     juint width = hix - lox; \
294  \
295     pPix = PtrCoord(pRasInfo->rasBase, lox, DST ## PixelStride, loy, scan); \
296     do { \
297         Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, lox) \
298         jint w = width; \
299         do { \
300             InitialLoad ## DST(pPix, DstPix); \
301             Store ## DST ## PixelData(pPix, 0, pixel, DstPix); \
302             ShiftBits ## DST(DstPix); \
303         } while (--w > 0); \
304         FinalStore ## DST(pPix, DstPix); \
305         pPix = PtrAddBytes(pPix, scan); \
306     } while (--height > 0); \
307 }
308 
309 #define DEFINE_BYTE_BINARY_SOLID_FILLSPANS(DST) \
310 void NAME_SOLID_FILLSPANS(DST)(SurfaceDataRasInfo *pRasInfo, \
311                                SpanIteratorFuncs *pSpanFuncs, void *siData, \
312                                jint pixel, NativePrimitive *pPrim, \
313                                CompositeInfo *pCompInfo) \
314 { \
315     void *pBase = pRasInfo->rasBase; \
316     jint scan = pRasInfo->scanStride; \
317     jint bbox[4]; \
318  \
319     while ((*pSpanFuncs->nextSpan)(siData, bbox)) { \
320         jint x = bbox[0]; \
321         jint y = bbox[1]; \
322         juint w = bbox[2] - x; \
323         juint h = bbox[3] - y; \
324         DST ## DataType *pPix = PtrCoord(pBase, \
325                                          x, DST ## PixelStride, \
326                                          y, scan); \
327         do { \
328             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, x) \
329             jint relx = w; \
330             do { \
331                 InitialLoad ## DST(pPix, DstPix); \
332                 Store ## DST ## PixelData(pPix, 0, pixel, DstPix); \
333                 ShiftBits ## DST(DstPix); \
334             } while (--relx > 0); \
335             FinalStore ## DST(pPix, DstPix); \
336             pPix = PtrAddBytes(pPix, scan); \
337         } while (--h > 0); \
338     } \
339 }
340 
341 #define DEFINE_BYTE_BINARY_SOLID_DRAWLINE(DST) \
342 void NAME_SOLID_DRAWLINE(DST)(SurfaceDataRasInfo *pRasInfo, \
343                               jint x1, jint y1, jint pixel, \
344                               jint steps, jint error, \
345                               jint bumpmajormask, jint errmajor, \
346                               jint bumpminormask, jint errminor, \
347                               NativePrimitive *pPrim, \
348                               CompositeInfo *pCompInfo) \
349 { \
350     jint scan = pRasInfo->scanStride; \
351     DST ## DataType *pPix = PtrCoord(pRasInfo->rasBase, \
352                                      x1, DST ## PixelStride, \
353                                      y1, scan); \
354     DeclareBumps(bumpmajor, bumpminor) \
355  \
356     scan *= DST ## PixelsPerByte; \
357     InitBumps(bumpmajor, bumpminor, bumpmajormask, bumpminormask, 1, scan); \
358     if (errmajor == 0) { \
359         do { \
360             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, x1) \
361             Store ## DST ## PixelData(pPix, 0, pixel, DstPix); \
362             FinalStore ## DST(pPix, DstPix); \
363             x1 += bumpmajor; \
364         } while (--steps > 0); \
365     } else { \
366         do { \
367             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, x1) \
368             Store ## DST ## PixelData(pPix, 0, pixel, DstPix); \
369             FinalStore ## DST(pPix, DstPix); \
370             if (error < 0) { \
371                 x1 += bumpmajor; \
372                 error += errmajor; \
373             } else { \
374                 x1 += bumpminor; \
375                 error -= errminor; \
376             } \
377         } while (--steps > 0); \
378     } \
379 }
380 
381 #define DEFINE_BYTE_BINARY_XOR_FILLRECT(DST) \
382 void NAME_XOR_FILLRECT(DST)(SurfaceDataRasInfo *pRasInfo, \
383                             jint lox, jint loy, \
384                             jint hix, jint hiy, \
385                             jint pixel, \
386                             NativePrimitive *pPrim, \
387                             CompositeInfo *pCompInfo) \
388 { \
389     jint xorpixel = pCompInfo->details.xorPixel; \
390     juint alphamask = pCompInfo->alphaMask; \
391     DST ## DataType *pPix; \
392     jint scan = pRasInfo->scanStride; \
393     juint height = hiy - loy; \
394     juint width = hix - lox; \
395  \
396     pPix = PtrCoord(pRasInfo->rasBase, lox, DST ## PixelStride, loy, scan); \
397     do { \
398         Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, lox) \
399         jint w = width; \
400         do { \
401             InitialLoad ## DST(pPix, DstPix); \
402             Xor ## DST ## PixelData(pPix, 0, DstPix, \
403                                     pixel, xorpixel, alphamask); \
404             ShiftBits ## DST(DstPix); \
405         } while (--w > 0); \
406         FinalStore ## DST(pPix, DstPix); \
407         pPix = PtrAddBytes(pPix, scan); \
408     } while (--height > 0); \
409 }
410 
411 #define DEFINE_BYTE_BINARY_XOR_FILLSPANS(DST) \
412 void NAME_XOR_FILLSPANS(DST)(SurfaceDataRasInfo *pRasInfo, \
413                              SpanIteratorFuncs *pSpanFuncs, \
414                              void *siData, jint pixel, \
415                              NativePrimitive *pPrim, \
416                              CompositeInfo *pCompInfo) \
417 { \
418     void *pBase = pRasInfo->rasBase; \
419     jint xorpixel = pCompInfo->details.xorPixel; \
420     juint alphamask = pCompInfo->alphaMask; \
421     jint scan = pRasInfo->scanStride; \
422     jint bbox[4]; \
423  \
424     while ((*pSpanFuncs->nextSpan)(siData, bbox)) { \
425         jint x = bbox[0]; \
426         jint y = bbox[1]; \
427         juint w = bbox[2] - x; \
428         juint h = bbox[3] - y; \
429         DST ## DataType *pPix = PtrCoord(pBase, \
430                                          x, DST ## PixelStride, \
431                                          y, scan); \
432         do { \
433             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, x) \
434             jint relx = w; \
435             do { \
436                 InitialLoad ## DST(pPix, DstPix); \
437                 Xor ## DST ## PixelData(pPix, 0, DstPix, \
438                                         pixel, xorpixel, alphamask); \
439                 ShiftBits ## DST(DstPix); \
440             } while (--relx > 0); \
441             FinalStore ## DST(pPix, DstPix); \
442             pPix = PtrAddBytes(pPix, scan); \
443         } while (--h > 0); \
444     } \
445 }
446 
447 #define DEFINE_BYTE_BINARY_XOR_DRAWLINE(DST) \
448 void NAME_XOR_DRAWLINE(DST)(SurfaceDataRasInfo *pRasInfo, \
449                             jint x1, jint y1, jint pixel, \
450                             jint steps, jint error, \
451                             jint bumpmajormask, jint errmajor, \
452                             jint bumpminormask, jint errminor, \
453                             NativePrimitive *pPrim, \
454                             CompositeInfo *pCompInfo) \
455 { \
456     jint xorpixel = pCompInfo->details.xorPixel; \
457     juint alphamask = pCompInfo->alphaMask; \
458     jint scan = pRasInfo->scanStride; \
459     DST ## DataType *pPix = PtrCoord(pRasInfo->rasBase, \
460                                      x1, DST ## PixelStride, \
461                                      y1, scan); \
462     DeclareBumps(bumpmajor, bumpminor) \
463  \
464     scan *= DST ## PixelsPerByte; \
465     InitBumps(bumpmajor, bumpminor, bumpmajormask, bumpminormask, 1, scan); \
466  \
467     if (errmajor == 0) { \
468         do { \
469             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, x1) \
470             Xor ## DST ## PixelData(pPix, 0, DstPix, \
471                                     pixel, xorpixel, alphamask); \
472             FinalStore ## DST(pPix, DstPix); \
473             x1 += bumpmajor; \
474         } while (--steps > 0); \
475     } else { \
476         do { \
477             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, x1) \
478             Xor ## DST ## PixelData(pPix, 0, DstPix, \
479                                     pixel, xorpixel, alphamask); \
480             FinalStore ## DST(pPix, DstPix); \
481             if (error < 0) { \
482                 x1 += bumpmajor; \
483                 error += errmajor; \
484             } else { \
485                 x1 += bumpminor; \
486                 error -= errminor; \
487             } \
488         } while (--steps > 0); \
489     } \
490 }
491 
492 #define DEFINE_BYTE_BINARY_SOLID_DRAWGLYPHLIST(DST) \
493 void NAME_SOLID_DRAWGLYPHLIST(DST)(SurfaceDataRasInfo *pRasInfo, \
494                                    ImageRef *glyphs, \
495                                    jint totalGlyphs, jint fgpixel, \
496                                    jint argbcolor, \
497                                    jint clipLeft, jint clipTop, \
498                                    jint clipRight, jint clipBottom, \
499                                    NativePrimitive *pPrim, \
500                                    CompositeInfo *pCompInfo) \
501 { \
502     jint glyphCounter; \
503     jint scan = pRasInfo->scanStride; \
504     DST ## DataType *pPix; \
505 \
506     for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { \
507         DeclareDrawGlyphListClipVars(pixels, rowBytes, width, height, \
508                                      left, top, right, bottom) \
509         ClipDrawGlyphList(DST, pixels, 1, rowBytes, width, height, \
510                           left, top, right, bottom, \
511                           clipLeft, clipTop, clipRight, clipBottom, \
512                           glyphs, glyphCounter, continue) \
513         pPix = PtrCoord(pRasInfo->rasBase,left,DST ## PixelStride,top,scan); \
514 \
515         do { \
516             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, left) \
517             jint x = 0; \
518             do { \
519                 InitialLoad ## DST(pPix, DstPix); \
520                 if (pixels[x]) { \
521                     Store ## DST ## PixelData(pPix, 0, fgpixel, DstPix); \
522                 } \
523                 ShiftBits ## DST(DstPix); \
524             } while (++x < width); \
525             FinalStore ## DST(pPix, DstPix); \
526             pPix = PtrAddBytes(pPix, scan); \
527             pixels += rowBytes; \
528         } while (--height > 0); \
529     } \
530 }
531 
532 /*
533  * REMIND: we shouldn't be attempting to do antialiased text for the
534  *         ByteBinary surfaces in the first place
535  */
536 #define DEFINE_BYTE_BINARY_SOLID_DRAWGLYPHLISTAA(DST, STRATEGY) \
537 void NAME_SOLID_DRAWGLYPHLISTAA(DST)(SurfaceDataRasInfo *pRasInfo, \
538                                      ImageRef *glyphs, \
539                                      jint totalGlyphs, jint fgpixel, \
540                                      jint argbcolor, \
541                                      jint clipLeft, jint clipTop, \
542                                      jint clipRight, jint clipBottom, \
543                                      NativePrimitive *pPrim, \
544                                      CompositeInfo *pCompInfo) \
545 { \
546     jint glyphCounter; \
547     jint scan = pRasInfo->scanStride; \
548     DST ## DataType *pPix; \
549     DeclareAlphaVarFor ## STRATEGY(srcA) \
550     DeclareCompVarsFor ## STRATEGY(src) \
551 \
552     Declare ## DST ## LoadVars(pix) \
553     Declare ## DST ## StoreVars(pix) \
554 \
555     Init ## DST ## LoadVars(pix, pRasInfo); \
556     Init ## DST ## StoreVarsY(pix, pRasInfo); \
557     Init ## DST ## StoreVarsX(pix, pRasInfo); \
558     Extract ## STRATEGY ## CompsAndAlphaFromArgb(argbcolor, src); \
559 \
560     for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { \
561         DeclareDrawGlyphListClipVars(pixels, rowBytes, width, height, \
562                                      left, top, right, bottom) \
563         ClipDrawGlyphList(DST, pixels, 1, rowBytes, width, height, \
564                           left, top, right, bottom, \
565                           clipLeft, clipTop, clipRight, clipBottom, \
566                           glyphs, glyphCounter, continue) \
567         pPix = PtrCoord(pRasInfo->rasBase,left,DST ## PixelStride,top,scan); \
568 \
569         Set ## DST ## StoreVarsYPos(pix, pRasInfo, top); \
570         do { \
571             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, pix, left) \
572             int x = 0; \
573             Set ## DST ## StoreVarsXPos(pix, pRasInfo, left); \
574             do { \
575                 InitialLoad ## DST(pPix, pix); \
576                 GlyphListAABlend ## STRATEGY(DST, pixels, x, pPix, \
577                                              fgpixel, pix, src); \
578                 ShiftBits ## DST(pix); \
579                 Next ## DST ## StoreVarsX(pix); \
580             } while (++x < width); \
581             FinalStore ## DST(pPix, pix); \
582             pPix = PtrAddBytes(pPix, scan); \
583             pixels += rowBytes; \
584             Next ## DST ## StoreVarsY(pix); \
585         } while (--height > 0); \
586     } \
587 }
588 
589 #define DEFINE_BYTE_BINARY_XOR_DRAWGLYPHLIST(DST) \
590 void NAME_XOR_DRAWGLYPHLIST(DST)(SurfaceDataRasInfo *pRasInfo, \
591                                  ImageRef *glyphs, \
592                                  jint totalGlyphs, jint fgpixel, \
593                                  jint argbcolor, \
594                                  jint clipLeft, jint clipTop, \
595                                  jint clipRight, jint clipBottom, \
596                                  NativePrimitive *pPrim, \
597                                  CompositeInfo *pCompInfo) \
598 { \
599     jint glyphCounter; \
600     jint scan = pRasInfo->scanStride; \
601     jint xorpixel = pCompInfo->details.xorPixel; \
602     juint alphamask = pCompInfo->alphaMask; \
603     DST ## DataType *pPix; \
604  \
605     for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) { \
606         DeclareDrawGlyphListClipVars(pixels, rowBytes, width, height, \
607                                      left, top, right, bottom) \
608         ClipDrawGlyphList(DST, pixels, 1, rowBytes, width, height, \
609                           left, top, right, bottom, \
610                           clipLeft, clipTop, clipRight, clipBottom, \
611                           glyphs, glyphCounter, continue) \
612         pPix = PtrCoord(pRasInfo->rasBase,left,DST ## PixelStride,top,scan); \
613 \
614         do { \
615             Declare ## DST ## InitialLoadVars(pRasInfo, pPix, DstPix, left) \
616             jint x = 0; \
617             do { \
618                 InitialLoad ## DST(pPix, DstPix); \
619                 if (pixels[x]) { \
620                     Xor ## DST ## PixelData(pPix, 0, DstPix, \
621                                             fgpixel, xorpixel, alphamask); \
622                 } \
623                 ShiftBits ## DST(DstPix); \
624             } while (++x < width); \
625             FinalStore ## DST(pPix, DstPix); \
626             pPix = PtrAddBytes(pPix, scan); \
627             pixels += rowBytes; \
628         } while (--height > 0); \
629     } \
630 }
631 
632 #define DEFINE_BYTE_BINARY_ALPHA_MASKBLIT(SRC, DST, STRATEGY) \
633 void NAME_ALPHA_MASKBLIT(SRC, DST) \
634     (void *dstBase, void *srcBase, \
635      jubyte *pMask, jint maskOff, jint maskScan, \
636      jint width, jint height, \
637      SurfaceDataRasInfo *pDstInfo, \
638      SurfaceDataRasInfo *pSrcInfo, \
639      NativePrimitive *pPrim, \
640      CompositeInfo *pCompInfo) \
641 { \
642     DeclareAndSetOpaqueAlphaVarFor ## STRATEGY(pathA) \
643     DeclareAndClearAlphaVarFor ## STRATEGY(srcA) \
644     DeclareAndClearAlphaVarFor ## STRATEGY(dstA) \
645     DeclareAndInitExtraAlphaFor ## STRATEGY(extraA) \
646     jint srcScan = pSrcInfo->scanStride; \
647     jint dstScan = pDstInfo->scanStride; \
648     jboolean loadsrc, loaddst; \
649     jint srcx1 = pSrcInfo->bounds.x1; \
650     jint dstx1 = pDstInfo->bounds.x1; \
651     SRC ## DataType *pSrc = (SRC ## DataType *) (srcBase); \
652     DST ## DataType *pDst = (DST ## DataType *) (dstBase); \
653     Declare ## SRC ## AlphaLoadData(SrcRead) \
654     Declare ## DST ## AlphaLoadData(DstWrite) \
655     Declare ## DST ## StoreVars(DstWrite) \
656     DeclareAlphaOperands(SrcOp) \
657     DeclareAlphaOperands(DstOp) \
658  \
659     ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].srcOps, \
660                                         SrcOp); \
661     ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].dstOps, \
662                                         DstOp); \
663     loadsrc = !FuncIsZero(SrcOp) || FuncNeedsAlpha(DstOp); \
664     loaddst = pMask || !FuncIsZero(DstOp) || FuncNeedsAlpha(SrcOp); \
665  \
666     Init ## SRC ## AlphaLoadData(SrcRead, pSrcInfo); \
667     Init ## DST ## AlphaLoadData(DstWrite, pDstInfo); \
668     srcScan -= width * SRC ## PixelStride; \
669     dstScan -= width * DST ## PixelStride; \
670     maskScan -= width; \
671     if (pMask) { \
672         pMask += maskOff; \
673     } \
674  \
675     Init ## DST ## StoreVarsY(DstWrite, pDstInfo); \
676     do { \
677         Declare ## SRC ## InitialLoadVars(pSrcInfo, pSrc, SrcRead, srcx1) \
678         Declare ## DST ## InitialLoadVars(pDstInfo, pDst, DstWrite, dstx1) \
679         jint w = width; \
680         Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \
681         do { \
682             DeclareAlphaVarFor ## STRATEGY(resA) \
683             DeclareCompVarsFor ## STRATEGY(res) \
684             DeclareAlphaVarFor ## STRATEGY(srcF) \
685             DeclareAlphaVarFor ## STRATEGY(dstF) \
686  \
687             InitialLoad ## SRC(pSrc, SrcRead); \
688             InitialLoad ## DST(pDst, DstWrite); \
689             if (pMask) { \
690                 pathA = *pMask++; \
691                 if (!pathA) { \
692                     ShiftBits ## SRC(SrcRead); \
693                     ShiftBits ## DST(DstWrite); \
694                     pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
695                     pDst = PtrAddBytes(pDst, DST ## PixelStride); \
696                     Next ## DST ## StoreVarsX(DstWrite); \
697                     continue; \
698                 } \
699                 PromoteByteAlphaFor ## STRATEGY(pathA); \
700             } \
701             if (loadsrc) { \
702                 LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc,SrcRead,src); \
703                 srcA = MultiplyAlphaFor ## STRATEGY(extraA, srcA); \
704             } \
705             if (loaddst) { \
706                 LoadAlphaFrom ## DST ## For ## STRATEGY(pDst,DstWrite,dst); \
707             } \
708             srcF = ApplyAlphaOperands(SrcOp, dstA); \
709             dstF = ApplyAlphaOperands(DstOp, srcA); \
710             if (pathA != MaxValFor ## STRATEGY) { \
711                 srcF = MultiplyAlphaFor ## STRATEGY(pathA, srcF); \
712                 dstF = MaxValFor ## STRATEGY - pathA + \
713                            MultiplyAlphaFor ## STRATEGY(pathA, dstF); \
714             } \
715             if (srcF) { \
716                 resA = MultiplyAlphaFor ## STRATEGY(srcF, srcA); \
717                 if (!(SRC ## IsPremultiplied)) { \
718                     srcF = resA; \
719                 } else { \
720                     srcF = MultiplyAlphaFor ## STRATEGY(srcF, extraA); \
721                 } \
722                 if (srcF) { \
723                     /* assert(loadsrc); */ \
724                     Postload ## STRATEGY ## From ## SRC(pSrc, SrcRead, res); \
725                     if (srcF != MaxValFor ## STRATEGY) { \
726                         MultiplyAndStore ## STRATEGY ## Comps(res, \
727                                                               srcF, res); \
728                     } \
729                 } else { \
730                     Set ## STRATEGY ## CompsToZero(res); \
731                 } \
732             } else { \
733                 if (dstF == MaxValFor ## STRATEGY) { \
734                     ShiftBits ## SRC(SrcRead); \
735                     ShiftBits ## DST(DstWrite); \
736                     pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
737                     pDst = PtrAddBytes(pDst, DST ## PixelStride); \
738                     Next ## DST ## StoreVarsX(DstWrite); \
739                     continue; \
740                 } \
741                 resA = 0; \
742                 Set ## STRATEGY ## CompsToZero(res); \
743             } \
744             if (dstF) { \
745                 dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \
746                 if (!(DST ## IsPremultiplied)) { \
747                     dstF = dstA; \
748                 } \
749                 resA += dstA; \
750                 if (dstF) { \
751                     DeclareCompVarsFor ## STRATEGY(tmp) \
752                     /* assert(loaddst); */ \
753                     Postload ## STRATEGY ## From ## DST(pDst,DstWrite,tmp); \
754                     if (dstF != MaxValFor ## STRATEGY) { \
755                         MultiplyAndStore ## STRATEGY ## Comps(tmp, \
756                                                               dstF, tmp); \
757                     } \
758                     Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \
759                 } \
760             } \
761             if (!(DST ## IsPremultiplied) && resA && \
762                 resA < MaxValFor ## STRATEGY) \
763             { \
764                 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
765             } \
766             Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite, \
767                                                       0, res); \
768             ShiftBits ## SRC(SrcRead); \
769             ShiftBits ## DST(DstWrite); \
770             pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
771             pDst = PtrAddBytes(pDst, DST ## PixelStride); \
772             Next ## DST ## StoreVarsX(DstWrite); \
773         } while (--w > 0); \
774         FinalStore ## DST(pDst, DstWrite); \
775         pSrc = PtrAddBytes(pSrc, srcScan); \
776         pDst = PtrAddBytes(pDst, dstScan); \
777         Next ## DST ## StoreVarsY(DstWrite); \
778         if (pMask) { \
779             pMask = PtrAddBytes(pMask, maskScan); \
780         } \
781     } while (--height > 0); \
782 }
783 
784 #define DEFINE_BYTE_BINARY_ALPHA_MASKFILL(TYPE, STRATEGY) \
785 void NAME_ALPHA_MASKFILL(TYPE) \
786     (void *rasBase, \
787      jubyte *pMask, jint maskOff, jint maskScan, \
788      jint width, jint height, \
789      jint fgColor, \
790      SurfaceDataRasInfo *pRasInfo, \
791      NativePrimitive *pPrim, \
792      CompositeInfo *pCompInfo) \
793 { \
794     DeclareAndSetOpaqueAlphaVarFor ## STRATEGY(pathA) \
795     DeclareAlphaVarFor ## STRATEGY(srcA) \
796     DeclareCompVarsFor ## STRATEGY(src) \
797     DeclareAndClearAlphaVarFor ## STRATEGY(dstA) \
798     DeclareAlphaVarFor ## STRATEGY(dstF) \
799     DeclareAlphaVarFor ## STRATEGY(dstFbase) \
800     jint rasScan = pRasInfo->scanStride; \
801     jboolean loaddst; \
802     jint x1 = pRasInfo->bounds.x1; \
803     TYPE ## DataType *pRas = (TYPE ## DataType *) (rasBase); \
804     Declare ## TYPE ## AlphaLoadData(DstWrite) \
805     Declare ## TYPE ## StoreVars(DstWrite) \
806     DeclareAlphaOperands(SrcOp) \
807     DeclareAlphaOperands(DstOp) \
808  \
809     Extract ## STRATEGY ## CompsAndAlphaFromArgb(fgColor, src); \
810     if (srcA != MaxValFor ## STRATEGY) { \
811         MultiplyAndStore ## STRATEGY ## Comps(src, srcA, src); \
812     } \
813  \
814     ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].srcOps, \
815                                         SrcOp); \
816     ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].dstOps, \
817                                         DstOp); \
818     loaddst = pMask || !FuncIsZero(DstOp) || FuncNeedsAlpha(SrcOp); \
819  \
820     dstFbase = dstF = ApplyAlphaOperands(DstOp, srcA); \
821  \
822     Init ## TYPE ## AlphaLoadData(DstWrite, pRasInfo); \
823     maskScan -= width; \
824     if (pMask) { \
825         pMask += maskOff; \
826     } \
827  \
828     Init ## TYPE ## StoreVarsY(DstWrite, pRasInfo); \
829     do { \
830         Declare ## TYPE ## InitialLoadVars(pRasInfo, pRas, DstWrite, x1) \
831         jint w = width; \
832         Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \
833         do { \
834             DeclareAlphaVarFor ## STRATEGY(resA) \
835             DeclareCompVarsFor ## STRATEGY(res) \
836             DeclareAlphaVarFor ## STRATEGY(srcF) \
837  \
838             InitialLoad ## TYPE(pRas, DstWrite); \
839             if (pMask) { \
840                 pathA = *pMask++; \
841                 if (!pathA) { \
842                     ShiftBits ## TYPE(DstWrite); \
843                     Next ## TYPE ## StoreVarsX(DstWrite); \
844                     continue; \
845                 } \
846                 PromoteByteAlphaFor ## STRATEGY(pathA); \
847                 dstF = dstFbase; \
848             } \
849             if (loaddst) { \
850                 LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas,DstWrite,dst);\
851             } \
852             srcF = ApplyAlphaOperands(SrcOp, dstA); \
853             if (pathA != MaxValFor ## STRATEGY) { \
854                 srcF = MultiplyAlphaFor ## STRATEGY(pathA, srcF); \
855                 dstF = MaxValFor ## STRATEGY - pathA + \
856                            MultiplyAlphaFor ## STRATEGY(pathA, dstF); \
857             } \
858             if (srcF) { \
859                 if (srcF == MaxValFor ## STRATEGY) { \
860                     resA = srcA; \
861                     Store ## STRATEGY ## CompsUsingOp(res, =, src); \
862                 } else { \
863                     resA = MultiplyAlphaFor ## STRATEGY(srcF, srcA); \
864                     MultiplyAndStore ## STRATEGY ## Comps(res, srcF, src); \
865                 } \
866             } else { \
867                 if (dstF == MaxValFor ## STRATEGY) { \
868                     ShiftBits ## TYPE(DstWrite); \
869                     Next ## TYPE ## StoreVarsX(DstWrite); \
870                     continue; \
871                 } \
872                 resA = 0; \
873                 Set ## STRATEGY ## CompsToZero(res); \
874             } \
875             if (dstF) { \
876                 dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \
877                 if (!(TYPE ## IsPremultiplied)) { \
878                     dstF = dstA; \
879                 } \
880                 resA += dstA; \
881                 if (dstF) { \
882                     DeclareCompVarsFor ## STRATEGY(tmp) \
883                     /* assert(loaddst); */ \
884                     Postload ## STRATEGY ## From ## TYPE(pRas,DstWrite,tmp); \
885                     if (dstF != MaxValFor ## STRATEGY) { \
886                         MultiplyAndStore ## STRATEGY ## Comps(tmp, \
887                                                               dstF, tmp); \
888                     } \
889                     Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \
890                 } \
891             } \
892             if (!(TYPE ## IsPremultiplied) && resA && \
893                 resA < MaxValFor ## STRATEGY) \
894             { \
895                 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
896             } \
897             Store ## TYPE ## From ## STRATEGY ## Comps(pRas, DstWrite, \
898                                                        0, res); \
899             ShiftBits ## TYPE(DstWrite); \
900             Next ## TYPE ## StoreVarsX(DstWrite); \
901         } while (--w > 0); \
902         FinalStore ## TYPE(pRas, DstWrite); \
903         pRas = PtrAddBytes(pRas, rasScan); \
904         Next ## TYPE ## StoreVarsY(DstWrite); \
905         if (pMask) { \
906             pMask = PtrAddBytes(pMask, maskScan); \
907         } \
908     } while (--height > 0); \
909 }
910 
911 
912 /*
913  * The macros defined above use the following macro definitions supplied
914  * for the various ByteBinary-specific surface types to manipulate pixel data.
915  *
916  * In the macro names in the following definitions, the string <stype>
917  * is used as a place holder for the SurfaceType name (eg. ByteBinary2Bit).
918  * The macros above access these type specific macros using the ANSI
919  * CPP token concatenation operator "##".
920  *
921  * Declare<stype>InitialLoadVars     Declare and initialize the variables used
922  *                                   for managing byte/bit offsets
923  * InitialLoad<stype>                Store the current byte, fetch the next
924  *                                   byte, and reset the bit offset
925  * ShiftBits<stype>                  Advance to the next pixel by adjusting
926  *                                   the bit offset (1, 2, or 4 bits)
927  * FinalStore<stype>                 Store the current byte
928  * CurrentPixel<stype>               Represents the current pixel by shifting
929  *                                   the value with the current bit offset and
930  *                                   then masking the value to either 1, 2, or
931  *                                   4 bits
932  */
933 
934 #endif /* AnyByteBinary_h_Included */
935