1/*
2 * Copyright (c) 2000, 2008, 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 AlphaMacros_h_Included
27#define AlphaMacros_h_Included
28
29#include "GraphicsPrimitiveMgr.h"
30#include "AlphaMath.h"
31#include "IntArgb.h" /* for "Extract...FromArgb" macros */
32
33#define DeclareAlphaOperands(PREFIX) \
34 jint PREFIX ## And, PREFIX ## Xor, PREFIX ## Add;
35
36#define ExtractAlphaOperandsFor4ByteArgb(f, PREFIX) \
37 do { \
38 PREFIX ## And = (f).andval; \
39 PREFIX ## Xor = (f).xorval; \
40 PREFIX ## Add = (jint) (f).addval - PREFIX ## Xor; \
41 } while (0)
42
43#define ExtractAlphaOperandsFor1ByteGray(f, PREFIX) \
44 ExtractAlphaOperandsFor4ByteArgb(f, PREFIX)
45
46#define ExtractAlphaOperandsFor1ShortGray(f, PREFIX) \
47 do { \
48 PREFIX ## And = ((f).andval << 8) + (f).andval; \
49 PREFIX ## Xor = (f).xorval; \
50 PREFIX ## Add = (jint) (((f).addval << 8) + (f).addval) - \
51 PREFIX ## Xor; \
52 } while (0)
53
54#define ApplyAlphaOperands(PREFIX, a) \
55 ((((a) & PREFIX ## And) ^ PREFIX ## Xor) + PREFIX ## Add)
56
57#define FuncNeedsAlpha(PREFIX) (PREFIX ## And != 0)
58#define FuncIsZero(PREFIX) ((PREFIX ## And | PREFIX ## Add) == 0)
59
60typedef struct {
61 jubyte addval;
62 jubyte andval;
63 jshort xorval;
64} AlphaOperands;
65
66typedef struct {
67 AlphaOperands srcOps;
68 AlphaOperands dstOps;
69} AlphaFunc;
70
71extern AlphaFunc AlphaRules[];
72
73#define DEFINE_ALPHA_MASKBLIT(SRC, DST, STRATEGY) \
74void NAME_ALPHA_MASKBLIT(SRC, DST) \
75 (void *dstBase, void *srcBase, \
76 jubyte *pMask, jint maskOff, jint maskScan, \
77 jint width, jint height, \
78 SurfaceDataRasInfo *pDstInfo, \
79 SurfaceDataRasInfo *pSrcInfo, \
80 NativePrimitive *pPrim, \
81 CompositeInfo *pCompInfo) \
82{ \
83 DeclareAndSetOpaqueAlphaVarFor ## STRATEGY(pathA) \
84 DeclareAndClearAlphaVarFor ## STRATEGY(srcA) \
85 DeclareAndClearAlphaVarFor ## STRATEGY(dstA) \
86 DeclareAndInitExtraAlphaFor ## STRATEGY(extraA) \
87 jint srcScan = pSrcInfo->scanStride; \
88 jint dstScan = pDstInfo->scanStride; \
89 jboolean loadsrc, loaddst; \
90 SRC ## DataType *pSrc = (SRC ## DataType *) (srcBase); \
91 DST ## DataType *pDst = (DST ## DataType *) (dstBase); \
92 Declare ## SRC ## AlphaLoadData(SrcPix) \
93 Declare ## DST ## AlphaLoadData(DstPix) \
94 Declare ## DST ## StoreVars(DstWrite) \
95 DeclareAlphaOperands(SrcOp) \
96 DeclareAlphaOperands(DstOp) \
97 \
98 ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].srcOps, \
99 SrcOp); \
100 ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].dstOps, \
101 DstOp); \
102 loadsrc = !FuncIsZero(SrcOp) || FuncNeedsAlpha(DstOp); \
103 loaddst = pMask || !FuncIsZero(DstOp) || FuncNeedsAlpha(SrcOp); \
104 \
105 Init ## SRC ## AlphaLoadData(SrcPix, pSrcInfo); \
106 Init ## DST ## AlphaLoadData(DstPix, pDstInfo); \
107 srcScan -= width * SRC ## PixelStride; \
108 dstScan -= width * DST ## PixelStride; \
109 maskScan -= width; \
110 if (pMask) { \
111 pMask += maskOff; \
112 } \
113 \
114 Init ## DST ## StoreVarsY(DstWrite, pDstInfo); \
115 do { \
116 jint w = width; \
117 Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \
118 do { \
119 DeclareAlphaVarFor ## STRATEGY(resA) \
120 DeclareCompVarsFor ## STRATEGY(res) \
121 DeclareAlphaVarFor ## STRATEGY(srcF) \
122 DeclareAlphaVarFor ## STRATEGY(dstF) \
123 \
124 if (pMask) { \
125 pathA = *pMask++; \
126 if (!pathA) { \
127 pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
128 pDst = PtrAddBytes(pDst, DST ## PixelStride); \
129 Next ## DST ## StoreVarsX(DstWrite); \
130 continue; \
131 } \
132 PromoteByteAlphaFor ## STRATEGY(pathA); \
133 } \
134 if (loadsrc) { \
135 LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, SrcPix, src); \
136 srcA = MultiplyAlphaFor ## STRATEGY(extraA, srcA); \
137 } \
138 if (loaddst) { \
139 LoadAlphaFrom ## DST ## For ## STRATEGY(pDst, DstPix, dst); \
140 } \
141 srcF = ApplyAlphaOperands(SrcOp, dstA); \
142 dstF = ApplyAlphaOperands(DstOp, srcA); \
143 if (pathA != MaxValFor ## STRATEGY) { \
144 srcF = MultiplyAlphaFor ## STRATEGY(pathA, srcF); \
145 dstF = MaxValFor ## STRATEGY - pathA + \
146 MultiplyAlphaFor ## STRATEGY(pathA, dstF); \
147 } \
148 if (srcF) { \
149 resA = MultiplyAlphaFor ## STRATEGY(srcF, srcA); \
150 if (!(SRC ## IsPremultiplied)) { \
151 srcF = resA; \
152 } else { \
153 srcF = MultiplyAlphaFor ## STRATEGY(srcF, extraA); \
154 } \
155 if (srcF) { \
156 /* assert(loadsrc); */ \
157 Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, res); \
158 if (srcF != MaxValFor ## STRATEGY) { \
159 MultiplyAndStore ## STRATEGY ## Comps(res, \
160 srcF, res); \
161 } \
162 } else { \
163 if (dstF == MaxValFor ## STRATEGY) { \
164 pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
165 pDst = PtrAddBytes(pDst, DST ## PixelStride); \
166 Next ## DST ## StoreVarsX(DstWrite); \
167 continue; \
168 } \
169 Set ## STRATEGY ## CompsToZero(res); \
170 } \
171 } else { \
172 if (dstF == MaxValFor ## STRATEGY) { \
173 pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
174 pDst = PtrAddBytes(pDst, DST ## PixelStride); \
175 Next ## DST ## StoreVarsX(DstWrite); \
176 continue; \
177 } \
178 resA = 0; \
179 Set ## STRATEGY ## CompsToZero(res); \
180 } \
181 if (dstF) { \
182 dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \
183 if (!(DST ## IsPremultiplied)) { \
184 dstF = dstA; \
185 } \
186 resA += dstA; \
187 if (dstF) { \
188 DeclareCompVarsFor ## STRATEGY(tmp) \
189 /* assert(loaddst); */ \
190 Postload ## STRATEGY ## From ## DST(pDst, DstPix, tmp); \
191 if (dstF != MaxValFor ## STRATEGY) { \
192 MultiplyAndStore ## STRATEGY ## Comps(tmp, \
193 dstF, tmp); \
194 } \
195 Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \
196 } \
197 } \
198 if (!(DST ## IsPremultiplied) && resA && \
199 resA < MaxValFor ## STRATEGY) \
200 { \
201 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
202 } \
203 Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite, \
204 0, res); \
205 pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
206 pDst = PtrAddBytes(pDst, DST ## PixelStride); \
207 Next ## DST ## StoreVarsX(DstWrite); \
208 } while (--w > 0); \
209 pSrc = PtrAddBytes(pSrc, srcScan); \
210 pDst = PtrAddBytes(pDst, dstScan); \
211 Next ## DST ## StoreVarsY(DstWrite); \
212 if (pMask) { \
213 pMask = PtrAddBytes(pMask, maskScan); \
214 } \
215 } while (--height > 0); \
216}
217
218/* REMIND: This macro is as yet, untested */
219#define DEFINE_SRC_MASKBLIT(SRC, DST, STRATEGY) \
220void NAME_SRC_MASKBLIT(SRC, DST) \
221 (void *dstBase, void *srcBase, \
222 jubyte *pMask, jint maskOff, jint maskScan, \
223 jint width, jint height, \
224 SurfaceDataRasInfo *pDstInfo, \
225 SurfaceDataRasInfo *pSrcInfo, \
226 NativePrimitive *pPrim, \
227 CompositeInfo *pCompInfo) \
228{ \
229 DeclareAndInitExtraAlphaFor ## STRATEGY(extraA) \
230 jint srcScan = pSrcInfo->scanStride; \
231 jint dstScan = pDstInfo->scanStride; \
232 SRC ## DataType *pSrc = (SRC ## DataType *) (srcBase); \
233 DST ## DataType *pDst = (DST ## DataType *) (dstBase); \
234 Declare ## SRC ## AlphaLoadData(SrcPix) \
235 Declare ## DST ## AlphaLoadData(DstPix) \
236 Declare ## DST ## StoreVars(DstWrite) \
237 \
238 Init ## SRC ## AlphaLoadData(SrcPix, pSrcInfo); \
239 Init ## DST ## AlphaLoadData(DstPix, pDstInfo); \
240 srcScan -= width * SRC ## PixelStride; \
241 dstScan -= width * DST ## PixelStride; \
242 \
243 Init ## DST ## StoreVarsY(DstWrite, pDstInfo); \
244 if (pMask) { \
245 maskScan -= width; \
246 pMask += maskOff; \
247 do { \
248 jint w = width; \
249 Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \
250 do { \
251 DeclareAlphaVarFor ## STRATEGY(resA) \
252 DeclareCompVarsFor ## STRATEGY(res) \
253 DeclareAlphaVarFor ## STRATEGY(srcF) \
254 DeclareAlphaVarFor ## STRATEGY(dstF) \
255 DeclareAndInitPathAlphaFor ## STRATEGY(pathA) \
256 \
257 if (pathA) { \
258 LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, \
259 SrcPix, res); \
260 resA = MultiplyAlphaFor ## STRATEGY(extraA, resA); \
261 if (SRC ## IsPremultiplied) { \
262 srcF = extraA; \
263 } else { \
264 srcF = resA; \
265 } \
266 Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, res); \
267 if (pathA < 0xff) { \
268 DeclareAlphaVarFor ## STRATEGY(dstA) \
269 DeclareCompVarsFor ## STRATEGY(dst) \
270 PromoteByteAlphaFor ## STRATEGY(pathA); \
271 srcF = MultiplyAlphaFor ## STRATEGY(pathA, srcF); \
272 dstF = MaxValFor ## STRATEGY - pathA; \
273 LoadAlphaFrom ## DST ## For ## STRATEGY(pDst, \
274 DstPix, \
275 dst); \
276 dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA) \
277 if (!(DST ## IsPremultiplied)) { \
278 dstF = dstA; \
279 } \
280 Postload ## STRATEGY ## From ## DST(pDst, DstPix, \
281 dst); \
282 resA = dstA + \
283 MultiplyAlphaFor ## STRATEGY(pathA, resA); \
284 MultMultAddAndStore ## STRATEGY ## Comps(res, \
285 dstF, dst, \
286 srcF, res); \
287 } else if (srcF < MaxValFor ## STRATEGY) { \
288 MultiplyAndStore ## STRATEGY ## Comps(res, \
289 srcF, src); \
290 } \
291 if (!(DST ## IsPremultiplied) && resA && \
292 resA < MaxValFor ## STRATEGY) \
293 { \
294 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
295 } \
296 Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite,\
297 0, res);\
298 } \
299 pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
300 pDst = PtrAddBytes(pDst, DST ## PixelStride); \
301 Next ## DST ## StoreVarsX(DstWrite); \
302 } while (--w > 0); \
303 pSrc = PtrAddBytes(pSrc, srcScan); \
304 pDst = PtrAddBytes(pDst, dstScan); \
305 Next ## DST ## StoreVarsY(DstWrite); \
306 pMask = PtrAddBytes(pMask, maskScan); \
307 } while (--height > 0); \
308 } else /* pMask == 0 */ { \
309 do { \
310 jint w = width; \
311 Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \
312 do { \
313 DeclareAlphaVarFor ## STRATEGY(resA) \
314 DeclareCompVarsFor ## STRATEGY(res) \
315 DeclareAlphaVarFor ## STRATEGY(srcF) \
316 \
317 LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, SrcPix, res); \
318 resA = MultiplyAlphaFor ## STRATEGY(extraA, resA); \
319 if (SRC ## IsPremultiplied) { \
320 srcF = extraA; \
321 } else { \
322 srcF = resA; \
323 } \
324 Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, res); \
325 if (srcF < MaxValFor ## STRATEGY) { \
326 MultiplyAndStore ## STRATEGY ## Comps(res, srcF, src); \
327 } \
328 if (!(DST ## IsPremultiplied) && resA && \
329 resA < MaxValFor ## STRATEGY) \
330 { \
331 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
332 } \
333 Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite, \
334 0, res); \
335 pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
336 pDst = PtrAddBytes(pDst, DST ## PixelStride); \
337 Next ## DST ## StoreVarsX(DstWrite); \
338 } while (--w > 0); \
339 pSrc = PtrAddBytes(pSrc, srcScan); \
340 pDst = PtrAddBytes(pDst, dstScan); \
341 Next ## DST ## StoreVarsY(DstWrite); \
342 } while (--height > 0); \
343 } \
344}
345
346#define DEFINE_SRCOVER_MASKBLIT(SRC, DST, STRATEGY) \
347void NAME_SRCOVER_MASKBLIT(SRC, DST) \
348 (void *dstBase, void *srcBase, \
349 jubyte *pMask, jint maskOff, jint maskScan, \
350 jint width, jint height, \
351 SurfaceDataRasInfo *pDstInfo, \
352 SurfaceDataRasInfo *pSrcInfo, \
353 NativePrimitive *pPrim, \
354 CompositeInfo *pCompInfo) \
355{ \
356 DeclareAndInitExtraAlphaFor ## STRATEGY(extraA) \
357 jint srcScan = pSrcInfo->scanStride; \
358 jint dstScan = pDstInfo->scanStride; \
359 SRC ## DataType *pSrc = (SRC ## DataType *) (srcBase); \
360 DST ## DataType *pDst = (DST ## DataType *) (dstBase); \
361 Declare ## SRC ## AlphaLoadData(SrcPix) \
362 Declare ## DST ## AlphaLoadData(DstPix) \
363 Declare ## DST ## StoreVars(DstWrite) \
364 \
365 Init ## SRC ## AlphaLoadData(SrcPix, pSrcInfo); \
366 Init ## DST ## AlphaLoadData(DstPix, pDstInfo); \
367 srcScan -= width * SRC ## PixelStride; \
368 dstScan -= width * DST ## PixelStride; \
369 \
370 Init ## DST ## StoreVarsY(DstWrite, pDstInfo); \
371 if (pMask) { \
372 pMask += maskOff; \
373 maskScan -= width; \
374 do { \
375 jint w = width; \
376 Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \
377 do { \
378 DeclareAndInitPathAlphaFor ## STRATEGY(pathA) \
379 \
380 if (pathA) { \
381 DeclareAlphaVarFor ## STRATEGY(resA) \
382 DeclareCompVarsFor ## STRATEGY(res) \
383 DeclareAlphaVarFor ## STRATEGY(srcF) \
384 PromoteByteAlphaFor ## STRATEGY(pathA); \
385 pathA = MultiplyAlphaFor ## STRATEGY(pathA, extraA); \
386 LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, \
387 SrcPix, res); \
388 resA = MultiplyAlphaFor ## STRATEGY(pathA, resA); \
389 if (resA) { \
390 if (SRC ## IsPremultiplied) { \
391 srcF = pathA; \
392 } else { \
393 srcF = resA; \
394 } \
395 Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, \
396 res); \
397 if (resA < MaxValFor ## STRATEGY) { \
398 DeclareAlphaVarFor ## STRATEGY(dstA) \
399 DeclareCompVarsFor ## STRATEGY(dst) \
400 DeclareAndInvertAlphaVarFor ## STRATEGY(dstF, \
401 resA) \
402 LoadAlphaFrom ## DST ## For ## STRATEGY(pDst, \
403 DstPix, \
404 dst); \
405 dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \
406 if (!(DST ## IsPremultiplied)) { \
407 dstF = dstA; \
408 } \
409 Postload ## STRATEGY ## From ## DST(pDst, DstPix,\
410 dst); \
411 resA += dstA; \
412 MultMultAddAndStore ## STRATEGY ## Comps(res, \
413 dstF, dst, \
414 srcF, res);\
415 } else if (srcF < MaxValFor ## STRATEGY) { \
416 MultiplyAndStore ## STRATEGY ## Comps(res, \
417 srcF, res);\
418 } \
419 if (!(DST ## IsOpaque) && \
420 !(DST ## IsPremultiplied) && resA && \
421 resA < MaxValFor ## STRATEGY) \
422 { \
423 DivideAndStore ## STRATEGY ## Comps(res, \
424 res, resA); \
425 } \
426 Store ## DST ## From ## STRATEGY ## Comps(pDst, \
427 DstWrite, \
428 0, res); \
429 } \
430 } \
431 pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
432 pDst = PtrAddBytes(pDst, DST ## PixelStride); \
433 Next ## DST ## StoreVarsX(DstWrite); \
434 } while (--w > 0); \
435 pSrc = PtrAddBytes(pSrc, srcScan); \
436 pDst = PtrAddBytes(pDst, dstScan); \
437 Next ## DST ## StoreVarsY(DstWrite); \
438 pMask = PtrAddBytes(pMask, maskScan); \
439 } while (--height > 0); \
440 } else /* pMask == 0 */ { \
441 do { \
442 jint w = width; \
443 Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \
444 do { \
445 DeclareAlphaVarFor ## STRATEGY(resA) \
446 DeclareCompVarsFor ## STRATEGY(res) \
447 DeclareAlphaVarFor ## STRATEGY(srcF) \
448 \
449 LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, SrcPix, res); \
450 resA = MultiplyAlphaFor ## STRATEGY(extraA, resA); \
451 if (resA) { \
452 if (SRC ## IsPremultiplied) { \
453 srcF = extraA; \
454 } else { \
455 srcF = resA; \
456 } \
457 Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, res); \
458 if (resA < MaxValFor ## STRATEGY) { \
459 DeclareAlphaVarFor ## STRATEGY(dstA) \
460 DeclareCompVarsFor ## STRATEGY(dst) \
461 DeclareAndInvertAlphaVarFor ## STRATEGY(dstF, resA) \
462 LoadAlphaFrom ## DST ## For ## STRATEGY(pDst, \
463 DstPix, \
464 dst); \
465 dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \
466 if (!(DST ## IsPremultiplied)) { \
467 dstF = dstA; \
468 } \
469 Postload ## STRATEGY ## From ## DST(pDst, DstPix, \
470 dst); \
471 resA += dstA; \
472 MultMultAddAndStore ## STRATEGY ## Comps(res, \
473 dstF, dst, \
474 srcF, res); \
475 } else if (srcF < MaxValFor ## STRATEGY) { \
476 MultiplyAndStore ## STRATEGY ## Comps(res, \
477 srcF, res); \
478 } \
479 if (!(DST ## IsOpaque) && \
480 !(DST ## IsPremultiplied) && resA && \
481 resA < MaxValFor ## STRATEGY) \
482 { \
483 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
484 } \
485 Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite,\
486 0, res); \
487 } \
488 pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \
489 pDst = PtrAddBytes(pDst, DST ## PixelStride); \
490 Next ## DST ## StoreVarsX(DstWrite); \
491 } while (--w > 0); \
492 pSrc = PtrAddBytes(pSrc, srcScan); \
493 pDst = PtrAddBytes(pDst, dstScan); \
494 Next ## DST ## StoreVarsY(DstWrite); \
495 } while (--height > 0); \
496 } \
497}
498
499#define DEFINE_ALPHA_MASKFILL(TYPE, STRATEGY) \
500void NAME_ALPHA_MASKFILL(TYPE) \
501 (void *rasBase, \
502 jubyte *pMask, jint maskOff, jint maskScan, \
503 jint width, jint height, \
504 jint fgColor, \
505 SurfaceDataRasInfo *pRasInfo, \
506 NativePrimitive *pPrim, \
507 CompositeInfo *pCompInfo) \
508{ \
509 DeclareAndSetOpaqueAlphaVarFor ## STRATEGY(pathA) \
510 DeclareAlphaVarFor ## STRATEGY(srcA) \
511 DeclareCompVarsFor ## STRATEGY(src) \
512 DeclareAndClearAlphaVarFor ## STRATEGY(dstA) \
513 DeclareAlphaVarFor ## STRATEGY(dstF) \
514 DeclareAlphaVarFor ## STRATEGY(dstFbase) \
515 jint rasScan = pRasInfo->scanStride; \
516 jboolean loaddst; \
517 TYPE ## DataType *pRas = (TYPE ## DataType *) (rasBase); \
518 Declare ## TYPE ## AlphaLoadData(DstPix) \
519 Declare ## TYPE ## StoreVars(DstWrite) \
520 DeclareAlphaOperands(SrcOp) \
521 DeclareAlphaOperands(DstOp) \
522 \
523 Extract ## STRATEGY ## CompsAndAlphaFromArgb(fgColor, src); \
524 if (srcA != MaxValFor ## STRATEGY) { \
525 MultiplyAndStore ## STRATEGY ## Comps(src, srcA, src); \
526 } \
527 \
528 ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].srcOps, \
529 SrcOp); \
530 ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].dstOps, \
531 DstOp); \
532 loaddst = pMask || !FuncIsZero(DstOp) || FuncNeedsAlpha(SrcOp); \
533 \
534 dstFbase = dstF = ApplyAlphaOperands(DstOp, srcA); \
535 \
536 Init ## TYPE ## AlphaLoadData(DstPix, pRasInfo); \
537 rasScan -= width * TYPE ## PixelStride; \
538 maskScan -= width; \
539 if (pMask) { \
540 pMask += maskOff; \
541 } \
542 \
543 Init ## TYPE ## StoreVarsY(DstWrite, pRasInfo); \
544 do { \
545 jint w = width; \
546 Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \
547 do { \
548 DeclareAlphaVarFor ## STRATEGY(resA) \
549 DeclareCompVarsFor ## STRATEGY(res) \
550 DeclareAlphaVarFor ## STRATEGY(srcF) \
551 \
552 if (pMask) { \
553 pathA = *pMask++; \
554 if (!pathA) { \
555 pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \
556 Next ## TYPE ## StoreVarsX(DstWrite); \
557 continue; \
558 } \
559 PromoteByteAlphaFor ## STRATEGY(pathA); \
560 dstF = dstFbase; \
561 } \
562 if (loaddst) { \
563 LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas, DstPix, dst);\
564 } \
565 srcF = ApplyAlphaOperands(SrcOp, dstA); \
566 if (pathA != MaxValFor ## STRATEGY) { \
567 srcF = MultiplyAlphaFor ## STRATEGY(pathA, srcF); \
568 dstF = MaxValFor ## STRATEGY - pathA + \
569 MultiplyAlphaFor ## STRATEGY(pathA, dstF); \
570 } \
571 if (srcF) { \
572 if (srcF == MaxValFor ## STRATEGY) { \
573 resA = srcA; \
574 Store ## STRATEGY ## CompsUsingOp(res, =, src); \
575 } else { \
576 resA = MultiplyAlphaFor ## STRATEGY(srcF, srcA); \
577 MultiplyAndStore ## STRATEGY ## Comps(res, srcF, src); \
578 } \
579 } else { \
580 if (dstF == MaxValFor ## STRATEGY) { \
581 pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \
582 Next ## TYPE ## StoreVarsX(DstWrite); \
583 continue; \
584 } \
585 resA = 0; \
586 Set ## STRATEGY ## CompsToZero(res); \
587 } \
588 if (dstF) { \
589 dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \
590 resA += dstA; \
591 if (TYPE ## IsPremultiplied) { \
592 dstA = dstF; \
593 } \
594 if (dstA) { \
595 DeclareCompVarsFor ## STRATEGY(tmp) \
596 /* assert(loaddst); */ \
597 Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, tmp); \
598 if (dstA != MaxValFor ## STRATEGY) { \
599 MultiplyAndStore ## STRATEGY ## Comps(tmp, \
600 dstA, tmp); \
601 } \
602 Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \
603 } \
604 } \
605 if (!(TYPE ## IsPremultiplied) && resA && \
606 resA < MaxValFor ## STRATEGY) \
607 { \
608 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
609 } \
610 Store ## TYPE ## From ## STRATEGY ## Comps(pRas, DstWrite, \
611 0, res); \
612 pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \
613 Next ## TYPE ## StoreVarsX(DstWrite); \
614 } while (--w > 0); \
615 pRas = PtrAddBytes(pRas, rasScan); \
616 Next ## TYPE ## StoreVarsY(DstWrite); \
617 if (pMask) { \
618 pMask = PtrAddBytes(pMask, maskScan); \
619 } \
620 } while (--height > 0); \
621}
622
623#define DEFINE_SRC_MASKFILL(TYPE, STRATEGY) \
624void NAME_SRC_MASKFILL(TYPE) \
625 (void *rasBase, \
626 jubyte *pMask, jint maskOff, jint maskScan, \
627 jint width, jint height, \
628 jint fgColor, \
629 SurfaceDataRasInfo *pRasInfo, \
630 NativePrimitive *pPrim, \
631 CompositeInfo *pCompInfo) \
632{ \
633 DeclareAlphaVarFor ## STRATEGY(srcA) \
634 DeclareCompVarsFor ## STRATEGY(src) \
635 jint rasScan = pRasInfo->scanStride; \
636 TYPE ## DataType *pRas = (TYPE ## DataType *) (rasBase); \
637 Declare ## TYPE ## AlphaLoadData(DstPix) \
638 Declare ## TYPE ## StoreVars(DstWrite) \
639 Declare ## TYPE ## BlendFillVars(DstFill) \
640 \
641 Extract ## STRATEGY ## CompsAndAlphaFromArgb(fgColor, src); \
642 if (srcA == 0) { \
643 Set ## STRATEGY ## CompsToZero(src); \
644 Clear ## TYPE ## BlendFillVars(DstFill, fgColor); \
645 } else { \
646 if (!(TYPE ## IsPremultiplied)) { \
647 Init ## TYPE ## BlendFillVarsNonPre(DstFill, fgColor, src); \
648 } \
649 if (srcA != MaxValFor ## STRATEGY) { \
650 MultiplyAndStore ## STRATEGY ## Comps(src, srcA, src); \
651 } \
652 if (TYPE ## IsPremultiplied) { \
653 Init ## TYPE ## BlendFillVarsPre(DstFill, fgColor, src); \
654 } \
655 } \
656 \
657 Init ## TYPE ## AlphaLoadData(DstPix, pRasInfo); \
658 Init ## TYPE ## StoreVarsY(DstWrite, pRasInfo); \
659 \
660 rasScan -= width * TYPE ## PixelStride; \
661 if (pMask) { \
662 pMask += maskOff; \
663 maskScan -= width; \
664 do { \
665 jint w = width; \
666 Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \
667 do { \
668 DeclareAlphaVarFor ## STRATEGY(resA) \
669 DeclareCompVarsFor ## STRATEGY(res) \
670 DeclareAlphaVarFor ## STRATEGY(dstF) \
671 DeclareAndInitPathAlphaFor ## STRATEGY(pathA) \
672 \
673 if (pathA > 0) { \
674 if (pathA == 0xff) { \
675 /* pathA ignored here, not promoted */ \
676 Store ## TYPE ## BlendFill(pRas, DstFill, 0, \
677 fgColor, src); \
678 } else { \
679 PromoteByteAlphaFor ## STRATEGY(pathA); \
680 dstF = MaxValFor ## STRATEGY - pathA; \
681 LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas, \
682 DstPix, \
683 res); \
684 resA = MultiplyAlphaFor ## STRATEGY(dstF, resA); \
685 if (!(TYPE ## IsPremultiplied)) { \
686 dstF = resA; \
687 } \
688 resA += MultiplyAlphaFor ## STRATEGY(pathA, srcA); \
689 Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, \
690 res); \
691 MultMultAddAndStore ## STRATEGY ## Comps(res, \
692 dstF, res, \
693 pathA, src);\
694 if (!(TYPE ## IsPremultiplied) && resA && \
695 resA < MaxValFor ## STRATEGY) \
696 { \
697 DivideAndStore ## STRATEGY ## Comps(res, \
698 res, resA); \
699 } \
700 Store ## TYPE ## From ## STRATEGY ## Comps(pRas, \
701 DstWrite, \
702 0, res); \
703 } \
704 } \
705 pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \
706 Next ## TYPE ## StoreVarsX(DstWrite); \
707 } while (--w > 0); \
708 pRas = PtrAddBytes(pRas, rasScan); \
709 Next ## TYPE ## StoreVarsY(DstWrite); \
710 pMask = PtrAddBytes(pMask, maskScan); \
711 } while (--height > 0); \
712 } else /* pMask == 0 */ { \
713 do { \
714 jint w = width; \
715 Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \
716 do { \
717 Store ## TYPE ## BlendFill(pRas, DstFill, 0, fgColor, src); \
718 pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \
719 Next ## TYPE ## StoreVarsX(DstWrite); \
720 } while (--w > 0); \
721 pRas = PtrAddBytes(pRas, rasScan); \
722 Next ## TYPE ## StoreVarsY(DstWrite); \
723 } while (--height > 0); \
724 } \
725}
726
727#define DEFINE_SRCOVER_MASKFILL(TYPE, STRATEGY) \
728void NAME_SRCOVER_MASKFILL(TYPE) \
729 (void *rasBase, \
730 jubyte *pMask, jint maskOff, jint maskScan, \
731 jint width, jint height, \
732 jint fgColor, \
733 SurfaceDataRasInfo *pRasInfo, \
734 NativePrimitive *pPrim, \
735 CompositeInfo *pCompInfo) \
736{ \
737 DeclareAlphaVarFor ## STRATEGY(srcA) \
738 DeclareCompVarsFor ## STRATEGY(src) \
739 jint rasScan = pRasInfo->scanStride; \
740 TYPE ## DataType *pRas = (TYPE ## DataType *) (rasBase); \
741 Declare ## TYPE ## AlphaLoadData(DstPix) \
742 Declare ## TYPE ## StoreVars(DstWrite) \
743 \
744 Extract ## STRATEGY ## CompsAndAlphaFromArgb(fgColor, src); \
745 if (srcA != MaxValFor ## STRATEGY) { \
746 if (srcA == 0) { \
747 return; \
748 } \
749 MultiplyAndStore ## STRATEGY ## Comps(src, srcA, src); \
750 } \
751 \
752 Init ## TYPE ## AlphaLoadData(DstPix, pRasInfo); \
753 Init ## TYPE ## StoreVarsY(DstWrite, pRasInfo); \
754 \
755 rasScan -= width * TYPE ## PixelStride; \
756 if (pMask) { \
757 pMask += maskOff; \
758 maskScan -= width; \
759 do { \
760 jint w = width; \
761 Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \
762 do { \
763 DeclareAlphaVarFor ## STRATEGY(resA) \
764 DeclareCompVarsFor ## STRATEGY(res) \
765 DeclareAndInitPathAlphaFor ## STRATEGY(pathA) \
766 \
767 if (pathA > 0) { \
768 if (pathA != 0xff) { \
769 PromoteByteAlphaFor ## STRATEGY(pathA); \
770 resA = MultiplyAlphaFor ## STRATEGY(pathA, srcA); \
771 MultiplyAndStore ## STRATEGY ## Comps(res, \
772 pathA, src); \
773 } else { \
774 /* pathA ignored here, not promoted */ \
775 resA = srcA; \
776 Store ## STRATEGY ## CompsUsingOp(res, =, src); \
777 } \
778 if (resA != MaxValFor ## STRATEGY) { \
779 DeclareAndInvertAlphaVarFor ## STRATEGY(dstF, resA) \
780 DeclareAndClearAlphaVarFor ## STRATEGY(dstA) \
781 LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas, \
782 DstPix, \
783 dst); \
784 dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \
785 if (!(TYPE ## IsPremultiplied)) { \
786 dstF = dstA; \
787 } \
788 resA += dstA; \
789 if (dstF) { \
790 DeclareCompVarsFor ## STRATEGY(tmp) \
791 Postload ## STRATEGY ## From ## TYPE(pRas, \
792 DstPix, \
793 tmp); \
794 if (dstF != MaxValFor ## STRATEGY) { \
795 MultiplyAndStore ## STRATEGY ## Comps(tmp, \
796 dstF, \
797 tmp); \
798 } \
799 Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \
800 } \
801 } \
802 if (!(TYPE ## IsOpaque) && \
803 !(TYPE ## IsPremultiplied) && resA && \
804 resA < MaxValFor ## STRATEGY) \
805 { \
806 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
807 } \
808 Store ## TYPE ## From ## STRATEGY ## Comps(pRas, \
809 DstWrite, 0, \
810 res); \
811 } \
812 pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \
813 Next ## TYPE ## StoreVarsX(DstWrite); \
814 } while (--w > 0); \
815 pRas = PtrAddBytes(pRas, rasScan); \
816 Next ## TYPE ## StoreVarsY(DstWrite); \
817 pMask = PtrAddBytes(pMask, maskScan); \
818 } while (--height > 0); \
819 } else /* pMask == 0 */ { \
820 do { \
821 jint w = width; \
822 Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \
823 do { \
824 DeclareAlphaVarFor ## STRATEGY(resA) \
825 DeclareCompVarsFor ## STRATEGY(res) \
826 DeclareAndInvertAlphaVarFor ## STRATEGY(dstF, srcA) \
827\
828 LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas, DstPix, res);\
829 resA = MultiplyAlphaFor ## STRATEGY(dstF, resA); \
830 if (!(TYPE ## IsPremultiplied)) { \
831 dstF = resA; \
832 } \
833 resA += srcA; \
834 Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, res); \
835 MultiplyAddAndStore ## STRATEGY ## Comps(res, \
836 dstF, res, src); \
837 if (!(TYPE ## IsOpaque) && \
838 !(TYPE ## IsPremultiplied) && resA && \
839 resA < MaxValFor ## STRATEGY) \
840 { \
841 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
842 } \
843 Store ## TYPE ## From ## STRATEGY ## Comps(pRas, DstWrite, \
844 0, res); \
845 pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \
846 Next ## TYPE ## StoreVarsX(DstWrite); \
847 } while (--w > 0); \
848 pRas = PtrAddBytes(pRas, rasScan); \
849 Next ## TYPE ## StoreVarsY(DstWrite); \
850 } while (--height > 0); \
851 } \
852}
853
854
855/*
856 * The macros defined above use the following macro definitions supplied
857 * for the various surface types to manipulate pixels and pixel data.
858 * The surface-specific macros are typically supplied by header files
859 * named after the SurfaceType name (eg. IntArgb.h, ByteGray.h, etc.).
860 *
861 * In the macro names in the following definitions, the string <stype>
862 * is used as a place holder for the SurfaceType name (eg. IntArgb). The
863 * string <strategy> is a place holder for the strategy name (eg. 4ByteArgb).
864 * The macros above access these type specific macros using the ANSI
865 * CPP token concatenation operator "##".
866 *
867 * Declare<stype>AlphaLoadData Declare the variables used when an alpha
868 * value is pre-fetched to see whether or
869 * not blending needs to occur
870 * Init<stype>AlphaLoadData Initialize the aforementioned variables
871 * LoadAlphaFrom<stype>For<strategy> Load the alpha value for the given pixel
872 * into a variable used later (the strategy
873 * type determines the bit depth of the
874 * alpha value)
875 * Postload<strategy>From<stype> Load the pixel components from the given
876 * surface type into the form required by
877 * the given strategy. Typically there will
878 * be a couple macros of this variety, one
879 * for 4ByteArgb, one for 1ByteGray, one
880 * for 1ShortGray, etc. Its code is only
881 * executed when blending needs to occur.
882 *
883 * <stype>IsPremultiplied Constant specifying whether the pixel
884 * components have been premultiplied with
885 * the alpha value
886 * Declare<stype>BlendFillVars Declare the variables used when alpha
887 * blending need not occur (mask and source
888 * pixel are opaque)
889 * Clear<stype>BlendFillVars Clear the variables used in a no-blend
890 * situation (may modify argb argument)
891 * Init<stype>BlendFillVarsNonPre Initialize the variables used for a
892 * no-blending situation (this macro is for
893 * surfaces that do not have premultiplied
894 * components) (may modify argb argument)
895 * Init<stype>BlendFillVarsPre Initialize the variables used for a
896 * no-blending situation (this macro is for
897 * surfaces that have premultiplied
898 * components) (may modify argb argument)
899 * Store<stype>BlendFill Simply store the pixel for the given
900 * surface (used when blending is
901 * unnecessary)
902 * Store<stype>From<strategy>Comps Store the pixel for the given surface
903 * type after converting it from a pixel of
904 * the given strategy
905 */
906
907#endif /* AlphaMacros_h_Included */
908