mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
908 lines
41 KiB
C
908 lines
41 KiB
C
/*
|
|
* Copyright 2000-2005 Sun Microsystems, Inc. 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. Sun designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
* CA 95054 USA or visit www.sun.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 */
|