SkAvoidXfermode.cpp revision 0910916c0f7b951ee55c4b7c6358295b9bca0565
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/graphics/effects/SkAvoidXfermode.cpp
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License.
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAvoidXfermode.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h"
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkAvoidXfermode::SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode)
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (tolerance > 255) {
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        tolerance = 255;
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fOpColor = opColor;
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDistMul = (256 << 14) / (tolerance + 1);
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMode = mode;
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkAvoidXfermode::SkAvoidXfermode(SkFlattenableReadBuffer& buffer)
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    : INHERITED(buffer)
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fOpColor = buffer.readU32();
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDistMul = buffer.readU32();
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMode = (Mode)buffer.readU8();
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::flatten(SkFlattenableWriteBuffer& buffer)
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->INHERITED::flatten(buffer);
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(fOpColor);
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(fDistMul);
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(fMode);
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable* SkAvoidXfermode::Create(SkFlattenableReadBuffer& rb)
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkNEW_ARGS(SkAvoidXfermode, (rb));
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkFlattenable::Factory SkAvoidXfermode::getFactory()
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return Create;
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// returns 0..31
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic unsigned color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b)
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(r <= SK_R16_MASK);
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(g <= SK_G16_MASK);
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(b <= SK_B16_MASK);
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dr = SkAbs32(SkGetPackedR16(c) - r);
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS);
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned db = SkAbs32(SkGetPackedB16(c) - b);
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkMax32(dr, SkMax32(dg, db));
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// returns 0..15
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic unsigned color_dist4444(uint16_t c, unsigned r, unsigned g, unsigned b)
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(r <= 0xF);
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(g <= 0xF);
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(b <= 0xF);
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dr = SkAbs32(SkGetPackedR4444(c) - r);
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dg = SkAbs32(SkGetPackedG4444(c) - g);
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned db = SkAbs32(SkGetPackedB4444(c) - b);
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkMax32(dr, SkMax32(dg, db));
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// returns 0..255
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic unsigned color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b)
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(r <= 0xFF);
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(g <= 0xFF);
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(b <= 0xFF);
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dr = SkAbs32(SkGetPackedR32(c) - r);
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned dg = SkAbs32(SkGetPackedG32(c) - g);
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned db = SkAbs32(SkGetPackedB32(c) - b);
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkMax32(dr, SkMax32(dg, db));
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int scale_dist_14(int dist, uint32_t mul, uint32_t sub)
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int tmp = dist * mul - sub;
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int result = (tmp + (1 << 13)) >> 14;
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return result;
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst, unsigned scale)
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale);
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale);
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale);
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale);
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkPackARGB32(a, r, g, b);
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count,
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             const SkAlpha aa[])
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opR = SkColorGetR(fOpColor);
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opG = SkColorGetG(fOpColor);
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opB = SkColorGetB(fOpColor);
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    mul = fDistMul;
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    sub = (fDistMul - (1 << 14)) << 8;
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int MAX, mask;
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kTargetColor_Mode == fMode) {
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = -1;
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 255;
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = 0;
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 0;
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 0; i < count; i++) {
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int d = color_dist32(dst[i], opR, opG, opB);
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now reverse d if we need to
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = MAX + (d ^ mask) - mask;
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((unsigned)d <= 255);
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = SkAlpha255To256(d);
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = scale_dist_14(d, mul, sub);
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(d <= 256);
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (d > 0) {
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != aa) {
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                d = SkAlphaMul(d, SkAlpha255To256(*aa++));
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (0 == d) {
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    continue;
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst[i] = SkFourByteInterp(src[i], dst[i], d);
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale)
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(scale <= 32);
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    scale <<= 3;
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkPackRGB16( SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale),
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale),
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale));
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count,
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             const SkAlpha aa[])
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opR = SkColorGetR(fOpColor) >> (8 - SK_R16_BITS);
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS);
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS);
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    mul = fDistMul;
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    sub = (fDistMul - (1 << 14)) << 8;
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int MAX, mask;
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kTargetColor_Mode == fMode) {
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = -1;
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 31;
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = 0;
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 0;
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 0; i < count; i++) {
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int d = color_dist16(dst[i], opR, opG, opB);
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now reverse d if we need to
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = MAX + (d ^ mask) - mask;
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((unsigned)d <= 31);
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // convert from 0..31 to 0..32
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d += d >> 4;
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = scale_dist_14(d, mul, sub);
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(d <= 32);
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (d > 0) {
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != aa) {
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                d = SkAlphaMul(d, SkAlpha255To256(*aa++));
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (0 == d) {
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    continue;
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst[i] = SkBlend3216(src[i], dst[i], d);
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::xfer4444(uint16_t dst[], const SkPMColor src[], int count,
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const SkAlpha aa[])
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opR = SkColorGetR(fOpColor) >> 4;
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opG = SkColorGetG(fOpColor) >> 4;
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned    opB = SkColorGetB(fOpColor) >> 4;
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    mul = fDistMul;
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t    sub = (fDistMul - (1 << 14)) << 8;
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int MAX, mask;
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kTargetColor_Mode == fMode) {
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = -1;
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 15;
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mask = 0;
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        MAX = 0;
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 0; i < count; i++) {
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int d = color_dist4444(dst[i], opR, opG, opB);
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // now reverse d if we need to
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = MAX + (d ^ mask) - mask;
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT((unsigned)d <= 15);
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = SkAlpha255To256(d);
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        d = scale_dist_14(d, mul, sub);
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(d <= 16);
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (d > 0) {
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (NULL != aa) {
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                d = SkAlphaMul(d, SkAlpha255To256(*aa++));
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (0 == d) {
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    continue;
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dst[i] = SkBlend4444(SkPixel32ToPixel4444(src[i]), dst[i], d);
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkAvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, const SkAlpha aa[])
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // override in subclass
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
258