void SkProcXfermode::xfer4444(SK_RESTRICT SkPMColor16 dst[], const SK_RESTRICT SkPMColor src[], int count, const SK_RESTRICT SkAlpha aa[]) { SkASSERT(dst && src && count >= 0); SkXfermodeProc proc = fProc; if (NULL != proc) { if (NULL == aa) { for (int i = count - 1; i >= 0; --i) { SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); dst[i] = SkPixel32ToPixel4444(proc(src[i], dstC)); } } else { for (int i = count - 1; i >= 0; --i) { unsigned a = aa[i]; if (0 != a) { SkPMColor dstC = SkPixel4444ToPixel32(dst[i]); SkPMColor C = proc(src[i], dstC); if (0xFF != a) { C = SkFourByteInterp(C, dstC, a); } dst[i] = SkPixel32ToPixel4444(C); } } } } }
SkARGB4444_Blitter::SkARGB4444_Blitter(const SkBitmap& device, const SkPaint& paint) : INHERITED(device) { // cache premultiplied versions in 4444 SkPMColor c = SkPreMultiplyColor(paint.getColor()); fPMColor16 = SkPixel32ToPixel4444(c); if (paint.isDither()) { fPMColor16Other = SkDitherPixel32To4444(c); } else { fPMColor16Other = fPMColor16; } // cache raw versions in 4444 fRawColor16 = SkPackARGB4444(0xFF >> 4, SkColorGetR(c) >> 4, SkColorGetG(c) >> 4, SkColorGetB(c) >> 4); if (paint.isDither()) { fRawColor16Other = SkDitherARGB32To4444(0xFF, SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); } else { fRawColor16Other = fRawColor16; } fScale16 = SkAlpha15To16(SkGetPackedA4444(fPMColor16Other)); if (16 == fScale16) { // force the original to also be opaque fPMColor16 |= (0xF << SK_A4444_SHIFT); } }
SkARGB4444_Blitter::SkARGB4444_Blitter(const SkBitmap& device, const SkPaint& paint) : INHERITED(device) { // cache premultiplied versions in 4444 SkPMColor c = SkPreMultiplyColor(paint.getColor()); fPMColor16 = SkPixel32ToPixel4444(c); if (paint.isDither()) { fPMColor16Other = SkDitherPixel32To4444(c); } else { fPMColor16Other = fPMColor16; } // cache raw versions in 4444 fRawColor16 = SkPackARGB4444(0xFF >> 4, SkColorGetR(c) >> 4, SkColorGetG(c) >> 4, SkColorGetB(c) >> 4); if (paint.isDither()) { fRawColor16Other = SkDitherARGB32To4444(0xFF, SkColorGetR(c), SkColorGetG(c), SkColorGetB(c)); } else { fRawColor16Other = fRawColor16; } #if 0 /// don't think this assertion is true, but need it be? // our dithered color will be the same or more opaque than the original // so use dithered to compute our scale SkASSERT(SkGetPackedA4444(fPMColor16Other) >= SkGetPackedA4444(fPMColor16)); #endif fScale16 = SkAlpha15To16(SkGetPackedA4444(fPMColor16Other)); if (16 == fScale16) { // force the original to also be opaque fPMColor16 |= (0xF << SK_A4444_SHIFT); } }
void SkAvoidXfermode::xfer4444(uint16_t dst[], const SkPMColor src[], int count, const SkAlpha aa[]) { unsigned opR = SkColorGetR(fOpColor) >> 4; unsigned opG = SkColorGetG(fOpColor) >> 4; unsigned opB = SkColorGetB(fOpColor) >> 4; uint32_t mul = fDistMul; uint32_t sub = (fDistMul - (1 << 14)) << 4; int MAX, mask; if (kTargetColor_Mode == fMode) { mask = -1; MAX = 15; } else { mask = 0; MAX = 0; } for (int i = 0; i < count; i++) { int d = color_dist4444(dst[i], opR, opG, opB); // now reverse d if we need to d = MAX + (d ^ mask) - mask; SkASSERT((unsigned)d <= 15); // convert from 0..15 to 0..16 d += d >> 3; d = scale_dist_14(d, mul, sub); SkASSERT(d <= 16); if (d > 0) { if (NULL != aa) { d = SkAlphaMul(d, Accurate255To256(*aa++)); if (0 == d) { continue; } } dst[i] = SkBlend4444(SkPixel32ToPixel4444(src[i]), dst[i], d); } } }
static uint16_t remove_alpha_argb4444(uint16_t pmColor) { return SkPixel32ToPixel4444( remove_alpha_argb8888(SkPixel4444ToPixel32(pmColor))); }