blob: 4b03c8d4091f3dd7286d0ddde2b79fea898a926e [file] [log] [blame]
/*
* 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 */