1f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 2f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/* 3f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Copyright 2006 The Android Open Source Project 4f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * 5f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 6f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger * found in the LICENSE file. 7f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger */ 8f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 9f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 10f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkXfermode.h" 11f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#include "SkColorPriv.h" 12f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 13f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) 14f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 15f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#if 0 16f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// idea for higher precision blends in xfer procs (and slightly faster) 17f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// see DstATop as a probable caller 18f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { 19f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(a <= 255); 20f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(b <= 255); 21f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(c <= 255); 22f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(d <= 255); 23f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned prod = SkMulS16(a, b) + SkMulS16(c, d) + 128; 24f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned result = (prod + (prod >> 8)) >> 8; 25f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(result <= 255); 26f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return result; 27f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 28f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 29f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 30f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline unsigned saturated_add(unsigned a, unsigned b) { 31f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(a <= 255); 32f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(b <= 255); 33f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned sum = a + b; 34f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (sum > 255) { 35f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger sum = 255; 36f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 37f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return sum; 38f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 39f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 40f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int clamp_signed_byte(int n) { 41f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (n < 0) { 42f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n = 0; 43f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (n > 255) { 44f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger n = 255; 45f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 46f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return n; 47f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 48f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 49f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int clamp_div255round(int prod) { 50f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (prod <= 0) { 51f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return 0; 52f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (prod >= 255*255) { 53f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return 255; 54f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 55f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkDiv255Round(prod); 56f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 57f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 58f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 59f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int clamp_max(int value, int max) { 60f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (value > max) { 61f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger value = max; 62f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 63f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return value; 64f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 65f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 66f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 67f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 68f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kClear_Mode, //!< [0, 0] 69f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 70f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return 0; 71f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 72f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 73f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kSrc_Mode, //!< [Sa, Sc] 74f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 75f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return src; 76f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 77f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 78f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kDst_Mode, //!< [Da, Dc] 79f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 80f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 81f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 82f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 83f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 84f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) { 85f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#if 0 86f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // this is the old, more-correct way, but it doesn't guarantee that dst==255 87f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // will always stay opaque 88f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 89f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#else 90f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // this is slightly faster, but more importantly guarantees that dst==255 91f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // will always stay opaque 92f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src)); 93f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 94f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 95f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 96f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kDstOver_Mode, //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc] 97f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) { 98f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // this is the reverse of srcover, just flipping src and dst 99f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // see srcover's comment about the 256 for opaqueness guarantees 100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst)); 101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) { 110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src))); 111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) { 115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst))); 116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) { 120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) { 125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned sa = SkGetPackedA32(src); 126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned da = SkGetPackedA32(dst); 127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned isa = 255 - sa; 128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(da, 130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(da, SkGetPackedR32(src)) + 131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(da, SkGetPackedG32(src)) + 133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(da, SkGetPackedB32(src)) + 135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) { 140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned sa = SkGetPackedA32(src); 141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned da = SkGetPackedA32(dst); 142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned ida = 255 - da; 143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(sa, 145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(sa, SkGetPackedR32(dst)), 147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(sa, SkGetPackedG32(dst)), 149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(sa, SkGetPackedB32(dst))); 151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) { 155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned sa = SkGetPackedA32(src); 156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned da = SkGetPackedA32(dst); 157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned isa = 255 - sa; 158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned ida = 255 - da; 159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1), 161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 163f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 164f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 165f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 166f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 167f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 168f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 169f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 170f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 171f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kPlus_Mode 172f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { 173f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); 174f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); 175f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); 176f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); 177f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 178f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 179f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 180f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kMultiply_Mode 181f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { 182f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); 183f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); 184f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); 185f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); 186f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 187f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 188f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 189f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kScreen_Mode 190f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int srcover_byte(int a, int b) { 191f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return a + b - SkAlphaMulAlpha(a, b); 192f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 193f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 194f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 195f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 196f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 197f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 198f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 199f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 200f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 201f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kOverlay_Mode 202f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int overlay_byte(int sc, int dc, int sa, int da) { 203f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int tmp = sc * (255 - da) + dc * (255 - sa); 204f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int rc; 205f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (2 * dc <= da) { 206f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = 2 * sc * dc; 207f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 208f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = sa * da - 2 * (da - dc) * (sa - sc); 209f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 210f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return clamp_div255round(rc + tmp); 211f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 212f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 213f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 214f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 215f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 216f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 217f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 218f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 219f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 220f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 221f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 222f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kDarken_Mode 223f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int darken_byte(int sc, int dc, int sa, int da) { 224f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sd = sc * da; 225f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int ds = dc * sa; 226f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (sd < ds) { 227f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // srcover 228f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return sc + dc - SkDiv255Round(ds); 229f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 230f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // dstover 231f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dc + sc - SkDiv255Round(sd); 232f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 233f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 234f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 235f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 236f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 237f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 238f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 239f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 240f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 241f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 242f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 243f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 244f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kLighten_Mode 245f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int lighten_byte(int sc, int dc, int sa, int da) { 246f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sd = sc * da; 247f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int ds = dc * sa; 248f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (sd > ds) { 249f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // srcover 250f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return sc + dc - SkDiv255Round(ds); 251f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 252f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // dstover 253f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dc + sc - SkDiv255Round(sd); 254f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 255f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 256f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 257f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 258f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 259f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 260f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 261f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 262f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 263f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 264f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 265f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 266f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kColorDodge_Mode 267f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int colordodge_byte(int sc, int dc, int sa, int da) { 268f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int diff = sa - sc; 269f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int rc; 270f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 == diff) { 271f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = sa * da + sc * (255 - da) + dc * (255 - sa); 272f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = SkDiv255Round(rc); 273f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 274f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int tmp = (dc * sa << 15) / (da * diff); 275f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = SkDiv255Round(sa * da) * tmp >> 15; 276f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // don't clamp here, since we'll do it in our modeproc 277f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 278f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return rc; 279f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 280f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 281f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // added to avoid div-by-zero in colordodge_byte 282f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 == dst) { 283f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return src; 284f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 285f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 286f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 287f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 288f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 289f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 290f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 291f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 292f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger r = clamp_max(r, a); 293f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger g = clamp_max(g, a); 294f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger b = clamp_max(b, a); 295f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 296f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 297f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 298f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kColorBurn_Mode 299f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int colorburn_byte(int sc, int dc, int sa, int da) { 300f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int rc; 301f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (dc == da && 0 == sc) { 302f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = sa * da + dc * (255 - sa); 303f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (0 == sc) { 304f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkAlphaMulAlpha(dc, 255 - sa); 305f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 306f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int tmp = (sa * (da - dc) * 256) / (sc * da); 307f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (tmp > 256) { 308f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger tmp = 256; 309f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 310f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int tmp2 = sa * da; 311f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa); 312f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 313f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkDiv255Round(rc); 314f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 315f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 316f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // added to avoid div-by-zero in colorburn_byte 317f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 == dst) { 318f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return src; 319f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 320f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 321f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 322f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 323f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 324f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 325f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 326f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 327f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 328f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 329f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 330f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kHardLight_Mode 331f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int hardlight_byte(int sc, int dc, int sa, int da) { 332f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int rc; 333f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (2 * sc <= sa) { 334f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = 2 * sc * dc; 335f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 336f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = sa * da - 2 * (da - dc) * (sa - sc); 337f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 338f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 339f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 340f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 341f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 342f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 343f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 344f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 345f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 346f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 347f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 348f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 349f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 350f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// returns 255 * sqrt(n/255) 351f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic U8CPU sqrt_unit_byte(U8CPU n) { 352f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkSqrtBits(n, 15+4); 353f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 354f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 355f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kSoftLight_Mode 356f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int softlight_byte(int sc, int dc, int sa, int da) { 357f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int m = da ? dc * 256 / da : 0; 358f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int rc; 359f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (2 * sc <= sa) { 360f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 361f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (4 * dc <= da) { 362f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 363f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 364f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 365f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int tmp = sqrt_unit_byte(m) - m; 366f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 367f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 368f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 369f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 370f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 371f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 372f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 373f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 374f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 375f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 376f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 377f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 378f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 379f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 380f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kDifference_Mode 381f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int difference_byte(int sc, int dc, int sa, int da) { 382f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int tmp = SkMin32(sc * da, dc * sa); 383f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 384f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 385f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 386f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 387f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 388f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 389f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 390f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 391f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 392f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 393f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 394f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 395f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger// kExclusion_Mode 396f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic inline int exclusion_byte(int sc, int dc, int sa, int da) { 397f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // this equations is wacky, wait for SVG to confirm it 398f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 399f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return clamp_div255round(r); 400f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 401f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 402f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int sa = SkGetPackedA32(src); 403f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int da = SkGetPackedA32(dst); 404f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int a = srcover_byte(sa, da); 405f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 406f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 407f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 408f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackARGB32(a, r, g, b); 409f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 410f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 411f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstruct ProcCoeff { 412f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc fProc; 413f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermode::Coeff fSC; 414f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermode::Coeff fDC; 415f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 416f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 417f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#define CANNOT_USE_COEFF SkXfermode::Coeff(-1) 418f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 419f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic const ProcCoeff gProcCoeffs[] = { 420f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 421f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 422f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 423f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 424f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 425f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 426f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 427f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 428f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 429f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 430f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 431f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 432f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 433f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 434f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { multiply_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 435f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { screen_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 436f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 437f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 438f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 439f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 440f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 441f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 442f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 443f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 444f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 445f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 446f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 447f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 448f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 449f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkXfermode::asCoeff(Coeff* src, Coeff* dst) { 450f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 451f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 452f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 453f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkXfermode::asMode(Mode* mode) { 454f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 455f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 456f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 457f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) { 458f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // no-op. subclasses should override this 459f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 460f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 461f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 462f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 463f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 464f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 465f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 466f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 467f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 468f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 469f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = this->xferColor(src[i], dst[i]); 470f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 471f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 472f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 473f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 474f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 475f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = dst[i]; 476f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor C = this->xferColor(src[i], dstC); 477f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF != a) { 478f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger C = SkFourByteInterp(C, dstC, a); 479f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 480f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = C; 481f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 482f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 483f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 484f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 485f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 486f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkXfermode::xfer16(uint16_t* dst, 487f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 488f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 489f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 490f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 491f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 492f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 493f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 494f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 495f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 496f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 497f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 498f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 499f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 500f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 501f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor C = this->xferColor(src[i], dstC); 502f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF != a) { 503f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger C = SkFourByteInterp(C, dstC, a); 504f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 505f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkPixel32ToPixel16_ToU16(C); 506f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 507f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 508f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 509f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 510f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 511f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 512f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 513f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) 514f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 515f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 516f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 517f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 518f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 519f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 520f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkPixel32ToPixel4444(this->xferColor(src[i], dstC)); 521f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 522f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 523f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 524f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 525f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 526f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 527f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor C = this->xferColor(src[i], dstC); 528f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF != a) { 529f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger C = SkFourByteInterp(C, dstC, a); 530f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 531f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkPixel32ToPixel4444(C); 532f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 533f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 534f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 535f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 536f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 537f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 538f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor src[], int count, 539f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) 540f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger{ 541f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 542f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 543f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 544f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 545f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 546f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkToU8(SkGetPackedA32(res)); 547f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 548f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 549f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 550f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 551f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 552f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlpha dstA = dst[i]; 553f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned A = SkGetPackedA32(this->xferColor(src[i], 554f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger (SkPMColor)(dstA << SK_A32_SHIFT))); 555f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF != a) { 556f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 557f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 558f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkToU8(A); 559f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 560f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 561f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 562f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 563f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 564f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 565f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 566f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkProcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 567f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 568f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 569f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 570f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 571f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc proc = fProc; 572f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 573f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != proc) { 574f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 575f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 576f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = proc(src[i], dst[i]); 577f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 578f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 579f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 580f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 581f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 582f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = dst[i]; 583f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor C = proc(src[i], dstC); 584f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (a != 0xFF) { 585f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger C = SkFourByteInterp(C, dstC, a); 586f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 587f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = C; 588f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 589f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 590f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 591f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 592f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 593f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 594f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkProcXfermode::xfer16(uint16_t* SK_RESTRICT dst, 595f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 596f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 597f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 598f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 599f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc proc = fProc; 600f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 601f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != proc) { 602f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 603f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 604f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 605f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 606f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 607f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 608f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 609f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 610f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 611f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 612f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor C = proc(src[i], dstC); 613f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF != a) { 614f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger C = SkFourByteInterp(C, dstC, a); 615f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 616f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkPixel32ToPixel16_ToU16(C); 617f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 618f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 619f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 620f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 621f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 622f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 623f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkProcXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 624f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 625f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 626f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 627f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 628f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc proc = fProc; 629f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 630f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != proc) { 631f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 632f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 633f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 634f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkPixel32ToPixel4444(proc(src[i], dstC)); 635f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 636f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 637f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 638f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 639f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 640f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 641f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor C = proc(src[i], dstC); 642f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF != a) { 643f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger C = SkFourByteInterp(C, dstC, a); 644f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 645f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkPixel32ToPixel4444(C); 646f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 647f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 648f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 649f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 650f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 651f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 652f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkProcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 653f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 654f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 655f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 656f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 657f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc proc = fProc; 658f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 659f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != proc) { 660f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 661f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 662f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 663f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkToU8(SkGetPackedA32(res)); 664f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 665f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 666f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 667f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 668f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 669f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkAlpha dstA = dst[i]; 670f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 671f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned A = SkGetPackedA32(res); 672f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF != a) { 673f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 674f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 675f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkToU8(A); 676f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 677f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 678f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 679f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 680f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 681f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 682f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkProcXfermode::SkProcXfermode(SkFlattenableReadBuffer& buffer) 683f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : SkXfermode(buffer) { 684f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // Might be a NULL if the Xfermode is recorded using the CrossProcess flag 685f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fProc = (SkXfermodeProc)buffer.readFunctionPtr(); 686f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 687f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 688f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkProcXfermode::flatten(SkFlattenableWriteBuffer& buffer) { 689f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (buffer.isCrossProcess()) { 690f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // function pointer is only valid in the current process. Write a NULL 691f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // so it can't be accidentally used 692f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger buffer.writeFunctionPtr(NULL); 693f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 694f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger buffer.writeFunctionPtr((void*)fProc); 695f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 696f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 697f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 698f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 699f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 700f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 701f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SkProcCoeffXfermode : public SkProcXfermode { 702f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 703f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) 704f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : INHERITED(rec.fProc) { 705f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fMode = mode; 706f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // these may be valid, or may be CANNOT_USE_COEFF 707f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fSrcCoeff = rec.fSC; 708f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fDstCoeff = rec.fDC; 709f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 710f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 711f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual bool asMode(Mode* mode) { 712f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (mode) { 713f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *mode = fMode; 714f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 715f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 716f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 717f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 718f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual bool asCoeff(Coeff* sc, Coeff* dc) { 719f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (CANNOT_USE_COEFF == fSrcCoeff) { 720f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 721f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 722f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 723f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (sc) { 724f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *sc = fSrcCoeff; 725f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 726f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (dc) { 727f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *dc = fDstCoeff; 728f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 729f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 730f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 731f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 732f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual Factory getFactory() { return CreateProc; } 733f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void flatten(SkFlattenableWriteBuffer& buffer) { 734f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger this->INHERITED::flatten(buffer); 735f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger buffer.write32(fMode); 736f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 737f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 738f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 739f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkProcCoeffXfermode, (buffer)); 740f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 741f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 742f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprotected: 743f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) 744f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : INHERITED(buffer) { 745f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fMode = (SkXfermode::Mode)buffer.readU32(); 746f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 747f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (buffer.getPictureVersion() == PICTURE_VERSION_ICS) { 748f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fSrcCoeff = (Coeff)buffer.readU32(); 749f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fDstCoeff = (Coeff)buffer.readU32(); 750f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return; 751f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 752f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 753f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const ProcCoeff& rec = gProcCoeffs[fMode]; 754f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // these may be valid, or may be CANNOT_USE_COEFF 755f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fSrcCoeff = rec.fSC; 756f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger fDstCoeff = rec.fDC; 757f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // now update our function-ptr in the super class 758f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger this->INHERITED::setProc(rec.fProc); 759f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 760f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 761f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 762f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Mode fMode; 763f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Coeff fSrcCoeff, fDstCoeff; 764f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 765f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 766f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger typedef SkProcXfermode INHERITED; 767f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 768f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 769f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 770f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 771f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SkClearXfermode : public SkProcCoeffXfermode { 772f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 773f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} 774f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 775f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 776f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 777f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 778f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 779f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 780f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkClearXfermode, (buffer)); 781f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 782f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 783f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 784f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkClearXfermode(SkFlattenableReadBuffer& buffer) 785f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : SkProcCoeffXfermode(buffer) {} 786f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 787f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 788f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 789f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 790f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT, int count, 791f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 792f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && count >= 0); 793f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 794f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 795f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger memset(dst, 0, count << 2); 796f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 797f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 798f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 799f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF == a) { 800f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = 0; 801f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (a != 0) { 802f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); 803f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 804f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 805f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 806f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 807f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 808f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT, int count, 809f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 810f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && count >= 0); 811f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 812f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 813f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger memset(dst, 0, count); 814f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 815f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 816f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 817f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0xFF == a) { 818f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = 0; 819f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (0 != a) { 820f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); 821f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 822f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 823f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 824f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 825f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 826f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 827f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 828f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SkSrcXfermode : public SkProcCoeffXfermode { 829f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 830f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} 831f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 832f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 833f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 834f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 835f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 836f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 837f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkSrcXfermode, (buffer)); 838f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 839f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 840f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 841f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkSrcXfermode(SkFlattenableReadBuffer& buffer) 842f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : SkProcCoeffXfermode(buffer) {} 843f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 844f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 845f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 846f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 847f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 848f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 849f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 850f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 851f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 852f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger memcpy(dst, src, count << 2); 853f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 854f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 855f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 856f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (a == 0xFF) { 857f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = src[i]; 858f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (a != 0) { 859f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkFourByteInterp(src[i], dst[i], a); 860f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 861f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 862f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 863f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 864f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 865f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 866f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 867f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 868f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src && count >= 0); 869f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 870f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == aa) { 871f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 872f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkToU8(SkGetPackedA32(src[i])); 873f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 874f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 875f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 876f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = aa[i]; 877f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 != a) { 878f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned srcA = SkGetPackedA32(src[i]); 879f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (a == 0xFF) { 880f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkToU8(srcA); 881f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 882f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); 883f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 884f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 885f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 886f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 887f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 888f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 889f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger//////////////////////////////////////////////////////////////////////////////////// 890f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 891f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SkDstInXfermode : public SkProcCoeffXfermode { 892f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 893f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} 894f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 895f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 896f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 897f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 898f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 899f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkDstInXfermode, (buffer)); 900f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 901f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 902f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 903f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDstInXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 904f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 905f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger typedef SkProcCoeffXfermode INHERITED; 906f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 907f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 908f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 909f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 910f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 911f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src); 912f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 913f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (count <= 0) { 914f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return; 915f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 916f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != aa) { 917f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return this->INHERITED::xfer32(dst, src, count, aa); 918f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 919f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 920f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 921f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = SkGetPackedA32(*src); 922f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); 923f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst++; 924f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src++; 925f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--count != 0); 926f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 927f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 928f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger///////////////////////////////////////////////////////////////////////////////////////// 929f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 930f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerclass SkDstOutXfermode : public SkProcCoeffXfermode { 931f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerpublic: 932f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} 933f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 934f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 935f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 936f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 937f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 938f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkDstOutXfermode, (buffer)); 939f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 940f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 941f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerprivate: 942f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkDstOutXfermode(SkFlattenableReadBuffer& buffer) 943f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger : INHERITED(buffer) {} 944f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 945f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger typedef SkProcCoeffXfermode INHERITED; 946f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 947f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 948f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergervoid SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 949f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 950f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 951f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(dst && src); 952f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 953f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (count <= 0) { 954f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return; 955f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 956f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL != aa) { 957f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return this->INHERITED::xfer32(dst, src, count, aa); 958f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 959f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 960f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger do { 961f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = SkGetPackedA32(*src); 962f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); 963f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger dst++; 964f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger src++; 965f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } while (--count != 0); 966f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 967f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 968f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 969f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 970f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkXfermode* SkXfermode::Create(Mode mode) { 971f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 972f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT((unsigned)mode < kModeCount); 973f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 974f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const ProcCoeff& rec = gProcCoeffs[mode]; 975f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 976f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger switch (mode) { 977f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger case kClear_Mode: 978f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkClearXfermode, (rec)); 979f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger case kSrc_Mode: 980f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkSrcXfermode, (rec)); 981f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger case kSrcOver_Mode: 982f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return NULL; 983f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger case kDstIn_Mode: 984f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkDstInXfermode, (rec)); 985f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger case kDstOut_Mode: 986f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkDstOutXfermode, (rec)); 987f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger default: 988f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 989f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 990f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 991f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 992f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkXfermodeProc SkXfermode::GetProc(Mode mode) { 993f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc proc = NULL; 994f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((unsigned)mode < kModeCount) { 995f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger proc = gProcCoeffs[mode].fProc; 996f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 997f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return proc; 998f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 999f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1000f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 1001f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 1002f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1003f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((unsigned)mode >= (unsigned)kModeCount) { 1004f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // illegal mode parameter 1005f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 1006f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1007f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1008f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const ProcCoeff& rec = gProcCoeffs[mode]; 1009f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1010f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (CANNOT_USE_COEFF == rec.fSC) { 1011f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 1012f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1013f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1014f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(CANNOT_USE_COEFF != rec.fDC); 1015f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (src) { 1016f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *src = rec.fSC; 1017f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1018f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (dst) { 1019f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *dst = rec.fDC; 1020f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1021f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 1022f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1023f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1024f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkXfermode::AsMode(SkXfermode* xfer, Mode* mode) { 1025f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == xfer) { 1026f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (mode) { 1027f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger *mode = kSrcOver_Mode; 1028f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1029f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return true; 1030f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1031f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return xfer->asMode(mode); 1032f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1033f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1034f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkXfermode::AsCoeff(SkXfermode* xfer, Coeff* src, Coeff* dst) { 1035f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (NULL == xfer) { 1036f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return ModeAsCoeff(kSrcOver_Mode, src, dst); 1037f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1038f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return xfer->asCoeff(src, dst); 1039f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1040f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1041f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerbool SkXfermode::IsMode(SkXfermode* xfer, Mode mode) { 1042f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger // if xfer==null then the mode is srcover 1043f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger Mode m = kSrcOver_Mode; 1044f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (xfer && !xfer->asMode(&m)) { 1045f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return false; 1046f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1047f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return mode == m; 1048f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1049f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1050f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1051f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger//////////// 16bit xfermode procs 1052f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1053f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#ifdef SK_DEBUG 1054f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; } 1055f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; } 1056f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger#endif 1057f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1058f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) { 1059f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1060f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPixel32ToPixel16(src); 1061f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1062f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1063f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) { 1064f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1065f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1066f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1067f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) { 1068f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_0(src)); 1069f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1070f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1071f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1072f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) { 1073f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1074f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPixel32ToPixel16(src); 1075f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1076f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1077f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) { 1078f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_0(src)); 1079f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1080f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1081f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1082f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) { 1083f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1084f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1085f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1086f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1087f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) { 1088f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1089f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPixel32ToPixel16(src); 1090f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1091f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1092f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) { 1093f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1094f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1095f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1096f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1097f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) { 1098f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_0(src)); 1099f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1100f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1101f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1102f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) { 1103f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned isa = 255 - SkGetPackedA32(src); 1104f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1105f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackRGB16( 1106f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa), 1107f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa), 1108f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa)); 1109f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1110f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1111f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) { 1112f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_0(src)); 1113f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1114f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1115f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1116f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) { 1117f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1118f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPixel32ToPixel16(src); 1119f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1120f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1121f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) { 1122f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1123f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1124f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1125f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1126f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger/********* 1127f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger darken and lighten boil down to this. 1128f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1129f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger darken = (1 - Sa) * Dc + min(Sc, Dc) 1130f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger lighten = (1 - Sa) * Dc + max(Sc, Dc) 1131f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1132f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (Sa == 0) these become 1133f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger darken = Dc + min(0, Dc) = 0 1134f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger lighten = Dc + max(0, Dc) = Dc 1135f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1136f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (Sa == 1) these become 1137f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger darken = min(Sc, Dc) 1138f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger lighten = max(Sc, Dc) 1139f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger*/ 1140f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1141f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) { 1142f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_0(src)); 1143f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return 0; 1144f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1145f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1146f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) { 1147f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1148f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 1149f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 1150f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 1151f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackRGB16(r, g, b); 1152f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1153f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1154f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) { 1155f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_0(src)); 1156f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return dst; 1157f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1158f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1159f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) { 1160f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkASSERT(require_255(src)); 1161f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 1162f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 1163f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 1164f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return SkPackRGB16(r, g, b); 1165f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1166f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1167f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstruct Proc16Rec { 1168f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc16 fProc16_0; 1169f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc16 fProc16_255; 1170f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc16 fProc16_General; 1171f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 1172f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1173f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenbergerstatic const Proc16Rec gModeProcs16[] = { 1174f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // CLEAR 1175f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, src_modeproc16_255, NULL }, 1176f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { dst_modeproc16, dst_modeproc16, dst_modeproc16 }, 1177f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { srcover_modeproc16_0, srcover_modeproc16_255, NULL }, 1178f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { dstover_modeproc16_0, dstover_modeproc16_255, NULL }, 1179f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, srcin_modeproc16_255, NULL }, 1180f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, dstin_modeproc16_255, NULL }, 1181f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL },// SRC_OUT 1182f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { dstout_modeproc16_0, NULL, NULL }, 1183f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 }, 1184f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, dstatop_modeproc16_255, NULL }, 1185f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // XOR 1186f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1187f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // plus 1188f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // multiply 1189f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // screen 1190f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // overlay 1191f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken 1192f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten 1193f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // colordodge 1194f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // colorburn 1195f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // hardlight 1196f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // softlight 1197f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // difference 1198f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger { NULL, NULL, NULL }, // exclusion 1199f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger}; 1200f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1201f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { 1202f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SkXfermodeProc16 proc16 = NULL; 1203f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if ((unsigned)mode < kModeCount) { 1204f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger const Proc16Rec& rec = gModeProcs16[mode]; 1205f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger unsigned a = SkColorGetA(srcColor); 1206f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1207f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger if (0 == a) { 1208f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger proc16 = rec.fProc16_0; 1209f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else if (255 == a) { 1210f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger proc16 = rec.fProc16_255; 1211f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } else { 1212f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger proc16 = rec.fProc16_General; 1213f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1214f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger } 1215f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger return proc16; 1216f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger} 1217f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger 1218f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1219f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1220f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) 1221f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) 1222f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) 1223f8cacf6b11e35785df8efb613b0c3592d535f603Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) 1224f8cacf6b11e35785df8efb613b0c3592d535f603Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1225