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