static inline SkPMColor SkBlendARGB4444(SkPMColor16 src, SkPMColor16 dst, U8CPU aa) { SkASSERT((unsigned)aa <= 255); unsigned src_scale = SkAlpha255To256(aa) >> 4; unsigned dst_scale = SkAlpha15To16(15 - SkAlphaMul4(SkGetPackedA4444(src), src_scale)); uint32_t src32 = SkExpand_4444(src) * src_scale; uint32_t dst32 = SkExpand_4444(dst) * dst_scale; return SkCompact_4444((src32 + dst32) >> 4); }
static void src_over_4444x(SkPMColor16 dst[], uint32_t color, uint32_t other, unsigned invScale, int count) { int twice = count >> 1; uint32_t tmp; while (--twice >= 0) { tmp = SkExpand_4444(*dst) * invScale; *dst++ = SkCompact_4444((color + tmp) >> 4); tmp = SkExpand_4444(*dst) * invScale; *dst++ = SkCompact_4444((other + tmp) >> 4); } if (count & 1) { tmp = SkExpand_4444(*dst) * invScale; *dst = SkCompact_4444((color + tmp) >> 4); }
// returns answer in SkPMColor format static inline SkPMColor Filter_4444_D32(unsigned x, unsigned y, uint32_t a00, uint32_t a01, uint32_t a10, uint32_t a11) { SkASSERT((unsigned)x <= 0xF); SkASSERT((unsigned)y <= 0xF); a00 = SkExpand_4444(a00); a01 = SkExpand_4444(a01); a10 = SkExpand_4444(a10); a11 = SkExpand_4444(a11); int xy = x * y >> 4; uint32_t result = a00 * (16 - y - x + xy) + a01 * (x - xy) + a10 * (y - xy) + a11 * xy; return SkCompact_8888(result); }
void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) { unsigned scale = SkAlpha255To256(fAlpha); switch (fDevice->getConfig()) { case SkBitmap::kARGB_8888_Config: if (scale == 256) { SkPMColor* src = fDevice->getAddr32(x, y); if (src != span) { memcpy(span, src, count * sizeof(SkPMColor)); } } else { const SkPMColor* src = fDevice->getAddr32(x, y); for (int i = count - 1; i >= 0; --i) { span[i] = SkAlphaMulQ(src[i], scale); } } break; case SkBitmap::kRGB_565_Config: { const uint16_t* src = fDevice->getAddr16(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { span[i] = SkPixel16ToPixel32(src[i]); } } else { unsigned alpha = fAlpha; for (int i = count - 1; i >= 0; --i) { uint16_t c = src[i]; unsigned r = SkPacked16ToR32(c); unsigned g = SkPacked16ToG32(c); unsigned b = SkPacked16ToB32(c); span[i] = SkPackARGB32( alpha, SkAlphaMul(r, scale), SkAlphaMul(g, scale), SkAlphaMul(b, scale)); } } break; } case SkBitmap::kARGB_4444_Config: { const uint16_t* src = fDevice->getAddr16(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { span[i] = SkPixel4444ToPixel32(src[i]); } } else { unsigned scale16 = scale >> 4; for (int i = count - 1; i >= 0; --i) { uint32_t c = SkExpand_4444(src[i]) * scale16; span[i] = SkCompact_8888(c); } } break; } case SkBitmap::kIndex8_Config: SkDEBUGFAIL("index8 not supported as a destination device"); break; case SkBitmap::kA8_Config: { const uint8_t* src = fDevice->getAddr8(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { span[i] = SkPackARGB32(src[i], 0, 0, 0); } } else { for (int i = count - 1; i >= 0; --i) { span[i] = SkPackARGB32(SkAlphaMul(src[i], scale), 0, 0, 0); } } break; } case SkBitmap::kA1_Config: SkDEBUGFAIL("kA1_Config umimplemented at this time"); break; default: // to avoid warnings break; } }
static inline uint32_t SkExpand_4444_Replicate(SkPMColor16 c) { uint32_t c32 = SkExpand_4444(c); return c32 | (c32 << 4); }