11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// idea for higher precision blends in xfer procs (and slightly faster) 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// see DstATop as a probable caller 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) { 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(a <= 255); 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(b <= 255); 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(c <= 255); 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(d <= 255); 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned prod = SkMulS16(a, b) + SkMulS16(c, d) + 128; 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned result = (prod + (prod >> 8)) >> 8; 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(result <= 255); 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return result; 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 30fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reedstatic inline unsigned saturated_add(unsigned a, unsigned b) { 31eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed SkASSERT(a <= 255); 32eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed SkASSERT(b <= 255); 33eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed unsigned sum = a + b; 34eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed if (sum > 255) { 35eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed sum = 255; 36eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed } 37eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed return sum; 38eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed} 39eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed 40fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reedstatic inline int clamp_signed_byte(int n) { 419f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed if (n < 0) { 429f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed n = 0; 439f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } else if (n > 255) { 449f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed n = 255; 459f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 469f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return n; 479f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 489f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed 49fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reedstatic inline int clamp_div255round(int prod) { 509f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed if (prod <= 0) { 519f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return 0; 529f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } else if (prod >= 255*255) { 539f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return 255; 549f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } else { 559f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return SkDiv255Round(prod); 569f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 579f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 589f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed 59fadb93e0b43c7451032c46f3c58a1effa9d681b3Mike Reedstatic inline int clamp_max(int value, int max) { 609f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed if (value > max) { 619f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed value = max; 629f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 639f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return value; 649f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 659f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kClear_Mode, //!< [0, 0] 6940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) { 7040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return 0; 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kSrc_Mode, //!< [Sa, Sc] 7440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) { 7540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return src; 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kDst_Mode, //!< [Da, Dc] 7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) { 8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return dst; 8140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger// kSrcOver_Mode, //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc] 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) { 8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#if 0 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // this is the old, more-correct way, but it doesn't guarantee that dst==255 8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // will always stay opaque 8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#else 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // this is slightly faster, but more importantly guarantees that dst==255 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // will always stay opaque 9240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src)); 9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kDstOver_Mode, //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc] 9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) { 9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // this is the reverse of srcover, just flipping src and dst 9940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // see srcover's comment about the 256 for opaqueness guarantees 10040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst)); 10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kSrcIn_Mode, //!< [Sa * Da, Sc * Da] 10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) { 10540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst))); 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kDstIn_Mode, //!< [Sa * Da, Sa * Dc] 10940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) { 11040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src))); 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)] 11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) { 11540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst))); 11640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)] 11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) { 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] 12440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) { 12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned sa = SkGetPackedA32(src); 12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned da = SkGetPackedA32(dst); 12740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned isa = 255 - sa; 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(da, 13040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(da, SkGetPackedR32(src)) + 13140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 13240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(da, SkGetPackedG32(src)) + 13340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 13440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(da, SkGetPackedB32(src)) + 13540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 13640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)] 13940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) { 14040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned sa = SkGetPackedA32(src); 14140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned da = SkGetPackedA32(dst); 14240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned ida = 255 - da; 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(sa, 14540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 14640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(sa, SkGetPackedR32(dst)), 14740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 14840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(sa, SkGetPackedG32(dst)), 14940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 15040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(sa, SkGetPackedB32(dst))); 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] 15440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) { 15540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned sa = SkGetPackedA32(src); 15640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned da = SkGetPackedA32(dst); 15740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned isa = 255 - sa; 15840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned ida = 255 - da; 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1), 16140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedR32(src)) + 16240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedR32(dst)), 16340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedG32(src)) + 16440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedG32(dst)), 16540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(ida, SkGetPackedB32(src)) + 16640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlphaMulAlpha(isa, SkGetPackedB32(dst))); 16740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 17040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 17140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kPlus_Mode 17240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) { 17340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst)); 17440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst)); 17540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst)); 17640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst)); 17740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(a, r, g, b); 1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kMultiply_Mode 18140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) { 18240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst)); 18340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst)); 18440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst)); 18540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst)); 18640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(a, r, g, b); 18740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1899f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed// kScreen_Mode 1909f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic inline int srcover_byte(int a, int b) { 1919f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return a + b - SkAlphaMulAlpha(a, b); 1929f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 1939f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) { 1949f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst)); 1959f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst)); 1969f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst)); 1979f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst)); 1989f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return SkPackARGB32(a, r, g, b); 1999f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 2009f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed 2019f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed// kOverlay_Mode 2029f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic inline int overlay_byte(int sc, int dc, int sa, int da) { 2039f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int tmp = sc * (255 - da) + dc * (255 - sa); 2049f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int rc; 2059f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed if (2 * dc <= da) { 2069f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed rc = 2 * sc * dc; 2079f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } else { 2089f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed rc = sa * da - 2 * (da - dc) * (sa - sc); 2099f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 2109f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return clamp_div255round(rc + tmp); 2119f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 2129f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) { 2139f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int sa = SkGetPackedA32(src); 2149f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int da = SkGetPackedA32(dst); 2159f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int a = srcover_byte(sa, da); 2169f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 2179f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 2189f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 2199f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return SkPackARGB32(a, r, g, b); 2209f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 2219f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed 2229f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed// kDarken_Mode 2239f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic inline int darken_byte(int sc, int dc, int sa, int da) { 2249f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int sd = sc * da; 2259f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int ds = dc * sa; 2269f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed if (sd < ds) { 2279f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed // srcover 2289f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return sc + dc - SkDiv255Round(ds); 2299f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } else { 2309f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed // dstover 2319f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return dc + sc - SkDiv255Round(sd); 2329f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 2339f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) { 2359f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int sa = SkGetPackedA32(src); 2369f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int da = SkGetPackedA32(dst); 2379f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int a = srcover_byte(sa, da); 2389f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 2399f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 2409f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 2419f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return SkPackARGB32(a, r, g, b); 2429f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2449f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed// kLighten_Mode 2459f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic inline int lighten_byte(int sc, int dc, int sa, int da) { 2469f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int sd = sc * da; 2479f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int ds = dc * sa; 2489f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed if (sd > ds) { 2499f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed // srcover 2509f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return sc + dc - SkDiv255Round(ds); 2519f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } else { 2529f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed // dstover 2539f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return dc + sc - SkDiv255Round(sd); 2549f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 2559f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 2569f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) { 2579f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int sa = SkGetPackedA32(src); 2589f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int da = SkGetPackedA32(dst); 2599f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int a = srcover_byte(sa, da); 2609f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 2619f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 2629f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 2639f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed return SkPackARGB32(a, r, g, b); 2649f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2669f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed// kColorDodge_Mode 2679f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic inline int colordodge_byte(int sc, int dc, int sa, int da) { 2689f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int diff = sa - sc; 2699f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int rc; 2709f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed if (0 == diff) { 2719f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed rc = sa * da + sc * (255 - da) + dc * (255 - sa); 2729f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed rc = SkDiv255Round(rc); 2739f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } else { 2749f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed int tmp = (dc * sa << 15) / (da * diff); 2759f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed rc = SkDiv255Round(sa * da) * tmp >> 15; 2769f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed // don't clamp here, since we'll do it in our modeproc 2779f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 27840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return rc; 27940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 28040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) { 28140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // added to avoid div-by-zero in colordodge_byte 28240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == dst) { 28340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return src; 28440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 28540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 28640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int sa = SkGetPackedA32(src); 28740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int da = SkGetPackedA32(dst); 28840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int a = srcover_byte(sa, da); 28940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 29040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 29140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 29240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger r = clamp_max(r, a); 29340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger g = clamp_max(g, a); 29440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger b = clamp_max(b, a); 29540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(a, r, g, b); 29640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 29740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 29840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kColorBurn_Mode 29940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline int colorburn_byte(int sc, int dc, int sa, int da) { 30040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int rc; 30140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (dc == da && 0 == sc) { 30240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rc = sa * da + dc * (255 - sa); 30340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else if (0 == sc) { 30440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkAlphaMulAlpha(dc, 255 - sa); 30540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 30640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int tmp = (sa * (da - dc) * 256) / (sc * da); 30740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (tmp > 256) { 30840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger tmp = 256; 30940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 31040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int tmp2 = sa * da; 31140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rc = tmp2 - (tmp2 * tmp >> 8) + sc * (255 - da) + dc * (255 - sa); 31240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 31340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkDiv255Round(rc); 31440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 31540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) { 31640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // added to avoid div-by-zero in colorburn_byte 31740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == dst) { 31840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return src; 31940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 32035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 32140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int sa = SkGetPackedA32(src); 32240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int da = SkGetPackedA32(dst); 32340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int a = srcover_byte(sa, da); 32440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 32540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 32640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 32740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(a, r, g, b); 32840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 32940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 33040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kHardLight_Mode 33140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline int hardlight_byte(int sc, int dc, int sa, int da) { 33240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int rc; 33340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (2 * sc <= sa) { 33440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rc = 2 * sc * dc; 33540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 33640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rc = sa * da - 2 * (da - dc) * (sa - sc); 33740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 33840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 33940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 34040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) { 34140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int sa = SkGetPackedA32(src); 34240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int da = SkGetPackedA32(dst); 34340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int a = srcover_byte(sa, da); 34440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 34540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 34640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 34740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(a, r, g, b); 34840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 34940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 35040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// returns 255 * sqrt(n/255) 35140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic U8CPU sqrt_unit_byte(U8CPU n) { 35240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkSqrtBits(n, 15+4); 35340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 35440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 35540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kSoftLight_Mode 35640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline int softlight_byte(int sc, int dc, int sa, int da) { 35740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int m = da ? dc * 256 / da : 0; 35840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int rc; 35940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (2 * sc <= sa) { 36040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8)); 36140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else if (4 * dc <= da) { 36240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m; 36340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 36440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 36540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int tmp = sqrt_unit_byte(m) - m; 36640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8); 36740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 36840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa)); 36940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 37040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) { 37140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int sa = SkGetPackedA32(src); 37240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int da = SkGetPackedA32(dst); 37340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int a = srcover_byte(sa, da); 37440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 37540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 37640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 37740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(a, r, g, b); 37840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 37940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 38040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kDifference_Mode 38140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline int difference_byte(int sc, int dc, int sa, int da) { 38240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int tmp = SkMin32(sc * da, dc * sa); 38340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp)); 38440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 38540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) { 38640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int sa = SkGetPackedA32(src); 38740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int da = SkGetPackedA32(dst); 38840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int a = srcover_byte(sa, da); 38940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 39040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 39140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 39240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(a, r, g, b); 39340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 39440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 39540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// kExclusion_Mode 39640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic inline int exclusion_byte(int sc, int dc, int sa, int da) { 39740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // this equations is wacky, wait for SVG to confirm it 39840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa); 39940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return clamp_div255round(r); 40040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 40140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) { 40240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int sa = SkGetPackedA32(src); 40340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int da = SkGetPackedA32(dst); 40440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int a = srcover_byte(sa, da); 40540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da); 40640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da); 40740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da); 40840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkPackARGB32(a, r, g, b); 40940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 41040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 41140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstruct ProcCoeff { 41240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkXfermodeProc fProc; 41340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkXfermode::Coeff fSC; 41440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkXfermode::Coeff fDC; 41540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 41640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 41740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#define CANNOT_USE_COEFF SkXfermode::Coeff(-1) 41840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 41940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const ProcCoeff gProcCoeffs[] = { 42040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, 42140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, 42240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, 42340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, 42440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, 42540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, 42640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, 42740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, 42840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, 42940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, 43040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff }, 43140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, 43240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 43387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, 43487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger { multiply_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff }, 43540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { screen_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 43640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 43740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 43840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 43940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }, 44540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 44640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 44740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 44840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 44940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerbool SkXfermode::asCoeff(Coeff* src, Coeff* dst) { 45040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return false; 45140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 45240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 45340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerbool SkXfermode::asMode(Mode* mode) { 45435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return false; 45540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 45640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 45740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) { 45840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // no-op. subclasses should override this 45940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return dst; 46040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 46140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 4641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 46540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(dst && src && count >= 0); 46640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 46740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == aa) { 46840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 46940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = this->xferColor(src[i], dst[i]); 47040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 47140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 47240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 47340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = aa[i]; 47440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 != a) { 47540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = dst[i]; 47640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor C = this->xferColor(src[i], dstC); 47740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0xFF != a) { 47840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger C = SkFourByteInterp(C, dstC, a); 47940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 48040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = C; 48140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 48240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 48340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 48440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 48540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkXfermode::xfer16(uint16_t* dst, 4871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 4881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 48940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(dst && src && count >= 0); 49040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 49140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == aa) { 49240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 49340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 49440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC)); 49540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 49640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 49740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 49840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = aa[i]; 49940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 != a) { 50040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 50140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor C = this->xferColor(src[i], dstC); 50240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0xFF != a) { 50340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger C = SkFourByteInterp(C, dstC, a); 50440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 50540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkPixel32ToPixel16_ToU16(C); 50640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 50740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 50840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 50940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 51040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 5121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 5131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) 51440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger{ 51540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(dst && src && count >= 0); 51635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 51740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == aa) { 51840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 51940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 52040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkPixel32ToPixel4444(this->xferColor(src[i], dstC)); 52140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 52240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 52340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 52440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = aa[i]; 52540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 != a) { 52640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 52740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor C = this->xferColor(src[i], dstC); 52840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0xFF != a) { 52940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger C = SkFourByteInterp(C, dstC, a); 53040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 53140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkPixel32ToPixel4444(C); 53240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 53340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 53440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 53540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 53640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 53840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkPMColor src[], int count, 5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) 54040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger{ 54140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(dst && src && count >= 0); 54240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 54340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == aa) { 54440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 54540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT)); 54640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkToU8(SkGetPackedA32(res)); 54740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 54840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 54940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 55040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = aa[i]; 55140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 != a) { 55240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlpha dstA = dst[i]; 55340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned A = SkGetPackedA32(this->xferColor(src[i], 55440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger (SkPMColor)(dstA << SK_A32_SHIFT))); 55540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0xFF != a) { 55640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 55740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 55840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkToU8(A); 55940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 56040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 56140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 56240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 56340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 56440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 56540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkProcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 5671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 5681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 56940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(dst && src && count >= 0); 57040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 57140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkXfermodeProc proc = fProc; 57240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 57340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL != proc) { 57440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == aa) { 57540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 57640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = proc(src[i], dst[i]); 57740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 57840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 57940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 58040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = aa[i]; 58140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 != a) { 58240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = dst[i]; 58340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor C = proc(src[i], dstC); 58440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (a != 0xFF) { 58540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger C = SkFourByteInterp(C, dstC, a); 58640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 58740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = C; 58840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 58940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 59040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 59140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 59240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 59340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkProcXfermode::xfer16(uint16_t* SK_RESTRICT dst, 5951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 5961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 59740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(dst && src && count >= 0); 59840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 59940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkXfermodeProc proc = fProc; 60040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 60140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL != proc) { 60240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == aa) { 60340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 60440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 60540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); 60640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 60740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 60840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 60940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = aa[i]; 61040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 != a) { 61140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = SkPixel16ToPixel32(dst[i]); 61240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor C = proc(src[i], dstC); 61340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0xFF != a) { 61440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger C = SkFourByteInterp(C, dstC, a); 61540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 61640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkPixel32ToPixel16_ToU16(C); 61740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 61840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 61940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 62040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkProcXfermode::xfer4444(SkPMColor16* SK_RESTRICT dst, 6241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 6251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 62640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(dst && src && count >= 0); 62735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 62840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkXfermodeProc proc = fProc; 6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 63040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL != proc) { 63140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == aa) { 63240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 63340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 63440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkPixel32ToPixel4444(proc(src[i], dstC)); 63540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 63640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 63740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 63840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = aa[i]; 63940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 != a) { 64040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); 64140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor C = proc(src[i], dstC); 64240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0xFF != a) { 64340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger C = SkFourByteInterp(C, dstC, a); 64440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 64540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkPixel32ToPixel4444(C); 64640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 64740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6489f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 6499f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 6509f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed} 6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkProcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 6531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 6541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 65540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(dst && src && count >= 0); 65640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 65740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkXfermodeProc proc = fProc; 65840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 65940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL != proc) { 66040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == aa) { 66140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 66240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT); 66340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkToU8(SkGetPackedA32(res)); 66440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 66540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 66640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = count - 1; i >= 0; --i) { 66740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned a = aa[i]; 66840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 != a) { 66940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAlpha dstA = dst[i]; 67040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT); 67140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger unsigned A = SkGetPackedA32(res); 67240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0xFF != a) { 67340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 67440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 67540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger dst[i] = SkToU8(A); 67640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 67740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 67840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6799f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed } 6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 68140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 68240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkProcXfermode::SkProcXfermode(SkFlattenableReadBuffer& buffer) 68340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : SkXfermode(buffer) { 6841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Might be a NULL if the Xfermode is recorded using the CrossProcess flag 68540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fProc = (SkXfermodeProc)buffer.readFunctionPtr(); 6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 68840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkProcXfermode::flatten(SkFlattenableWriteBuffer& buffer) { 6891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (buffer.isCrossProcess()) { 6901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // function pointer is only valid in the current process. Write a NULL 6911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // so it can't be accidentally used 6921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger buffer.writeFunctionPtr(NULL); 6931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 6941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger buffer.writeFunctionPtr((void*)fProc); 6951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 69840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 69940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 7009f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed 70140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerclass SkProcCoeffXfermode : public SkProcXfermode { 70240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerpublic: 70335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) 70435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : INHERITED(rec.fProc) { 70535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fMode = mode; 70635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // these may be valid, or may be CANNOT_USE_COEFF 70735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fSrcCoeff = rec.fSC; 70835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fDstCoeff = rec.fDC; 70940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 71035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 71135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger virtual bool asMode(Mode* mode) { 71235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (mode) { 71335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger *mode = fMode; 71435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 71535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return true; 71635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 71735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 71840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual bool asCoeff(Coeff* sc, Coeff* dc) { 71935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (CANNOT_USE_COEFF == fSrcCoeff) { 72035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return false; 72135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 72235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 72340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (sc) { 72440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger *sc = fSrcCoeff; 72540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 72640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (dc) { 72740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger *dc = fDstCoeff; 72840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 72940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return true; 73040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 73135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 73240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual Factory getFactory() { return CreateProc; } 73340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual void flatten(SkFlattenableWriteBuffer& buffer) { 73440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->INHERITED::flatten(buffer); 73535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger buffer.write32(fMode); 73640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 73740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 73835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 73935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(SkProcCoeffXfermode, (buffer)); 74035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 74135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 74240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprotected: 74340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) 74440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : INHERITED(buffer) { 74535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger fMode = (SkXfermode::Mode)buffer.readU32(); 7461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 7474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (buffer.getPictureVersion() == PICTURE_VERSION_ICS) { 7484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fSrcCoeff = (Coeff)buffer.readU32(); 7494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fDstCoeff = (Coeff)buffer.readU32(); 7504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return; 7514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 7524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 7531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const ProcCoeff& rec = gProcCoeffs[fMode]; 7541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // these may be valid, or may be CANNOT_USE_COEFF 7551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fSrcCoeff = rec.fSC; 7561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fDstCoeff = rec.fDC; 7571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // now update our function-ptr in the super class 7581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->INHERITED::setProc(rec.fProc); 75940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 76035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 76140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprivate: 76235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger Mode fMode; 76340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Coeff fSrcCoeff, fDstCoeff; 76435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 76540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 76640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger typedef SkProcXfermode INHERITED; 76740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 768eba9f316916f3381d6a5dd5c1300fea6ec6da8dcMike Reed 7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkClearXfermode : public SkProcCoeffXfermode { 7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 77335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} 7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 7761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 7771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkClearXfermode, (buffer)); 7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 78235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 78335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate: 78435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkClearXfermode(SkFlattenableReadBuffer& buffer) 78535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : SkProcCoeffXfermode(buffer) {} 78635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 7901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT, int count, 7911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 7921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst && count >= 0); 7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == aa) { 7951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memset(dst, 0, count << 2); 7961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 7971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 7981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned a = aa[i]; 7991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0xFF == a) { 8001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = 0; 8011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (a != 0) { 8021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a)); 8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 8081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT, int count, 8091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 8101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst && count >= 0); 8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == aa) { 8131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memset(dst, 0, count); 8141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 8151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 8161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned a = aa[i]; 8171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0xFF == a) { 8181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = 0; 8191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (0 != a) { 8201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkAlphaMulAlpha(dst[i], 255 - a); 8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 82535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 8261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 8271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass SkSrcXfermode : public SkProcCoeffXfermode { 8291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic: 8301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} 8311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 8341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 8370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkSrcXfermode, (buffer)); 8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 83935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 84035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate: 84135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkSrcXfermode(SkFlattenableReadBuffer& buffer) 84235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : SkProcCoeffXfermode(buffer) {} 84335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 8481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst && src && count >= 0); 8501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == aa) { 8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(dst, src, count << 2); 8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned a = aa[i]; 8561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (a == 0xFF) { 8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = src[i]; 8581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else if (a != 0) { 8591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkFourByteInterp(src[i], dst[i], a); 8601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 86435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 8651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, 8661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 8671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 8681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst && src && count >= 0); 86935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 8701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == aa) { 8711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 8721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkToU8(SkGetPackedA32(src[i])); 8730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 8751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = count - 1; i >= 0; --i) { 8761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned a = aa[i]; 8771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 != a) { 8781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned srcA = SkGetPackedA32(src[i]); 8791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (a == 0xFF) { 8801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkToU8(srcA); 8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 8821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a)); 8831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 88835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////////////////////////////////////////////////////////////////////////////// 8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass SkDstInXfermode : public SkProcCoeffXfermode { 8921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic: 8931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} 8941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 8961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 89735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkDstInXfermode, (buffer)); 9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 90135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 90235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate: 90335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkDstInXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 90435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkProcCoeffXfermode INHERITED; 9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 9091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 9101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst && src); 91235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (count <= 0) { 9141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 9151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != aa) { 9171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return this->INHERITED::xfer32(dst, src, count, aa); 9181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 91935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 9211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned a = SkGetPackedA32(*src); 9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a)); 9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst++; 9241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src++; 9251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--count != 0); 9261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 92735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////////////// 92935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass SkDstOutXfermode : public SkProcCoeffXfermode { 9311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic: 9321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} 9331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) SK_OVERRIDE; 9351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } 93635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkNEW_ARGS(SkDstOutXfermode, (buffer)); 9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 94035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 94135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerprivate: 94235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkDstOutXfermode(SkFlattenableReadBuffer& buffer) 94335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger : INHERITED(buffer) {} 94435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project typedef SkProcCoeffXfermode INHERITED; 9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 9470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 9491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkPMColor* SK_RESTRICT src, int count, 9501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkAlpha* SK_RESTRICT aa) { 9511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst && src); 9521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (count <= 0) { 9541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 9551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL != aa) { 9571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return this->INHERITED::xfer32(dst, src, count, aa); 9581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger do { 9611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned a = SkGetPackedA32(*src); 9621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a)); 9631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst++; 9641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src++; 9651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } while (--count != 0); 9661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 9671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9709f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike ReedSkXfermode* SkXfermode::Create(Mode mode) { 9719f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 9729f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed SkASSERT((unsigned)mode < kModeCount); 9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 97435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger const ProcCoeff& rec = gProcCoeffs[mode]; 97535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (mode) { 9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kClear_Mode: 97835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(SkClearXfermode, (rec)); 9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kSrc_Mode: 98035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(SkSrcXfermode, (rec)); 9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kSrcOver_Mode: 9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kDstIn_Mode: 98435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(SkDstInXfermode, (rec)); 9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kDstOut_Mode: 98635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(SkDstOutXfermode, (rec)); 98735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger default: 98835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); 9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 99235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek SollenbergerSkXfermodeProc SkXfermode::GetProc(Mode mode) { 99335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkXfermodeProc proc = NULL; 99435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if ((unsigned)mode < kModeCount) { 99535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger proc = gProcCoeffs[mode].fProc; 99635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 99735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return proc; 99835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 99935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 100035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) { 100135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); 100235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 100335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if ((unsigned)mode >= (unsigned)kModeCount) { 100435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // illegal mode parameter 100535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return false; 100635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 100735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 100835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger const ProcCoeff& rec = gProcCoeffs[mode]; 100935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 101035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (CANNOT_USE_COEFF == rec.fSC) { 101135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return false; 101235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 101335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 101435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(CANNOT_USE_COEFF != rec.fDC); 101535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (src) { 101635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger *src = rec.fSC; 101735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 101835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (dst) { 101935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger *dst = rec.fDC; 102035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 102135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return true; 102235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger} 102335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 102435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkXfermode::AsMode(SkXfermode* xfer, Mode* mode) { 10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL == xfer) { 10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (mode) { 10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *mode = kSrcOver_Mode; 10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return true; 10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 103135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return xfer->asMode(mode); 10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 103435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerbool SkXfermode::AsCoeff(SkXfermode* xfer, Coeff* src, Coeff* dst) { 103535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (NULL == xfer) { 103635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return ModeAsCoeff(kSrcOver_Mode, src, dst); 10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 103835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger return xfer->asCoeff(src, dst); 10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkXfermode::IsMode(SkXfermode* xfer, Mode mode) { 10421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if xfer==null then the mode is srcover 10431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger Mode m = kSrcOver_Mode; 10441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (xfer && !xfer->asMode(&m)) { 10451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 10461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return mode == m; 10481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 10491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////// 16bit xfermode procs 10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG 10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; } 10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; } 10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) { 10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkPixel32ToPixel16(src); 10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) { 10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) { 10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_0(src)); 10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) { 10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkPixel32ToPixel16(src); 10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) { 10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_0(src)); 10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) { 10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) { 10880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkPixel32ToPixel16(src); 10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) { 10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) { 10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_0(src)); 10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) { 11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned isa = 255 - SkGetPackedA32(src); 110435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkPackRGB16( 11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa), 11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa), 11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa)); 11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) { 11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_0(src)); 11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) { 11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkPixel32ToPixel16(src); 11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) { 11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/********* 11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project darken and lighten boil down to this. 11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project darken = (1 - Sa) * Dc + min(Sc, Dc) 11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project lighten = (1 - Sa) * Dc + max(Sc, Dc) 11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (Sa == 0) these become 11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project darken = Dc + min(0, Dc) = 0 11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project lighten = Dc + max(0, Dc) = Dc 11350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (Sa == 1) these become 11370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project darken = min(Sc, Dc) 11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project lighten = max(Sc, Dc) 11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/ 11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) { 11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_0(src)); 11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) { 11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 11480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkPackRGB16(r, g, b); 11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) { 11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_0(src)); 11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return dst; 11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) { 11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(require_255(src)); 11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst)); 11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst)); 11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst)); 11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkPackRGB16(r, g, b); 11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstruct Proc16Rec { 11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermodeProc16 fProc16_0; 11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermodeProc16 fProc16_255; 11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermodeProc16 fProc16_General; 11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11739f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reedstatic const Proc16Rec gModeProcs16[] = { 11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { NULL, NULL, NULL }, // CLEAR 11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { NULL, src_modeproc16_255, NULL }, 11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { dst_modeproc16, dst_modeproc16, dst_modeproc16 }, 11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { srcover_modeproc16_0, srcover_modeproc16_255, NULL }, 11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { dstover_modeproc16_0, dstover_modeproc16_255, NULL }, 11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { NULL, srcin_modeproc16_255, NULL }, 11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { NULL, dstin_modeproc16_255, NULL }, 11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { NULL, NULL, NULL },// SRC_OUT 11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { dstout_modeproc16_0, NULL, NULL }, 11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 }, 11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { NULL, dstatop_modeproc16_255, NULL }, 11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { NULL, NULL, NULL }, // XOR 11869f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed 11879f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // plus 11889f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // multiply 11899f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // screen 11909f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // overlay 11919f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { darken_modeproc16_0, darken_modeproc16_255, NULL }, // darken 11929f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { lighten_modeproc16_0, lighten_modeproc16_255, NULL }, // lighten 11939f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // colordodge 11949f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // colorburn 11959f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // hardlight 11969f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // softlight 11979f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // difference 11989f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed { NULL, NULL, NULL }, // exclusion 11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12019f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike ReedSkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) { 12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkXfermodeProc16 proc16 = NULL; 12039f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed if ((unsigned)mode < kModeCount) { 12049f0b433bdd1680cd1d371c19d7e0ffde8fb2c484Mike Reed const Proc16Rec& rec = gModeProcs16[mode]; 12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned a = SkColorGetA(srcColor); 12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (0 == a) { 12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project proc16 = rec.fProc16_0; 12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else if (255 == a) { 12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project proc16 = rec.fProc16_255; 12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project proc16 = rec.fProc16_General; 12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return proc16; 12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12181cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 12191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 12201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) 12211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) 12221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) 12231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) 12241cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1225