| /* | |
| * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. Oracle designates this | |
| * particular file as subject to the "Classpath" exception as provided | |
| * by Oracle in the LICENSE file that accompanied this code. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| #ifndef AlphaMacros_h_Included | |
| #define AlphaMacros_h_Included | |
| #include "GraphicsPrimitiveMgr.h" | |
| #include "AlphaMath.h" | |
| #include "IntArgb.h" /* for "Extract...FromArgb" macros */ | |
| #define DeclareAlphaOperands(PREFIX) \ | |
| jint PREFIX ## And, PREFIX ## Xor, PREFIX ## Add; | |
| #define ExtractAlphaOperandsFor4ByteArgb(f, PREFIX) \ | |
| do { \ | |
| PREFIX ## And = (f).andval; \ | |
| PREFIX ## Xor = (f).xorval; \ | |
| PREFIX ## Add = (jint) (f).addval - PREFIX ## Xor; \ | |
| } while (0) | |
| #define ExtractAlphaOperandsFor1ByteGray(f, PREFIX) \ | |
| ExtractAlphaOperandsFor4ByteArgb(f, PREFIX) | |
| #define ExtractAlphaOperandsFor1ShortGray(f, PREFIX) \ | |
| do { \ | |
| PREFIX ## And = ((f).andval << 8) + (f).andval; \ | |
| PREFIX ## Xor = (f).xorval; \ | |
| PREFIX ## Add = (jint) (((f).addval << 8) + (f).addval) - \ | |
| PREFIX ## Xor; \ | |
| } while (0) | |
| #define ApplyAlphaOperands(PREFIX, a) \ | |
| ((((a) & PREFIX ## And) ^ PREFIX ## Xor) + PREFIX ## Add) | |
| #define FuncNeedsAlpha(PREFIX) (PREFIX ## And != 0) | |
| #define FuncIsZero(PREFIX) ((PREFIX ## And | PREFIX ## Add) == 0) | |
| typedef struct { | |
| jubyte addval; | |
| jubyte andval; | |
| jshort xorval; | |
| } AlphaOperands; | |
| typedef struct { | |
| AlphaOperands srcOps; | |
| AlphaOperands dstOps; | |
| } AlphaFunc; | |
| extern AlphaFunc AlphaRules[]; | |
| #define DEFINE_ALPHA_MASKBLIT(SRC, DST, STRATEGY) \ | |
| void NAME_ALPHA_MASKBLIT(SRC, DST) \ | |
| (void *dstBase, void *srcBase, \ | |
| jubyte *pMask, jint maskOff, jint maskScan, \ | |
| jint width, jint height, \ | |
| SurfaceDataRasInfo *pDstInfo, \ | |
| SurfaceDataRasInfo *pSrcInfo, \ | |
| NativePrimitive *pPrim, \ | |
| CompositeInfo *pCompInfo) \ | |
| { \ | |
| DeclareAndSetOpaqueAlphaVarFor ## STRATEGY(pathA) \ | |
| DeclareAndClearAlphaVarFor ## STRATEGY(srcA) \ | |
| DeclareAndClearAlphaVarFor ## STRATEGY(dstA) \ | |
| DeclareAndInitExtraAlphaFor ## STRATEGY(extraA) \ | |
| jint srcScan = pSrcInfo->scanStride; \ | |
| jint dstScan = pDstInfo->scanStride; \ | |
| jboolean loadsrc, loaddst; \ | |
| SRC ## DataType *pSrc = (SRC ## DataType *) (srcBase); \ | |
| DST ## DataType *pDst = (DST ## DataType *) (dstBase); \ | |
| Declare ## SRC ## AlphaLoadData(SrcPix) \ | |
| Declare ## DST ## AlphaLoadData(DstPix) \ | |
| Declare ## DST ## StoreVars(DstWrite) \ | |
| DeclareAlphaOperands(SrcOp) \ | |
| DeclareAlphaOperands(DstOp) \ | |
| \ | |
| ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].srcOps, \ | |
| SrcOp); \ | |
| ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].dstOps, \ | |
| DstOp); \ | |
| loadsrc = !FuncIsZero(SrcOp) || FuncNeedsAlpha(DstOp); \ | |
| loaddst = pMask || !FuncIsZero(DstOp) || FuncNeedsAlpha(SrcOp); \ | |
| \ | |
| Init ## SRC ## AlphaLoadData(SrcPix, pSrcInfo); \ | |
| Init ## DST ## AlphaLoadData(DstPix, pDstInfo); \ | |
| srcScan -= width * SRC ## PixelStride; \ | |
| dstScan -= width * DST ## PixelStride; \ | |
| maskScan -= width; \ | |
| if (pMask) { \ | |
| pMask += maskOff; \ | |
| } \ | |
| \ | |
| Init ## DST ## StoreVarsY(DstWrite, pDstInfo); \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \ | |
| do { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAlphaVarFor ## STRATEGY(srcF) \ | |
| DeclareAlphaVarFor ## STRATEGY(dstF) \ | |
| \ | |
| if (pMask) { \ | |
| pathA = *pMask++; \ | |
| if (!pathA) { \ | |
| pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \ | |
| pDst = PtrAddBytes(pDst, DST ## PixelStride); \ | |
| Next ## DST ## StoreVarsX(DstWrite); \ | |
| continue; \ | |
| } \ | |
| PromoteByteAlphaFor ## STRATEGY(pathA); \ | |
| } \ | |
| if (loadsrc) { \ | |
| LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, SrcPix, src); \ | |
| srcA = MultiplyAlphaFor ## STRATEGY(extraA, srcA); \ | |
| } \ | |
| if (loaddst) { \ | |
| LoadAlphaFrom ## DST ## For ## STRATEGY(pDst, DstPix, dst); \ | |
| } \ | |
| srcF = ApplyAlphaOperands(SrcOp, dstA); \ | |
| dstF = ApplyAlphaOperands(DstOp, srcA); \ | |
| if (pathA != MaxValFor ## STRATEGY) { \ | |
| srcF = MultiplyAlphaFor ## STRATEGY(pathA, srcF); \ | |
| dstF = MaxValFor ## STRATEGY - pathA + \ | |
| MultiplyAlphaFor ## STRATEGY(pathA, dstF); \ | |
| } \ | |
| if (srcF) { \ | |
| resA = MultiplyAlphaFor ## STRATEGY(srcF, srcA); \ | |
| if (!(SRC ## IsPremultiplied)) { \ | |
| srcF = resA; \ | |
| } else { \ | |
| srcF = MultiplyAlphaFor ## STRATEGY(srcF, extraA); \ | |
| } \ | |
| if (srcF) { \ | |
| /* assert(loadsrc); */ \ | |
| Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, res); \ | |
| if (srcF != MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(res, \ | |
| srcF, res); \ | |
| } \ | |
| } else { \ | |
| if (dstF == MaxValFor ## STRATEGY) { \ | |
| pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \ | |
| pDst = PtrAddBytes(pDst, DST ## PixelStride); \ | |
| Next ## DST ## StoreVarsX(DstWrite); \ | |
| continue; \ | |
| } \ | |
| Set ## STRATEGY ## CompsToZero(res); \ | |
| } \ | |
| } else { \ | |
| if (dstF == MaxValFor ## STRATEGY) { \ | |
| pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \ | |
| pDst = PtrAddBytes(pDst, DST ## PixelStride); \ | |
| Next ## DST ## StoreVarsX(DstWrite); \ | |
| continue; \ | |
| } \ | |
| resA = 0; \ | |
| Set ## STRATEGY ## CompsToZero(res); \ | |
| } \ | |
| if (dstF) { \ | |
| dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \ | |
| if (!(DST ## IsPremultiplied)) { \ | |
| dstF = dstA; \ | |
| } \ | |
| resA += dstA; \ | |
| if (dstF) { \ | |
| DeclareCompVarsFor ## STRATEGY(tmp) \ | |
| /* assert(loaddst); */ \ | |
| Postload ## STRATEGY ## From ## DST(pDst, DstPix, tmp); \ | |
| if (dstF != MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(tmp, \ | |
| dstF, tmp); \ | |
| } \ | |
| Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \ | |
| } \ | |
| } \ | |
| if (!(DST ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ | |
| } \ | |
| Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite, \ | |
| 0, res); \ | |
| pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \ | |
| pDst = PtrAddBytes(pDst, DST ## PixelStride); \ | |
| Next ## DST ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pSrc = PtrAddBytes(pSrc, srcScan); \ | |
| pDst = PtrAddBytes(pDst, dstScan); \ | |
| Next ## DST ## StoreVarsY(DstWrite); \ | |
| if (pMask) { \ | |
| pMask = PtrAddBytes(pMask, maskScan); \ | |
| } \ | |
| } while (--height > 0); \ | |
| } | |
| /* REMIND: This macro is as yet, untested */ | |
| #define DEFINE_SRC_MASKBLIT(SRC, DST, STRATEGY) \ | |
| void NAME_SRC_MASKBLIT(SRC, DST) \ | |
| (void *dstBase, void *srcBase, \ | |
| jubyte *pMask, jint maskOff, jint maskScan, \ | |
| jint width, jint height, \ | |
| SurfaceDataRasInfo *pDstInfo, \ | |
| SurfaceDataRasInfo *pSrcInfo, \ | |
| NativePrimitive *pPrim, \ | |
| CompositeInfo *pCompInfo) \ | |
| { \ | |
| DeclareAndInitExtraAlphaFor ## STRATEGY(extraA) \ | |
| jint srcScan = pSrcInfo->scanStride; \ | |
| jint dstScan = pDstInfo->scanStride; \ | |
| SRC ## DataType *pSrc = (SRC ## DataType *) (srcBase); \ | |
| DST ## DataType *pDst = (DST ## DataType *) (dstBase); \ | |
| Declare ## SRC ## AlphaLoadData(SrcPix) \ | |
| Declare ## DST ## AlphaLoadData(DstPix) \ | |
| Declare ## DST ## StoreVars(DstWrite) \ | |
| \ | |
| Init ## SRC ## AlphaLoadData(SrcPix, pSrcInfo); \ | |
| Init ## DST ## AlphaLoadData(DstPix, pDstInfo); \ | |
| srcScan -= width * SRC ## PixelStride; \ | |
| dstScan -= width * DST ## PixelStride; \ | |
| \ | |
| Init ## DST ## StoreVarsY(DstWrite, pDstInfo); \ | |
| if (pMask) { \ | |
| maskScan -= width; \ | |
| pMask += maskOff; \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \ | |
| do { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAlphaVarFor ## STRATEGY(srcF) \ | |
| DeclareAlphaVarFor ## STRATEGY(dstF) \ | |
| DeclareAndInitPathAlphaFor ## STRATEGY(pathA) \ | |
| \ | |
| if (pathA) { \ | |
| LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, \ | |
| SrcPix, res); \ | |
| resA = MultiplyAlphaFor ## STRATEGY(extraA, resA); \ | |
| if (SRC ## IsPremultiplied) { \ | |
| srcF = extraA; \ | |
| } else { \ | |
| srcF = resA; \ | |
| } \ | |
| Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, res); \ | |
| if (pathA < 0xff) { \ | |
| DeclareAlphaVarFor ## STRATEGY(dstA) \ | |
| DeclareCompVarsFor ## STRATEGY(dst) \ | |
| PromoteByteAlphaFor ## STRATEGY(pathA); \ | |
| srcF = MultiplyAlphaFor ## STRATEGY(pathA, srcF); \ | |
| dstF = MaxValFor ## STRATEGY - pathA; \ | |
| LoadAlphaFrom ## DST ## For ## STRATEGY(pDst, \ | |
| DstPix, \ | |
| dst); \ | |
| dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA) \ | |
| if (!(DST ## IsPremultiplied)) { \ | |
| dstF = dstA; \ | |
| } \ | |
| Postload ## STRATEGY ## From ## DST(pDst, DstPix, \ | |
| dst); \ | |
| resA = dstA + \ | |
| MultiplyAlphaFor ## STRATEGY(pathA, resA); \ | |
| MultMultAddAndStore ## STRATEGY ## Comps(res, \ | |
| dstF, dst, \ | |
| srcF, res); \ | |
| } else if (srcF < MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(res, \ | |
| srcF, src); \ | |
| } \ | |
| if (!(DST ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ | |
| } \ | |
| Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite,\ | |
| 0, res);\ | |
| } \ | |
| pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \ | |
| pDst = PtrAddBytes(pDst, DST ## PixelStride); \ | |
| Next ## DST ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pSrc = PtrAddBytes(pSrc, srcScan); \ | |
| pDst = PtrAddBytes(pDst, dstScan); \ | |
| Next ## DST ## StoreVarsY(DstWrite); \ | |
| pMask = PtrAddBytes(pMask, maskScan); \ | |
| } while (--height > 0); \ | |
| } else /* pMask == 0 */ { \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \ | |
| do { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAlphaVarFor ## STRATEGY(srcF) \ | |
| \ | |
| LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, SrcPix, res); \ | |
| resA = MultiplyAlphaFor ## STRATEGY(extraA, resA); \ | |
| if (SRC ## IsPremultiplied) { \ | |
| srcF = extraA; \ | |
| } else { \ | |
| srcF = resA; \ | |
| } \ | |
| Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, res); \ | |
| if (srcF < MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(res, srcF, src); \ | |
| } \ | |
| if (!(DST ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ | |
| } \ | |
| Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite, \ | |
| 0, res); \ | |
| pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \ | |
| pDst = PtrAddBytes(pDst, DST ## PixelStride); \ | |
| Next ## DST ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pSrc = PtrAddBytes(pSrc, srcScan); \ | |
| pDst = PtrAddBytes(pDst, dstScan); \ | |
| Next ## DST ## StoreVarsY(DstWrite); \ | |
| } while (--height > 0); \ | |
| } \ | |
| } | |
| #define DEFINE_SRCOVER_MASKBLIT(SRC, DST, STRATEGY) \ | |
| void NAME_SRCOVER_MASKBLIT(SRC, DST) \ | |
| (void *dstBase, void *srcBase, \ | |
| jubyte *pMask, jint maskOff, jint maskScan, \ | |
| jint width, jint height, \ | |
| SurfaceDataRasInfo *pDstInfo, \ | |
| SurfaceDataRasInfo *pSrcInfo, \ | |
| NativePrimitive *pPrim, \ | |
| CompositeInfo *pCompInfo) \ | |
| { \ | |
| DeclareAndInitExtraAlphaFor ## STRATEGY(extraA) \ | |
| jint srcScan = pSrcInfo->scanStride; \ | |
| jint dstScan = pDstInfo->scanStride; \ | |
| SRC ## DataType *pSrc = (SRC ## DataType *) (srcBase); \ | |
| DST ## DataType *pDst = (DST ## DataType *) (dstBase); \ | |
| Declare ## SRC ## AlphaLoadData(SrcPix) \ | |
| Declare ## DST ## AlphaLoadData(DstPix) \ | |
| Declare ## DST ## StoreVars(DstWrite) \ | |
| \ | |
| Init ## SRC ## AlphaLoadData(SrcPix, pSrcInfo); \ | |
| Init ## DST ## AlphaLoadData(DstPix, pDstInfo); \ | |
| srcScan -= width * SRC ## PixelStride; \ | |
| dstScan -= width * DST ## PixelStride; \ | |
| \ | |
| Init ## DST ## StoreVarsY(DstWrite, pDstInfo); \ | |
| if (pMask) { \ | |
| pMask += maskOff; \ | |
| maskScan -= width; \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \ | |
| do { \ | |
| DeclareAndInitPathAlphaFor ## STRATEGY(pathA) \ | |
| \ | |
| if (pathA) { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAlphaVarFor ## STRATEGY(srcF) \ | |
| PromoteByteAlphaFor ## STRATEGY(pathA); \ | |
| pathA = MultiplyAlphaFor ## STRATEGY(pathA, extraA); \ | |
| LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, \ | |
| SrcPix, res); \ | |
| resA = MultiplyAlphaFor ## STRATEGY(pathA, resA); \ | |
| if (resA) { \ | |
| if (SRC ## IsPremultiplied) { \ | |
| srcF = pathA; \ | |
| } else { \ | |
| srcF = resA; \ | |
| } \ | |
| Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, \ | |
| res); \ | |
| if (resA < MaxValFor ## STRATEGY) { \ | |
| DeclareAlphaVarFor ## STRATEGY(dstA) \ | |
| DeclareCompVarsFor ## STRATEGY(dst) \ | |
| DeclareAndInvertAlphaVarFor ## STRATEGY(dstF, \ | |
| resA) \ | |
| LoadAlphaFrom ## DST ## For ## STRATEGY(pDst, \ | |
| DstPix, \ | |
| dst); \ | |
| dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \ | |
| if (!(DST ## IsPremultiplied)) { \ | |
| dstF = dstA; \ | |
| } \ | |
| Postload ## STRATEGY ## From ## DST(pDst, DstPix,\ | |
| dst); \ | |
| resA += dstA; \ | |
| MultMultAddAndStore ## STRATEGY ## Comps(res, \ | |
| dstF, dst, \ | |
| srcF, res);\ | |
| } else if (srcF < MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(res, \ | |
| srcF, res);\ | |
| } \ | |
| if (!(DST ## IsOpaque) && \ | |
| !(DST ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, \ | |
| res, resA); \ | |
| } \ | |
| Store ## DST ## From ## STRATEGY ## Comps(pDst, \ | |
| DstWrite, \ | |
| 0, res); \ | |
| } \ | |
| } \ | |
| pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \ | |
| pDst = PtrAddBytes(pDst, DST ## PixelStride); \ | |
| Next ## DST ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pSrc = PtrAddBytes(pSrc, srcScan); \ | |
| pDst = PtrAddBytes(pDst, dstScan); \ | |
| Next ## DST ## StoreVarsY(DstWrite); \ | |
| pMask = PtrAddBytes(pMask, maskScan); \ | |
| } while (--height > 0); \ | |
| } else /* pMask == 0 */ { \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## DST ## StoreVarsX(DstWrite, pDstInfo); \ | |
| do { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAlphaVarFor ## STRATEGY(srcF) \ | |
| \ | |
| LoadAlphaFrom ## SRC ## For ## STRATEGY(pSrc, SrcPix, res); \ | |
| resA = MultiplyAlphaFor ## STRATEGY(extraA, resA); \ | |
| if (resA) { \ | |
| if (SRC ## IsPremultiplied) { \ | |
| srcF = extraA; \ | |
| } else { \ | |
| srcF = resA; \ | |
| } \ | |
| Postload ## STRATEGY ## From ## SRC(pSrc, SrcPix, res); \ | |
| if (resA < MaxValFor ## STRATEGY) { \ | |
| DeclareAlphaVarFor ## STRATEGY(dstA) \ | |
| DeclareCompVarsFor ## STRATEGY(dst) \ | |
| DeclareAndInvertAlphaVarFor ## STRATEGY(dstF, resA) \ | |
| LoadAlphaFrom ## DST ## For ## STRATEGY(pDst, \ | |
| DstPix, \ | |
| dst); \ | |
| dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \ | |
| if (!(DST ## IsPremultiplied)) { \ | |
| dstF = dstA; \ | |
| } \ | |
| Postload ## STRATEGY ## From ## DST(pDst, DstPix, \ | |
| dst); \ | |
| resA += dstA; \ | |
| MultMultAddAndStore ## STRATEGY ## Comps(res, \ | |
| dstF, dst, \ | |
| srcF, res); \ | |
| } else if (srcF < MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(res, \ | |
| srcF, res); \ | |
| } \ | |
| if (!(DST ## IsOpaque) && \ | |
| !(DST ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ | |
| } \ | |
| Store ## DST ## From ## STRATEGY ## Comps(pDst, DstWrite,\ | |
| 0, res); \ | |
| } \ | |
| pSrc = PtrAddBytes(pSrc, SRC ## PixelStride); \ | |
| pDst = PtrAddBytes(pDst, DST ## PixelStride); \ | |
| Next ## DST ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pSrc = PtrAddBytes(pSrc, srcScan); \ | |
| pDst = PtrAddBytes(pDst, dstScan); \ | |
| Next ## DST ## StoreVarsY(DstWrite); \ | |
| } while (--height > 0); \ | |
| } \ | |
| } | |
| #define DEFINE_ALPHA_MASKFILL(TYPE, STRATEGY) \ | |
| void NAME_ALPHA_MASKFILL(TYPE) \ | |
| (void *rasBase, \ | |
| jubyte *pMask, jint maskOff, jint maskScan, \ | |
| jint width, jint height, \ | |
| jint fgColor, \ | |
| SurfaceDataRasInfo *pRasInfo, \ | |
| NativePrimitive *pPrim, \ | |
| CompositeInfo *pCompInfo) \ | |
| { \ | |
| DeclareAndSetOpaqueAlphaVarFor ## STRATEGY(pathA) \ | |
| DeclareAlphaVarFor ## STRATEGY(srcA) \ | |
| DeclareCompVarsFor ## STRATEGY(src) \ | |
| DeclareAndClearAlphaVarFor ## STRATEGY(dstA) \ | |
| DeclareAlphaVarFor ## STRATEGY(dstF) \ | |
| DeclareAlphaVarFor ## STRATEGY(dstFbase) \ | |
| jint rasScan = pRasInfo->scanStride; \ | |
| jboolean loaddst; \ | |
| TYPE ## DataType *pRas = (TYPE ## DataType *) (rasBase); \ | |
| Declare ## TYPE ## AlphaLoadData(DstPix) \ | |
| Declare ## TYPE ## StoreVars(DstWrite) \ | |
| DeclareAlphaOperands(SrcOp) \ | |
| DeclareAlphaOperands(DstOp) \ | |
| \ | |
| Extract ## STRATEGY ## CompsAndAlphaFromArgb(fgColor, src); \ | |
| if (srcA != MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(src, srcA, src); \ | |
| } \ | |
| \ | |
| ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].srcOps, \ | |
| SrcOp); \ | |
| ExtractAlphaOperandsFor ## STRATEGY(AlphaRules[pCompInfo->rule].dstOps, \ | |
| DstOp); \ | |
| loaddst = pMask || !FuncIsZero(DstOp) || FuncNeedsAlpha(SrcOp); \ | |
| \ | |
| dstFbase = dstF = ApplyAlphaOperands(DstOp, srcA); \ | |
| \ | |
| Init ## TYPE ## AlphaLoadData(DstPix, pRasInfo); \ | |
| rasScan -= width * TYPE ## PixelStride; \ | |
| maskScan -= width; \ | |
| if (pMask) { \ | |
| pMask += maskOff; \ | |
| } \ | |
| \ | |
| Init ## TYPE ## StoreVarsY(DstWrite, pRasInfo); \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \ | |
| do { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAlphaVarFor ## STRATEGY(srcF) \ | |
| \ | |
| if (pMask) { \ | |
| pathA = *pMask++; \ | |
| if (!pathA) { \ | |
| pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \ | |
| Next ## TYPE ## StoreVarsX(DstWrite); \ | |
| continue; \ | |
| } \ | |
| PromoteByteAlphaFor ## STRATEGY(pathA); \ | |
| dstF = dstFbase; \ | |
| } \ | |
| if (loaddst) { \ | |
| LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas, DstPix, dst);\ | |
| } \ | |
| srcF = ApplyAlphaOperands(SrcOp, dstA); \ | |
| if (pathA != MaxValFor ## STRATEGY) { \ | |
| srcF = MultiplyAlphaFor ## STRATEGY(pathA, srcF); \ | |
| dstF = MaxValFor ## STRATEGY - pathA + \ | |
| MultiplyAlphaFor ## STRATEGY(pathA, dstF); \ | |
| } \ | |
| if (srcF) { \ | |
| if (srcF == MaxValFor ## STRATEGY) { \ | |
| resA = srcA; \ | |
| Store ## STRATEGY ## CompsUsingOp(res, =, src); \ | |
| } else { \ | |
| resA = MultiplyAlphaFor ## STRATEGY(srcF, srcA); \ | |
| MultiplyAndStore ## STRATEGY ## Comps(res, srcF, src); \ | |
| } \ | |
| } else { \ | |
| if (dstF == MaxValFor ## STRATEGY) { \ | |
| pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \ | |
| Next ## TYPE ## StoreVarsX(DstWrite); \ | |
| continue; \ | |
| } \ | |
| resA = 0; \ | |
| Set ## STRATEGY ## CompsToZero(res); \ | |
| } \ | |
| if (dstF) { \ | |
| dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \ | |
| resA += dstA; \ | |
| if (TYPE ## IsPremultiplied) { \ | |
| dstA = dstF; \ | |
| } \ | |
| if (dstA) { \ | |
| DeclareCompVarsFor ## STRATEGY(tmp) \ | |
| /* assert(loaddst); */ \ | |
| Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, tmp); \ | |
| if (dstA != MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(tmp, \ | |
| dstA, tmp); \ | |
| } \ | |
| Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \ | |
| } \ | |
| } \ | |
| if (!(TYPE ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ | |
| } \ | |
| Store ## TYPE ## From ## STRATEGY ## Comps(pRas, DstWrite, \ | |
| 0, res); \ | |
| pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \ | |
| Next ## TYPE ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pRas = PtrAddBytes(pRas, rasScan); \ | |
| Next ## TYPE ## StoreVarsY(DstWrite); \ | |
| if (pMask) { \ | |
| pMask = PtrAddBytes(pMask, maskScan); \ | |
| } \ | |
| } while (--height > 0); \ | |
| } | |
| #define DEFINE_SRC_MASKFILL(TYPE, STRATEGY) \ | |
| void NAME_SRC_MASKFILL(TYPE) \ | |
| (void *rasBase, \ | |
| jubyte *pMask, jint maskOff, jint maskScan, \ | |
| jint width, jint height, \ | |
| jint fgColor, \ | |
| SurfaceDataRasInfo *pRasInfo, \ | |
| NativePrimitive *pPrim, \ | |
| CompositeInfo *pCompInfo) \ | |
| { \ | |
| DeclareAlphaVarFor ## STRATEGY(srcA) \ | |
| DeclareCompVarsFor ## STRATEGY(src) \ | |
| jint rasScan = pRasInfo->scanStride; \ | |
| TYPE ## DataType *pRas = (TYPE ## DataType *) (rasBase); \ | |
| Declare ## TYPE ## AlphaLoadData(DstPix) \ | |
| Declare ## TYPE ## StoreVars(DstWrite) \ | |
| Declare ## TYPE ## BlendFillVars(DstFill) \ | |
| \ | |
| Extract ## STRATEGY ## CompsAndAlphaFromArgb(fgColor, src); \ | |
| if (srcA == 0) { \ | |
| Set ## STRATEGY ## CompsToZero(src); \ | |
| Clear ## TYPE ## BlendFillVars(DstFill, fgColor); \ | |
| } else { \ | |
| if (!(TYPE ## IsPremultiplied)) { \ | |
| Init ## TYPE ## BlendFillVarsNonPre(DstFill, fgColor, src); \ | |
| } \ | |
| if (srcA != MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(src, srcA, src); \ | |
| } \ | |
| if (TYPE ## IsPremultiplied) { \ | |
| Init ## TYPE ## BlendFillVarsPre(DstFill, fgColor, src); \ | |
| } \ | |
| } \ | |
| \ | |
| Init ## TYPE ## AlphaLoadData(DstPix, pRasInfo); \ | |
| Init ## TYPE ## StoreVarsY(DstWrite, pRasInfo); \ | |
| \ | |
| rasScan -= width * TYPE ## PixelStride; \ | |
| if (pMask) { \ | |
| pMask += maskOff; \ | |
| maskScan -= width; \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \ | |
| do { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAlphaVarFor ## STRATEGY(dstF) \ | |
| DeclareAndInitPathAlphaFor ## STRATEGY(pathA) \ | |
| \ | |
| if (pathA > 0) { \ | |
| if (pathA == 0xff) { \ | |
| /* pathA ignored here, not promoted */ \ | |
| Store ## TYPE ## BlendFill(pRas, DstFill, 0, \ | |
| fgColor, src); \ | |
| } else { \ | |
| PromoteByteAlphaFor ## STRATEGY(pathA); \ | |
| dstF = MaxValFor ## STRATEGY - pathA; \ | |
| LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas, \ | |
| DstPix, \ | |
| res); \ | |
| resA = MultiplyAlphaFor ## STRATEGY(dstF, resA); \ | |
| if (!(TYPE ## IsPremultiplied)) { \ | |
| dstF = resA; \ | |
| } \ | |
| resA += MultiplyAlphaFor ## STRATEGY(pathA, srcA); \ | |
| Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, \ | |
| res); \ | |
| MultMultAddAndStore ## STRATEGY ## Comps(res, \ | |
| dstF, res, \ | |
| pathA, src);\ | |
| if (!(TYPE ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, \ | |
| res, resA); \ | |
| } \ | |
| Store ## TYPE ## From ## STRATEGY ## Comps(pRas, \ | |
| DstWrite, \ | |
| 0, res); \ | |
| } \ | |
| } \ | |
| pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \ | |
| Next ## TYPE ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pRas = PtrAddBytes(pRas, rasScan); \ | |
| Next ## TYPE ## StoreVarsY(DstWrite); \ | |
| pMask = PtrAddBytes(pMask, maskScan); \ | |
| } while (--height > 0); \ | |
| } else /* pMask == 0 */ { \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \ | |
| do { \ | |
| Store ## TYPE ## BlendFill(pRas, DstFill, 0, fgColor, src); \ | |
| pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \ | |
| Next ## TYPE ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pRas = PtrAddBytes(pRas, rasScan); \ | |
| Next ## TYPE ## StoreVarsY(DstWrite); \ | |
| } while (--height > 0); \ | |
| } \ | |
| } | |
| #define DEFINE_SRCOVER_MASKFILL(TYPE, STRATEGY) \ | |
| void NAME_SRCOVER_MASKFILL(TYPE) \ | |
| (void *rasBase, \ | |
| jubyte *pMask, jint maskOff, jint maskScan, \ | |
| jint width, jint height, \ | |
| jint fgColor, \ | |
| SurfaceDataRasInfo *pRasInfo, \ | |
| NativePrimitive *pPrim, \ | |
| CompositeInfo *pCompInfo) \ | |
| { \ | |
| DeclareAlphaVarFor ## STRATEGY(srcA) \ | |
| DeclareCompVarsFor ## STRATEGY(src) \ | |
| jint rasScan = pRasInfo->scanStride; \ | |
| TYPE ## DataType *pRas = (TYPE ## DataType *) (rasBase); \ | |
| Declare ## TYPE ## AlphaLoadData(DstPix) \ | |
| Declare ## TYPE ## StoreVars(DstWrite) \ | |
| \ | |
| Extract ## STRATEGY ## CompsAndAlphaFromArgb(fgColor, src); \ | |
| if (srcA != MaxValFor ## STRATEGY) { \ | |
| if (srcA == 0) { \ | |
| return; \ | |
| } \ | |
| MultiplyAndStore ## STRATEGY ## Comps(src, srcA, src); \ | |
| } \ | |
| \ | |
| Init ## TYPE ## AlphaLoadData(DstPix, pRasInfo); \ | |
| Init ## TYPE ## StoreVarsY(DstWrite, pRasInfo); \ | |
| \ | |
| rasScan -= width * TYPE ## PixelStride; \ | |
| if (pMask) { \ | |
| pMask += maskOff; \ | |
| maskScan -= width; \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \ | |
| do { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAndInitPathAlphaFor ## STRATEGY(pathA) \ | |
| \ | |
| if (pathA > 0) { \ | |
| if (pathA != 0xff) { \ | |
| PromoteByteAlphaFor ## STRATEGY(pathA); \ | |
| resA = MultiplyAlphaFor ## STRATEGY(pathA, srcA); \ | |
| MultiplyAndStore ## STRATEGY ## Comps(res, \ | |
| pathA, src); \ | |
| } else { \ | |
| /* pathA ignored here, not promoted */ \ | |
| resA = srcA; \ | |
| Store ## STRATEGY ## CompsUsingOp(res, =, src); \ | |
| } \ | |
| if (resA != MaxValFor ## STRATEGY) { \ | |
| DeclareAndInvertAlphaVarFor ## STRATEGY(dstF, resA) \ | |
| DeclareAndClearAlphaVarFor ## STRATEGY(dstA) \ | |
| LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas, \ | |
| DstPix, \ | |
| dst); \ | |
| dstA = MultiplyAlphaFor ## STRATEGY(dstF, dstA); \ | |
| if (!(TYPE ## IsPremultiplied)) { \ | |
| dstF = dstA; \ | |
| } \ | |
| resA += dstA; \ | |
| if (dstF) { \ | |
| DeclareCompVarsFor ## STRATEGY(tmp) \ | |
| Postload ## STRATEGY ## From ## TYPE(pRas, \ | |
| DstPix, \ | |
| tmp); \ | |
| if (dstF != MaxValFor ## STRATEGY) { \ | |
| MultiplyAndStore ## STRATEGY ## Comps(tmp, \ | |
| dstF, \ | |
| tmp); \ | |
| } \ | |
| Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \ | |
| } \ | |
| } \ | |
| if (!(TYPE ## IsOpaque) && \ | |
| !(TYPE ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ | |
| } \ | |
| Store ## TYPE ## From ## STRATEGY ## Comps(pRas, \ | |
| DstWrite, 0, \ | |
| res); \ | |
| } \ | |
| pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \ | |
| Next ## TYPE ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pRas = PtrAddBytes(pRas, rasScan); \ | |
| Next ## TYPE ## StoreVarsY(DstWrite); \ | |
| pMask = PtrAddBytes(pMask, maskScan); \ | |
| } while (--height > 0); \ | |
| } else /* pMask == 0 */ { \ | |
| do { \ | |
| jint w = width; \ | |
| Init ## TYPE ## StoreVarsX(DstWrite, pRasInfo); \ | |
| do { \ | |
| DeclareAlphaVarFor ## STRATEGY(resA) \ | |
| DeclareCompVarsFor ## STRATEGY(res) \ | |
| DeclareAndInvertAlphaVarFor ## STRATEGY(dstF, srcA) \ | |
| \ | |
| LoadAlphaFrom ## TYPE ## For ## STRATEGY(pRas, DstPix, res);\ | |
| resA = MultiplyAlphaFor ## STRATEGY(dstF, resA); \ | |
| if (!(TYPE ## IsPremultiplied)) { \ | |
| dstF = resA; \ | |
| } \ | |
| resA += srcA; \ | |
| Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, res); \ | |
| MultiplyAddAndStore ## STRATEGY ## Comps(res, \ | |
| dstF, res, src); \ | |
| if (!(TYPE ## IsOpaque) && \ | |
| !(TYPE ## IsPremultiplied) && resA && \ | |
| resA < MaxValFor ## STRATEGY) \ | |
| { \ | |
| DivideAndStore ## STRATEGY ## Comps(res, res, resA); \ | |
| } \ | |
| Store ## TYPE ## From ## STRATEGY ## Comps(pRas, DstWrite, \ | |
| 0, res); \ | |
| pRas = PtrAddBytes(pRas, TYPE ## PixelStride); \ | |
| Next ## TYPE ## StoreVarsX(DstWrite); \ | |
| } while (--w > 0); \ | |
| pRas = PtrAddBytes(pRas, rasScan); \ | |
| Next ## TYPE ## StoreVarsY(DstWrite); \ | |
| } while (--height > 0); \ | |
| } \ | |
| } | |
| /* | |
| * The macros defined above use the following macro definitions supplied | |
| * for the various surface types to manipulate pixels and pixel data. | |
| * The surface-specific macros are typically supplied by header files | |
| * named after the SurfaceType name (eg. IntArgb.h, ByteGray.h, etc.). | |
| * | |
| * In the macro names in the following definitions, the string <stype> | |
| * is used as a place holder for the SurfaceType name (eg. IntArgb). The | |
| * string <strategy> is a place holder for the strategy name (eg. 4ByteArgb). | |
| * The macros above access these type specific macros using the ANSI | |
| * CPP token concatenation operator "##". | |
| * | |
| * Declare<stype>AlphaLoadData Declare the variables used when an alpha | |
| * value is pre-fetched to see whether or | |
| * not blending needs to occur | |
| * Init<stype>AlphaLoadData Initialize the aforementioned variables | |
| * LoadAlphaFrom<stype>For<strategy> Load the alpha value for the given pixel | |
| * into a variable used later (the strategy | |
| * type determines the bit depth of the | |
| * alpha value) | |
| * Postload<strategy>From<stype> Load the pixel components from the given | |
| * surface type into the form required by | |
| * the given strategy. Typically there will | |
| * be a couple macros of this variety, one | |
| * for 4ByteArgb, one for 1ByteGray, one | |
| * for 1ShortGray, etc. Its code is only | |
| * executed when blending needs to occur. | |
| * | |
| * <stype>IsPremultiplied Constant specifying whether the pixel | |
| * components have been premultiplied with | |
| * the alpha value | |
| * Declare<stype>BlendFillVars Declare the variables used when alpha | |
| * blending need not occur (mask and source | |
| * pixel are opaque) | |
| * Clear<stype>BlendFillVars Clear the variables used in a no-blend | |
| * situation (may modify argb argument) | |
| * Init<stype>BlendFillVarsNonPre Initialize the variables used for a | |
| * no-blending situation (this macro is for | |
| * surfaces that do not have premultiplied | |
| * components) (may modify argb argument) | |
| * Init<stype>BlendFillVarsPre Initialize the variables used for a | |
| * no-blending situation (this macro is for | |
| * surfaces that have premultiplied | |
| * components) (may modify argb argument) | |
| * Store<stype>BlendFill Simply store the pixel for the given | |
| * surface (used when blending is | |
| * unnecessary) | |
| * Store<stype>From<strategy>Comps Store the pixel for the given surface | |
| * type after converting it from a pixel of | |
| * the given strategy | |
| */ | |
| #endif /* AlphaMacros_h_Included */ |