180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkXfermode.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenableBuffers.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMathPriv.h" 14d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkString.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(SkXfermode) 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// idea for higher precision blends in xfer procs (and slightly faster) 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// see DstATop as a probable caller 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(a <= 255); 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(b <= 255); 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(c <= 255); 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(d <= 255); 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned prod = SkMulS16(a, b) + SkMulS16(c, d) + 128; 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned result = (prod + (prod >> 8)) >> 8; 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(result <= 255); 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return result; 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned saturated_add(unsigned a, unsigned b) { 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(a <= 255); 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(b <= 255); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned sum = a + b; 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sum > 255) { 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sum = 255; 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return sum; 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int clamp_signed_byte(int n) { 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (n < 0) { 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = 0; 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (n > 255) { 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = 255; 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return n; 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int clamp_div255round(int prod) { 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (prod <= 0) { 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (prod >= 255*255) { 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 255; 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkDiv255Round(prod); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int clamp_max(int value, int max) { 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value > max) { 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru value = max; 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return value; 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kClear_Mode, //!< [0, 0] 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kSrc_Mode, //!< [Sa, Sc] 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return src; 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kDst_Mode, //!< [Da, Dc] 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) { 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this is the old, more-correct way, but it doesn't guarantee that dst==255 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // will always stay opaque 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this is slightly faster, but more importantly guarantees that dst==255 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // will always stay opaque 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src)); 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kDstOver_Mode, //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc] 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) { 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this is the reverse of srcover, just flipping src and dst 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // see srcover's comment about the 256 for opaqueness guarantees 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst)); 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) { 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src))); 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) { 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst))); 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) { 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) { 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned sa = SkGetPackedA32(src); 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned da = SkGetPackedA32(dst); 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned isa = 255 - sa; 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(da, 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(da, SkGetPackedR32(src)) + 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(da, SkGetPackedG32(src)) + 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(da, SkGetPackedB32(src)) + 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) { 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned sa = SkGetPackedA32(src); 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned da = SkGetPackedA32(dst); 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned ida = 255 - da; 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(sa, 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(sa, SkGetPackedR32(dst)), 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(sa, SkGetPackedG32(dst)), 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(sa, SkGetPackedB32(dst))); 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) { 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned sa = SkGetPackedA32(src); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned da = SkGetPackedA32(dst); 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned isa = 255 - sa; 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned ida = 255 - da; 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1), 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kPlus_Mode 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 185d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger// kModulate_Mode 186d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic SkPMColor modulate_modeproc(SkPMColor src, SkPMColor dst) { 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kScreen_Mode 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int srcover_byte(int a, int b) { 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return a + b - SkAlphaMulAlpha(a, b); 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kOverlay_Mode 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int overlay_byte(int sc, int dc, int sa, int da) { 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tmp = sc * (255 - da) + dc * (255 - sa); 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int rc; 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (2 * dc <= da) { 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = 2 * sc * dc; 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = sa * da - 2 * (da - dc) * (sa - sc); 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return clamp_div255round(rc + tmp); 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kDarken_Mode 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int darken_byte(int sc, int dc, int sa, int da) { 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sd = sc * da; 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int ds = dc * sa; 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sd < ds) { 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // srcover 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return sc + dc - SkDiv255Round(ds); 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // dstover 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dc + sc - SkDiv255Round(sd); 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kLighten_Mode 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int lighten_byte(int sc, int dc, int sa, int da) { 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sd = sc * da; 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int ds = dc * sa; 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sd > ds) { 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // srcover 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return sc + dc - SkDiv255Round(ds); 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // dstover 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dc + sc - SkDiv255Round(sd); 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kColorDodge_Mode 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int colordodge_byte(int sc, int dc, int sa, int da) { 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int diff = sa - sc; 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int rc; 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == diff) { 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = sa * da + sc * (255 - da) + dc * (255 - sa); 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = SkDiv255Round(rc); 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tmp = (dc * sa << 15) / (da * diff); 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = SkDiv255Round(sa * da) * tmp >> 15; 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // don't clamp here, since we'll do it in our modeproc 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return rc; 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // added to avoid div-by-zero in colordodge_byte 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == dst) { 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return src; 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru r = clamp_max(r, a); 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru g = clamp_max(g, a); 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru b = clamp_max(b, a); 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kColorBurn_Mode 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int colorburn_byte(int sc, int dc, int sa, int da) { 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int rc; 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (dc == da && 0 == sc) { 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = sa * da + dc * (255 - sa); 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (0 == sc) { 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkAlphaMulAlpha(dc, 255 - sa); 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tmp = (sa * (da - dc) * 256) / (sc * da); 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (tmp > 256) { 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp = 256; 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tmp2 = sa * da; 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa); 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkDiv255Round(rc); 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // added to avoid div-by-zero in colorburn_byte 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == dst) { 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return src; 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kHardLight_Mode 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int hardlight_byte(int sc, int dc, int sa, int da) { 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int rc; 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (2 * sc <= sa) { 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = 2 * sc * dc; 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = sa * da - 2 * (da - dc) * (sa - sc); 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// returns 255 * sqrt(n/255) 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic U8CPU sqrt_unit_byte(U8CPU n) { 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkSqrtBits(n, 15+4); 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kSoftLight_Mode 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int softlight_byte(int sc, int dc, int sa, int da) { 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int m = da ? dc * 256 / da : 0; 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int rc; 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (2 * sc <= sa) { 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (4 * dc <= da) { 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tmp = sqrt_unit_byte(m) - m; 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kDifference_Mode 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int difference_byte(int sc, int dc, int sa, int da) { 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int tmp = SkMin32(sc * da, dc * sa); 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// kExclusion_Mode 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int exclusion_byte(int sc, int dc, int sa, int da) { 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this equations is wacky, wait for SVG to confirm it 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return clamp_div255round(r); 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sa = SkGetPackedA32(src); 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int da = SkGetPackedA32(dst); 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int a = srcover_byte(sa, da); 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackARGB32(a, r, g, b); 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct ProcCoeff { 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc fProc; 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermode::Coeff fSC; 41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermode::Coeff fDC; 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define CANNOT_USE_COEFF SkXfermode::Coeff(-1) 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const ProcCoeff gProcCoeffs[] = { 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 439d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger { modulate_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { screen_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 454363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const { 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 458363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkXfermode::asMode(Mode* mode) const { 45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 462363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerSkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // no-op. subclasses should override this 46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 469363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = this->xferColor(src[i], dst[i]); 47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = dst[i]; 48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor C = this->xferColor(src[i], dstC); 48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF != a) { 48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru C = SkFourByteInterp(C, dstC, a); 48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = C; 48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXfermode::xfer16(uint16_t* dst, 49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 493363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 50580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor C = this->xferColor(src[i], dstC); 50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF != a) { 50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru C = SkFourByteInterp(C, dstC, a); 50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkPixel32ToPixel16_ToU16(C); 51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 51780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 518363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 51980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkPixel32ToPixel4444(this->xferColor(src[i], dstC)); 52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 52980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 53180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor C = this->xferColor(src[i], dstC); 53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF != a) { 53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru C = SkFourByteInterp(C, dstC, a); 53480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkPixel32ToPixel4444(C); 53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 54080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor src[], int count, 543363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkToU8(SkGetPackedA32(res)); 55080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlpha dstA = dst[i]; 55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned A = SkGetPackedA32(this->xferColor(src[i], 55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (SkPMColor)(dstA << SK_A32_SHIFT))); 55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF != a) { 55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 56080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkToU8(A); 56280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 56380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkProcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 571363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc proc = fProc; 57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != proc) { 57780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = proc(src[i], dst[i]); 58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = dst[i]; 58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor C = proc(src[i], dstC); 58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (a != 0xFF) { 58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru C = SkFourByteInterp(C, dstC, a); 58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = C; 59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkProcXfermode::xfer16(uint16_t* SK_RESTRICT dst, 59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 599363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc proc = fProc; 60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != proc) { 60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor C = proc(src[i], dstC); 61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF != a) { 61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru C = SkFourByteInterp(C, dstC, a); 61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkPixel32ToPixel16_ToU16(C); 62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkProcXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 628363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc proc = fProc; 63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != proc) { 63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 63580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 63680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 63780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkPixel32ToPixel4444(proc(src[i], dstC)); 63880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor C = proc(src[i], dstC); 64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF != a) { 64680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru C = SkFourByteInterp(C, dstC, a); 64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 64880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkPixel32ToPixel4444(C); 64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkProcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 65680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 657363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 65980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc proc = fProc; 66180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != proc) { 66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 66480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkToU8(SkGetPackedA32(res)); 66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 66880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 67080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 67280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAlpha dstA = dst[i]; 67380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 67480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned A = SkGetPackedA32(res); 67580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF != a) { 67680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 67780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 67880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkToU8(A); 67980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 68480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 68580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkProcXfermode::SkProcXfermode(SkFlattenableReadBuffer& buffer) 68680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : SkXfermode(buffer) { 68780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fProc = NULL; 68880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!buffer.isCrossProcess()) { 68980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fProc = (SkXfermodeProc)buffer.readFunctionPtr(); 69080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 69180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 69280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 69380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkProcXfermode::flatten(SkFlattenableWriteBuffer& buffer) const { 69480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::flatten(buffer); 69580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!buffer.isCrossProcess()) { 69680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.writeFunctionPtr((void*)fProc); 69780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 69880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 69980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 700d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER 701d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkProcXfermode::toString(SkString* str) const { 702d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->appendf("SkProcXfermode: %p", fProc); 703d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 704d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 705d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 70680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkProcCoeffXfermode : public SkProcXfermode { 71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 71180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) 71280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : INHERITED(rec.fProc) { 71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMode = mode; 71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // these may be valid, or may be CANNOT_USE_COEFF 71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSrcCoeff = rec.fSC; 71680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDstCoeff = rec.fDC; 71780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 71880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 719363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual bool asMode(Mode* mode) const SK_OVERRIDE { 72080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (mode) { 72180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *mode = fMode; 72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 72480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 726363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE { 72780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (CANNOT_USE_COEFF == fSrcCoeff) { 72880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 72980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 73180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sc) { 73280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *sc = fSrcCoeff; 73380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (dc) { 73580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *dc = fDstCoeff; 73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 740d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SK_DEVELOPER_TO_STRING() 74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) 74280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 74380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected: 74480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { 74580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMode = (SkXfermode::Mode)buffer.read32(); 74680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 74780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const ProcCoeff& rec = gProcCoeffs[fMode]; 74880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // these may be valid, or may be CANNOT_USE_COEFF 74980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSrcCoeff = rec.fSC; 75080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDstCoeff = rec.fDC; 75180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // now update our function-ptr in the super class 75280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::setProc(rec.fProc); 75380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 75480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 75580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { 75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::flatten(buffer); 75780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.write32(fMode); 75880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 75980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 76080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 76180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Mode fMode; 76280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Coeff fSrcCoeff, fDstCoeff; 76380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 76480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkProcXfermode INHERITED; 76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 76680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 767d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER 768d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkProcCoeffXfermode::toString(SkString* str) const { 769d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append("SkProcCoeffXfermode: "); 770d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 771d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const char *gModeStrings[kLastMode+1] = { 772d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", 773d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", 774d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", 775d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion" 776d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger }; 777d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 778d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append("mode: "); 779d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append(gModeStrings[fMode]); 780d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 781d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger static const char* gCoeffStrings[kCoeffCount] = { 782d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA" 783d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger }; 784d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 785d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append(" src: "); 786d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (CANNOT_USE_COEFF == fSrcCoeff) { 787d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append("can't use"); 788d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else { 789d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append(gCoeffStrings[fSrcCoeff]); 790d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 791d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 792d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append(" dst: "); 793d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (CANNOT_USE_COEFF == fDstCoeff) { 794d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append("can't use"); 795d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else { 796d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append(gCoeffStrings[fDstCoeff]); 797d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 798d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 799d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 800d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 80180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 80280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 80380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkClearXfermode : public SkProcCoeffXfermode { 80480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 80580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} 80680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 807363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 808363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 80980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 810d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SK_DEVELOPER_TO_STRING() 81180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkClearXfermode) 81280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 81380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 81480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkClearXfermode(SkFlattenableReadBuffer& buffer) 81580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : SkProcCoeffXfermode(buffer) {} 81680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 817d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger typedef SkProcCoeffXfermode INHERITED; 81880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 81980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 82080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 82180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT, int count, 822363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 82380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && count >= 0); 82480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 82580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 82680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(dst, 0, count << 2); 82780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 82880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 82980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 83080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF == a) { 83180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = 0; 83280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (a != 0) { 83380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); 83480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 83580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 83680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 83780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 83880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 83980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT, int count, 840363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 84180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && count >= 0); 84280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 84380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 84480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memset(dst, 0, count); 84580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 84680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 84780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 84880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0xFF == a) { 84980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = 0; 85080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (0 != a) { 85180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); 85280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 85380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 85480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 85580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 85680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 857d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER 858d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkClearXfermode::toString(SkString* str) const { 859d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->INHERITED::toString(str); 860d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 861d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 862d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 86380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 86480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 86580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkSrcXfermode : public SkProcCoeffXfermode { 86680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 86780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} 86880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 869363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 870363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 87180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 872d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SK_DEVELOPER_TO_STRING() 87380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSrcXfermode) 87480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 87580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 87680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkSrcXfermode(SkFlattenableReadBuffer& buffer) 87780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : SkProcCoeffXfermode(buffer) {} 87880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 879d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger typedef SkProcCoeffXfermode INHERITED; 88080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 88180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 88280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 88380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 884363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 88580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 88680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 88780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 88880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(dst, src, count << 2); 88980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 89080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 89180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 89280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (a == 0xFF) { 89380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = src[i]; 89480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (a != 0) { 89580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkFourByteInterp(src[i], dst[i], a); 89680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 89780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 89880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 89980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 90080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 90280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 903363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 90480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src && count >= 0); 90580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 90680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == aa) { 90780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 90880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkToU8(SkGetPackedA32(src[i])); 90980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 91080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 91180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 91280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = aa[i]; 91380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 != a) { 91480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned srcA = SkGetPackedA32(src[i]); 91580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (a == 0xFF) { 91680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkToU8(srcA); 91780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 91880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); 91980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 92080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 92180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 92280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 92380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 924d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER 925d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkSrcXfermode::toString(SkString* str) const { 926d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->INHERITED::toString(str); 927d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 928d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 92980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 930363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 93180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 93280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkDstInXfermode : public SkProcCoeffXfermode { 93380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 93480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} 93580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 936363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 93780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 938d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SK_DEVELOPER_TO_STRING() 93980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstInXfermode) 94080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 94180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 94280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDstInXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 94380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 94480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkProcCoeffXfermode INHERITED; 94580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 94680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 94780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 94880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 949363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 95080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src); 95180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 95280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count <= 0) { 95380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 95480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 95580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != aa) { 95680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->INHERITED::xfer32(dst, src, count, aa); 95780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 95880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 95980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 96080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = SkGetPackedA32(*src); 96180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); 96280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst++; 96380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src++; 96480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--count != 0); 96580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 96680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 967d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER 968d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkDstInXfermode::toString(SkString* str) const { 969d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->INHERITED::toString(str); 970d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 971d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 972d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 973363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 97480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 97580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkDstOutXfermode : public SkProcCoeffXfermode { 97680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 97780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} 97880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 979363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; 98080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 981d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SK_DEVELOPER_TO_STRING() 98280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstOutXfermode) 98380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 98480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 98580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDstOutXfermode(SkFlattenableReadBuffer& buffer) 98680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : INHERITED(buffer) {} 98780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 98880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkProcCoeffXfermode INHERITED; 98980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 99080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 99180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 99280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPMColor* SK_RESTRICT src, int count, 993363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkAlpha* SK_RESTRICT aa) const { 99480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && src); 99580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 99680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count <= 0) { 99780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 99880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 99980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != aa) { 100080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->INHERITED::xfer32(dst, src, count, aa); 100180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 100280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 100380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 100480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = SkGetPackedA32(*src); 100580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); 100680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst++; 100780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src++; 100880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--count != 0); 100980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 101080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1011d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER 1012d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkDstOutXfermode::toString(SkString* str) const { 1013d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->INHERITED::toString(str); 1014d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 1015d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 1016d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 101780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 101880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 101980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXfermode* SkXfermode::Create(Mode mode) { 102080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 102180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)mode < kModeCount); 102280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 102380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const ProcCoeff& rec = gProcCoeffs[mode]; 102480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 102580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (mode) { 102680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kClear_Mode: 102780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(SkClearXfermode, (rec)); 102880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kSrc_Mode: 102980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(SkSrcXfermode, (rec)); 103080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kSrcOver_Mode: 103180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 103280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kDstIn_Mode: 103380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(SkDstInXfermode, (rec)); 103480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kDstOut_Mode: 103580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(SkDstOutXfermode, (rec)); 103680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 103780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 103880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 103980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 104080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 104180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXfermodeProc SkXfermode::GetProc(Mode mode) { 104280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc proc = NULL; 104380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((unsigned)mode < kModeCount) { 104480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru proc = gProcCoeffs[mode].fProc; 104580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 104680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return proc; 104780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 104880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 104980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 105080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 105180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 105280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((unsigned)mode >= (unsigned)kModeCount) { 105380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // illegal mode parameter 105480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 105580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 105680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 105780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const ProcCoeff& rec = gProcCoeffs[mode]; 105880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 105980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (CANNOT_USE_COEFF == rec.fSC) { 106080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 106180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 106280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 106380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(CANNOT_USE_COEFF != rec.fDC); 106480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (src) { 106580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *src = rec.fSC; 106680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 106780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (dst) { 106880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *dst = rec.fDC; 106980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 107080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 107180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 107280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1073363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) { 107480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == xfer) { 107580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (mode) { 107680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *mode = kSrcOver_Mode; 107780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 107880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 107980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 108080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return xfer->asMode(mode); 108180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 108280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1083363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) { 108480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == xfer) { 108580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return ModeAsCoeff(kSrcOver_Mode, src, dst); 108680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 108780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return xfer->asCoeff(src, dst); 108880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 108980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1090363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) { 109180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if xfer==null then the mode is srcover 109280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Mode m = kSrcOver_Mode; 109380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (xfer && !xfer->asMode(&m)) { 109480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 109580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 109680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return mode == m; 109780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 109880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 109980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 110080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////// 16bit xfermode procs 110180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 110280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 110380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; } 110480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; } 110580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 110680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 110780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) { 110880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 110980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPixel32ToPixel16(src); 111080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 111180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) { 111380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 111480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 111580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) { 111780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_0(src)); 111880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 111980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 112080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 112180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) { 112280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 112380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPixel32ToPixel16(src); 112480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 112580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 112680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) { 112780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_0(src)); 112880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 112980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 113080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 113180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) { 113280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 113380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 113480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 113580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 113680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) { 113780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 113880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPixel32ToPixel16(src); 113980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 114080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 114180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) { 114280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 114380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 114480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 114580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 114680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) { 114780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_0(src)); 114880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 114980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 115080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 115180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) { 115280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned isa = 255 - SkGetPackedA32(src); 115380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 115480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackRGB16( 115580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa), 115680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa), 115780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa)); 115880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 115980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 116080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) { 116180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_0(src)); 116280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 116380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 116480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 116580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) { 116680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 116780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPixel32ToPixel16(src); 116880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 116980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 117080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) { 117180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 117280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 117380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 117480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 117580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/********* 117680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru darken and lighten boil down to this. 117780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 117880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru darken = (1 - Sa) * Dc + min(Sc, Dc) 117980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru lighten = (1 - Sa) * Dc + max(Sc, Dc) 118080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 118180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (Sa == 0) these become 118280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru darken = Dc + min(0, Dc) = 0 118380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru lighten = Dc + max(0, Dc) = Dc 118480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 118580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (Sa == 1) these become 118680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru darken = min(Sc, Dc) 118780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru lighten = max(Sc, Dc) 118880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/ 118980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) { 119180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_0(src)); 119280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 119380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 119480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) { 119680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 119780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 119880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 119980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 120080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackRGB16(r, g, b); 120180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 120280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) { 120480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_0(src)); 120580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 120680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 120780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) { 120980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(require_255(src)); 121080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 121180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 121280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 121380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkPackRGB16(r, g, b); 121480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 121580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 121680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct Proc16Rec { 121780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc16 fProc16_0; 121880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc16 fProc16_255; 121980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc16 fProc16_General; 122080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 122180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 122280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const Proc16Rec gModeProcs16[] = { 122380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // CLEAR 122480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, src_modeproc16_255, NULL }, 122580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { dst_modeproc16, dst_modeproc16, dst_modeproc16 }, 122680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { srcover_modeproc16_0, srcover_modeproc16_255, NULL }, 122780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { dstover_modeproc16_0, dstover_modeproc16_255, NULL }, 122880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, srcin_modeproc16_255, NULL }, 122980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, dstin_modeproc16_255, NULL }, 123080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL },// SRC_OUT 123180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { dstout_modeproc16_0, NULL, NULL }, 123280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 }, 123380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, dstatop_modeproc16_255, NULL }, 123480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // XOR 123580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // plus 1237d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger { NULL, NULL, NULL }, // modulate 123880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // screen 123980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // overlay 124080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken 124180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten 124280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // colordodge 124380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // colorburn 124480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // hardlight 124580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // softlight 124680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // difference 124780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { NULL, NULL, NULL }, // exclusion 124880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 124980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 125080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { 125180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkXfermodeProc16 proc16 = NULL; 125280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((unsigned)mode < kModeCount) { 125380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Proc16Rec& rec = gModeProcs16[mode]; 125480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned a = SkColorGetA(srcColor); 125580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 125680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == a) { 125780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru proc16 = rec.fProc16_0; 125880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (255 == a) { 125980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru proc16 = rec.fProc16_255; 126080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 126180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru proc16 = rec.fProc16_General; 126280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 126380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 126480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return proc16; 126580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 126680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 126780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 126880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 126980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) 127080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) 127180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) 127280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) 127380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1274