11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAvoidXfermode.h"
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h"
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkAvoidXfermode::SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode)
1435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger{
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (tolerance > 255) {
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        tolerance = 255;
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fOpColor = opColor;
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDistMul = (256 << 14) / (tolerance + 1);
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMode = mode;
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkAvoidXfermode::SkAvoidXfermode(SkFlattenableReadBuffer& buffer)
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    : INHERITED(buffer)
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fOpColor = buffer.readU32();
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDistMul = buffer.readU32();
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMode = (Mode)buffer.readU8();
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::flatten(SkFlattenableWriteBuffer& buffer)
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->INHERITED::flatten(buffer);
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(fOpColor);
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(fDistMul);
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(fMode);
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable* SkAvoidXfermode::Create(SkFlattenableReadBuffer& rb)
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkNEW_ARGS(SkAvoidXfermode, (rb));
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable::Factory SkAvoidXfermode::getFactory()
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return Create;
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// returns 0..31
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic unsigned color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b)
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(r <= SK_R16_MASK);
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(g <= SK_G16_MASK);
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(b <= SK_B16_MASK);
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dr = SkAbs32(SkGetPackedR16(c) - r);
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS);
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned db = SkAbs32(SkGetPackedB16(c) - b);
6135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkMax32(dr, SkMax32(dg, db));
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// returns 0..15
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic unsigned color_dist4444(uint16_t c, unsigned r, unsigned g, unsigned b)
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(r <= 0xF);
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(g <= 0xF);
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(b <= 0xF);
7135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dr = SkAbs32(SkGetPackedR4444(c) - r);
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dg = SkAbs32(SkGetPackedG4444(c) - g);
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned db = SkAbs32(SkGetPackedB4444(c) - b);
7535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkMax32(dr, SkMax32(dg, db));
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// returns 0..255
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic unsigned color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b)
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(r <= 0xFF);
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(g <= 0xFF);
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(b <= 0xFF);
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dr = SkAbs32(SkGetPackedR32(c) - r);
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dg = SkAbs32(SkGetPackedG32(c) - g);
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned db = SkAbs32(SkGetPackedB32(c) - b);
8935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkMax32(dr, SkMax32(dg, db));
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int scale_dist_14(int dist, uint32_t mul, uint32_t sub)
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int tmp = dist * mul - sub;
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int result = (tmp + (1 << 13)) >> 14;
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return result;
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1014ffbc6172403ee38fc70608377ce78c9db00394aMike Reedstatic inline unsigned Accurate255To256(unsigned x) {
1024ffbc6172403ee38fc70608377ce78c9db00394aMike Reed    return x + (x >> 7);
1034ffbc6172403ee38fc70608377ce78c9db00394aMike Reed}
1044ffbc6172403ee38fc70608377ce78c9db00394aMike Reed
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count,
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             const SkAlpha aa[])
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opR = SkColorGetR(fOpColor);
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opG = SkColorGetG(fOpColor);
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opB = SkColorGetB(fOpColor);
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    mul = fDistMul;
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    sub = (fDistMul - (1 << 14)) << 8;
11335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int MAX, mask;
11535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kTargetColor_Mode == fMode) {
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = -1;
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 255;
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = 0;
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 0;
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 0; i < count; i++) {
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int d = color_dist32(dst[i], opR, opG, opB);
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now reverse d if we need to
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = MAX + (d ^ mask) - mask;
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((unsigned)d <= 255);
1294ffbc6172403ee38fc70608377ce78c9db00394aMike Reed        d = Accurate255To256(d);
13035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = scale_dist_14(d, mul, sub);
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(d <= 256);
13335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (d > 0) {
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != aa) {
1364ffbc6172403ee38fc70608377ce78c9db00394aMike Reed                d = SkAlphaMul(d, Accurate255To256(*aa++));
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (0 == d) {
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    continue;
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst[i] = SkFourByteInterp(src[i], dst[i], d);
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale)
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(scale <= 32);
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    scale <<= 3;
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkPackRGB16( SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale),
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale),
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale));
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count,
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             const SkAlpha aa[])
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opR = SkColorGetR(fOpColor) >> (8 - SK_R16_BITS);
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS);
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS);
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    mul = fDistMul;
16324fb8c7cc7b76134a25914d8f6346c89c359c621Mike Reed    uint32_t    sub = (fDistMul - (1 << 14)) << SK_R16_BITS;
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int MAX, mask;
16635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kTargetColor_Mode == fMode) {
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = -1;
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 31;
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = 0;
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 0;
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 0; i < count; i++) {
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int d = color_dist16(dst[i], opR, opG, opB);
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now reverse d if we need to
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = MAX + (d ^ mask) - mask;
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((unsigned)d <= 31);
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // convert from 0..31 to 0..32
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d += d >> 4;
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = scale_dist_14(d, mul, sub);
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(d <= 32);
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (d > 0) {
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != aa) {
1874ffbc6172403ee38fc70608377ce78c9db00394aMike Reed                d = SkAlphaMul(d, Accurate255To256(*aa++));
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (0 == d) {
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    continue;
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst[i] = SkBlend3216(src[i], dst[i], d);
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::xfer4444(uint16_t dst[], const SkPMColor src[], int count,
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const SkAlpha aa[])
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opR = SkColorGetR(fOpColor) >> 4;
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opG = SkColorGetG(fOpColor) >> 4;
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opB = SkColorGetB(fOpColor) >> 4;
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    mul = fDistMul;
20424fb8c7cc7b76134a25914d8f6346c89c359c621Mike Reed    uint32_t    sub = (fDistMul - (1 << 14)) << 4;
20535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int MAX, mask;
20735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kTargetColor_Mode == fMode) {
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = -1;
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 15;
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = 0;
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 0;
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
21535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 0; i < count; i++) {
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int d = color_dist4444(dst[i], opR, opG, opB);
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now reverse d if we need to
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = MAX + (d ^ mask) - mask;
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((unsigned)d <= 15);
22124fb8c7cc7b76134a25914d8f6346c89c359c621Mike Reed        // convert from 0..15 to 0..16
22224fb8c7cc7b76134a25914d8f6346c89c359c621Mike Reed        d += d >> 3;
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = scale_dist_14(d, mul, sub);
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(d <= 16);
22535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (d > 0) {
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != aa) {
2284ffbc6172403ee38fc70608377ce78c9db00394aMike Reed                d = SkAlphaMul(d, Accurate255To256(*aa++));
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (0 == d) {
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    continue;
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst[i] = SkBlend4444(SkPixel32ToPixel4444(src[i]), dst[i], d);
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, const SkAlpha aa[])
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // override in subclass
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2431cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR(SkAvoidXfermode)
244