gfx/skia/trunk/src/effects/SkAvoidXfermode.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2  * Copyright 2006 The Android Open Source Project
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkAvoidXfermode.h"
     9 #include "SkColorPriv.h"
    10 #include "SkReadBuffer.h"
    11 #include "SkWriteBuffer.h"
    12 #include "SkString.h"
    14 SkAvoidXfermode::SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode) {
    15     if (tolerance > 255) {
    16         tolerance = 255;
    17     }
    19     fOpColor = opColor;
    20     fDistMul = (256 << 14) / (tolerance + 1);
    21     fMode = mode;
    22 }
    24 SkAvoidXfermode::SkAvoidXfermode(SkReadBuffer& buffer)
    25     : INHERITED(buffer) {
    26     fOpColor = buffer.readColor();
    27     fDistMul = buffer.readUInt();
    28     fMode = (Mode)buffer.readUInt();
    29 }
    31 void SkAvoidXfermode::flatten(SkWriteBuffer& buffer) const {
    32     this->INHERITED::flatten(buffer);
    34     buffer.writeColor(fOpColor);
    35     buffer.writeUInt(fDistMul);
    36     buffer.writeUInt(fMode);
    37 }
    39 // returns 0..31
    40 static unsigned color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b) {
    41     SkASSERT(r <= SK_R16_MASK);
    42     SkASSERT(g <= SK_G16_MASK);
    43     SkASSERT(b <= SK_B16_MASK);
    45     unsigned dr = SkAbs32(SkGetPackedR16(c) - r);
    46     unsigned dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS);
    47     unsigned db = SkAbs32(SkGetPackedB16(c) - b);
    49     return SkMax32(dr, SkMax32(dg, db));
    50 }
    52 // returns 0..255
    53 static unsigned color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b) {
    54     SkASSERT(r <= 0xFF);
    55     SkASSERT(g <= 0xFF);
    56     SkASSERT(b <= 0xFF);
    58     unsigned dr = SkAbs32(SkGetPackedR32(c) - r);
    59     unsigned dg = SkAbs32(SkGetPackedG32(c) - g);
    60     unsigned db = SkAbs32(SkGetPackedB32(c) - b);
    62     return SkMax32(dr, SkMax32(dg, db));
    63 }
    65 static int scale_dist_14(int dist, uint32_t mul, uint32_t sub) {
    66     int tmp = dist * mul - sub;
    67     int result = (tmp + (1 << 13)) >> 14;
    69     return result;
    70 }
    72 static inline unsigned Accurate255To256(unsigned x) {
    73     return x + (x >> 7);
    74 }
    76 void SkAvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count,
    77                              const SkAlpha aa[]) const {
    78     unsigned    opR = SkColorGetR(fOpColor);
    79     unsigned    opG = SkColorGetG(fOpColor);
    80     unsigned    opB = SkColorGetB(fOpColor);
    81     uint32_t    mul = fDistMul;
    82     uint32_t    sub = (fDistMul - (1 << 14)) << 8;
    84     int MAX, mask;
    86     if (kTargetColor_Mode == fMode) {
    87         mask = -1;
    88         MAX = 255;
    89     } else {
    90         mask = 0;
    91         MAX = 0;
    92     }
    94     for (int i = 0; i < count; i++) {
    95         int d = color_dist32(dst[i], opR, opG, opB);
    96         // now reverse d if we need to
    97         d = MAX + (d ^ mask) - mask;
    98         SkASSERT((unsigned)d <= 255);
    99         d = Accurate255To256(d);
   101         d = scale_dist_14(d, mul, sub);
   102         SkASSERT(d <= 256);
   104         if (d > 0) {
   105             if (NULL != aa) {
   106                 d = SkAlphaMul(d, Accurate255To256(*aa++));
   107                 if (0 == d) {
   108                     continue;
   109                 }
   110             }
   111             dst[i] = SkFourByteInterp256(src[i], dst[i], d);
   112         }
   113     }
   114 }
   116 static inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale) {
   117     SkASSERT(scale <= 32);
   118     scale <<= 3;
   120     return SkPackRGB16( SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale),
   121                         SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale),
   122                         SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale));
   123 }
   125 void SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count,
   126                              const SkAlpha aa[]) const {
   127     unsigned    opR = SkColorGetR(fOpColor) >> (8 - SK_R16_BITS);
   128     unsigned    opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS);
   129     unsigned    opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS);
   130     uint32_t    mul = fDistMul;
   131     uint32_t    sub = (fDistMul - (1 << 14)) << SK_R16_BITS;
   133     int MAX, mask;
   135     if (kTargetColor_Mode == fMode) {
   136         mask = -1;
   137         MAX = 31;
   138     } else {
   139         mask = 0;
   140         MAX = 0;
   141     }
   143     for (int i = 0; i < count; i++) {
   144         int d = color_dist16(dst[i], opR, opG, opB);
   145         // now reverse d if we need to
   146         d = MAX + (d ^ mask) - mask;
   147         SkASSERT((unsigned)d <= 31);
   148         // convert from 0..31 to 0..32
   149         d += d >> 4;
   150         d = scale_dist_14(d, mul, sub);
   151         SkASSERT(d <= 32);
   153         if (d > 0) {
   154             if (NULL != aa) {
   155                 d = SkAlphaMul(d, Accurate255To256(*aa++));
   156                 if (0 == d) {
   157                     continue;
   158                 }
   159             }
   160             dst[i] = SkBlend3216(src[i], dst[i], d);
   161         }
   162     }
   163 }
   165 void SkAvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count,
   166                              const SkAlpha aa[]) const {
   167     // override in subclass
   168 }
   170 #ifndef SK_IGNORE_TO_STRING
   171 void SkAvoidXfermode::toString(SkString* str) const {
   172     str->append("SkAvoidXfermode: opColor: ");
   173     str->appendHex(fOpColor);
   174     str->appendf("distMul: %d ", fDistMul);
   176     static const char* gModeStrings[] = { "Avoid", "Target" };
   178     str->appendf("mode: %s", gModeStrings[fMode]);
   179 }
   180 #endif

mercurial