bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix) { if (!this->INHERITED::setContext(device, paint, matrix)) { return false; } SkColor c; unsigned a; if (fInheritColor) { c = paint.getColor(); a = SkColorGetA(c); } else { c = fColor; a = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha())); } unsigned r = SkColorGetR(c); unsigned g = SkColorGetG(c); unsigned b = SkColorGetB(c); // we want this before we apply any alpha fColor16 = SkPack888ToRGB16(r, g, b); if (a != 255) { a = SkAlpha255To256(a); r = SkAlphaMul(r, a); g = SkAlphaMul(g, a); b = SkAlphaMul(b, a); } fPMColor = SkPackARGB32(a, r, g, b); return true; }
void SkTransparentShader::TransparentShaderContext::shadeSpan(int x, int y, SkPMColor span[], int count) { unsigned scale = SkAlpha255To256(this->getPaintAlpha()); switch (fDevice->colorType()) { case kN32_SkColorType: 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 kRGB_565_SkColorType: { 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 = this->getPaintAlpha(); 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 kAlpha_8_SkColorType: { 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; } default: SkDEBUGFAIL("colorType not supported as a destination device"); break; } }
SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint) : INHERITED(device) { uint32_t color = paint.getColor(); fSrcA = SkColorGetA(color); unsigned scale = SkAlpha255To256(fSrcA); fSrcR = SkAlphaMul(SkColorGetR(color), scale); fSrcG = SkAlphaMul(SkColorGetG(color), scale); fSrcB = SkAlphaMul(SkColorGetB(color), scale); fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB); }
SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint) : INHERITED(device) { SkColor color = paint.getColor(); fColor = color; fSrcA = SkColorGetA(color); unsigned scale = SkAlpha255To256(fSrcA); fSrcR = SkAlphaMul(SkColorGetR(color), scale); fSrcG = SkAlphaMul(SkColorGetG(color), scale); fSrcB = SkAlphaMul(SkColorGetB(color), scale); fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB); fColor32Proc = SkBlitRow::ColorProcFactory(); fColorRect32Proc = SkBlitRow::ColorRectProcFactory(); }
static void reverseRedAndBlue(const SkBitmap& bm) { SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config); uint8_t* p = (uint8_t*)bm.getPixels(); uint8_t* stop = p + bm.getSize(); while (p < stop) { // swap red/blue (to go from ARGB(int) to RGBA(memory) and premultiply unsigned scale = SkAlpha255To256(p[3]); unsigned r = p[2]; unsigned b = p[0]; p[0] = SkAlphaMul(r, scale); p[1] = SkAlphaMul(p[1], scale); p[2] = SkAlphaMul(b, scale); p += 4; } }
SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { if (a != 255) { #if 0 unsigned scale = SkAlpha255To256(a); r = SkAlphaMul(r, scale); g = SkAlphaMul(g, scale); b = SkAlphaMul(b, scale); #else r = SkMulDiv255Round(r, a); g = SkMulDiv255Round(g, a); b = SkMulDiv255Round(b, a); #endif } return SkPackARGB32(a, r, g, b); }
SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader, const ContextRec& rec) : INHERITED(shader, rec) { SkColor color = shader.fColor; unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha())); unsigned r = SkColorGetR(color); unsigned g = SkColorGetG(color); unsigned b = SkColorGetB(color); // we want this before we apply any alpha fColor16 = SkPack888ToRGB16(r, g, b); if (a != 255) { r = SkMulDiv255Round(r, a); g = SkMulDiv255Round(g, a); b = SkMulDiv255Round(b, a); } fPMColor = SkPackARGB32(a, r, g, b); fFlags = kConstInY32_Flag; if (255 == a) { fFlags |= kOpaqueAlpha_Flag; if (rec.fPaint->isDither() == false) { fFlags |= kHasSpan16_Flag; } } }
SkColor SkHSVToColor(U8CPU a, const SkScalar hsv[3]) { SkASSERT(hsv); U8CPU s = SkUnitScalarClampToByte(hsv[1]); U8CPU v = SkUnitScalarClampToByte(hsv[2]); if (0 == s) { // shade of gray return SkColorSetARGB(a, v, v, v); } SkFixed hx = (hsv[0] < 0 || hsv[0] >= SkIntToScalar(360)) ? 0 : SkScalarToFixed(hsv[0]/60); SkFixed f = hx & 0xFFFF; unsigned v_scale = SkAlpha255To256(v); unsigned p = SkAlphaMul(255 - s, v_scale); unsigned q = SkAlphaMul(255 - (s * f >> 16), v_scale); unsigned t = SkAlphaMul(255 - (s * (SK_Fixed1 - f) >> 16), v_scale); unsigned r, g, b; SkASSERT((unsigned)(hx >> 16) < 6); switch (hx >> 16) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; default: r = v; g = p; b = q; break; } return SkColorSetARGB(a, r, g, b); }
void SkBaseDevice::drawImageLattice(const SkImage* image, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint& paint) { SkLatticeIter iter(lattice, dst); SkRect srcR, dstR; SkColor c; bool isFixedColor = false; const SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType); while (iter.next(&srcR, &dstR, &isFixedColor, &c)) { if (isFixedColor || (srcR.width() <= 1.0f && srcR.height() <= 1.0f && image->readPixels(info, &c, 4, srcR.fLeft, srcR.fTop))) { // Fast draw with drawRect, if this is a patch containing a single color // or if this is a patch containing a single pixel. if (0 != c || !paint.isSrcOver()) { SkPaint paintCopy(paint); int alpha = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha())); paintCopy.setColor(SkColorSetA(c, alpha)); this->drawRect(dstR, paintCopy); } } else { this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint); } } }
static void clamp_with_orig(uint8_t dst[], int dstRowBytes, const uint8_t src[], int srcRowBytes, int sw, int sh, SkBlurMask::Style style) { int x; while (--sh >= 0) { switch (style) { case SkBlurMask::kSolid_Style: for (x = sw - 1; x >= 0; --x) { int s = *src; int d = *dst; *dst = SkToU8(s + d - SkMulDiv255Round(s, d)); dst += 1; src += 1; } break; case SkBlurMask::kOuter_Style: for (x = sw - 1; x >= 0; --x) { if (*src) { *dst = SkToU8(SkAlphaMul(*dst, SkAlpha255To256(255 - *src))); } dst += 1; src += 1; } break; default: SkDEBUGFAIL("Unexpected blur style here"); break; } dst += dstRowBytes - sw; src += srcRowBytes - sw; } }
SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader, const ContextRec& rec) : INHERITED(shader, rec) { SkColor color = shader.fColor; unsigned a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(rec.fPaint->getAlpha())); unsigned r = SkColorGetR(color); unsigned g = SkColorGetG(color); unsigned b = SkColorGetB(color); if (a != 255) { r = SkMulDiv255Round(r, a); g = SkMulDiv255Round(g, a); b = SkMulDiv255Round(b, a); } fPMColor = SkPackARGB32(a, r, g, b); SkColor4f c4 = SkColor4f::FromColor(shader.fColor); c4.fA *= rec.fPaint->getAlpha() / 255.0f; fPM4f = c4.premul(); fFlags = kConstInY32_Flag; if (255 == a) { fFlags |= kOpaqueAlpha_Flag; } }
SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint) : INHERITED(device) { SkColor color = paint.getColor(); fColor = color; fSrcA = SkColorGetA(color); unsigned scale = SkAlpha255To256(fSrcA); fSrcR = SkAlphaMul(SkColorGetR(color), scale); fSrcG = SkAlphaMul(SkColorGetG(color), scale); fSrcB = SkAlphaMul(SkColorGetB(color), scale); fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB); fColor32Proc = SkBlitRow::ColorProcFactory(); // init the pro for blitmask fBlitMaskProc = SkBlitMask::Factory(SkBitmap::kARGB_8888_Config, color); }
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) { unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); for (int i = 0; i < count; i++) { SkPMColor c = shader[i]; if (c) { unsigned a = SkGetPackedA32(c); unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR); unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG); unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB); c = SkPackARGB32(a, r, g, b); } result[i] = c; } }
virtual void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) { unsigned addR = SkColorGetR(fAdd); unsigned addG = SkColorGetG(fAdd); unsigned addB = SkColorGetB(fAdd); for (int i = 0; i < count; i++) { SkPMColor c = shader[i]; if (c) { unsigned a = SkGetPackedA32(c); unsigned scaleA = SkAlpha255To256(a); unsigned r = pin(SkGetPackedR32(c) + SkAlphaMul(addR, scaleA), a); unsigned g = pin(SkGetPackedG32(c) + SkAlphaMul(addG, scaleA), a); unsigned b = pin(SkGetPackedB32(c) + SkAlphaMul(addB, scaleA), a); c = SkPackARGB32(a, r, g, b); } result[i] = c; } }
SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const { int s = roundf(m_alpha * 256); if (s >= 256) return c; if (s < 0) return 0; int a = SkAlphaMul(SkColorGetA(c), s); return (c & 0x00FFFFFF) | (a << 24); }
SkColor PlatformGraphicsContext::State::applyAlpha(SkColor c) const { int s = RoundToInt(alpha * 256); if (s >= 256) return c; if (s < 0) return 0; int a = SkAlphaMul(SkColorGetA(c), s); return (c & 0x00FFFFFF) | (a << 24); }
static inline void D16_S32A_Blend_Pixel_helper(uint16_t* dst, SkPMColor sc, unsigned src_scale) { uint16_t dc = *dst; unsigned sa = SkGetPackedA32(sc); unsigned dr, dg, db; if (255 == sa) { dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale); dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale); db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale); } else { unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale); dr = (SkPacked32ToR16(sc) * src_scale + SkGetPackedR16(dc) * dst_scale) >> 8; dg = (SkPacked32ToG16(sc) * src_scale + SkGetPackedG16(dc) * dst_scale) >> 8; db = (SkPacked32ToB16(sc) * src_scale + SkGetPackedB16(dc) * dst_scale) >> 8; } *dst = SkPackRGB16(dr, dg, db); }
static void merge_src_with_blur(uint8_t dst[], int dstRB, const uint8_t src[], int srcRB, const uint8_t blur[], int blurRB, int sw, int sh) { dstRB -= sw; srcRB -= sw; blurRB -= sw; while (--sh >= 0) { for (int x = sw - 1; x >= 0; --x) { *dst = SkToU8(SkAlphaMul(*blur, SkAlpha255To256(*src))); dst += 1; src += 1; blur += 1; } dst += dstRB; src += srcRB; blur += blurRB; } }
bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix) { if (!this->INHERITED::setContext(device, paint, matrix)) { return false; } SkColor c; unsigned a; if (fInheritColor) { c = paint.getColor(); a = SkColorGetA(c); } else { c = fColor; a = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha())); } unsigned r = SkColorGetR(c); unsigned g = SkColorGetG(c); unsigned b = SkColorGetB(c); // we want this before we apply any alpha fColor16 = SkPack888ToRGB16(r, g, b); if (a != 255) { r = SkMulDiv255Round(r, a); g = SkMulDiv255Round(g, a); b = SkMulDiv255Round(b, a); } fPMColor = SkPackARGB32(a, r, g, b); fFlags = kConstInY32_Flag; if (255 == a) { fFlags |= kOpaqueAlpha_Flag; if (paint.isDither() == false) { fFlags |= kHasSpan16_Flag; } } return true; }
void SkAvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count, const SkAlpha aa[]) { unsigned opR = SkColorGetR(fOpColor); unsigned opG = SkColorGetG(fOpColor); unsigned opB = SkColorGetB(fOpColor); uint32_t mul = fDistMul; uint32_t sub = (fDistMul - (1 << 14)) << 8; int MAX, mask; if (kTargetColor_Mode == fMode) { mask = -1; MAX = 255; } else { mask = 0; MAX = 0; } for (int i = 0; i < count; i++) { int d = color_dist32(dst[i], opR, opG, opB); // now reverse d if we need to d = MAX + (d ^ mask) - mask; SkASSERT((unsigned)d <= 255); d = Accurate255To256(d); d = scale_dist_14(d, mul, sub); SkASSERT(d <= 256); if (d > 0) { if (NULL != aa) { d = SkAlphaMul(d, Accurate255To256(*aa++)); if (0 == d) { continue; } } dst[i] = SkFourByteInterp(src[i], dst[i], d); } } }
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); } } }
void SkAvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count, const SkAlpha aa[]) const { unsigned opR = SkColorGetR(fOpColor) >> (8 - SK_R16_BITS); unsigned opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS); unsigned opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS); uint32_t mul = fDistMul; uint32_t sub = (fDistMul - (1 << 14)) << SK_R16_BITS; int MAX, mask; if (kTargetColor_Mode == fMode) { mask = -1; MAX = 31; } else { mask = 0; MAX = 0; } for (int i = 0; i < count; i++) { int d = color_dist16(dst[i], opR, opG, opB); // now reverse d if we need to d = MAX + (d ^ mask) - mask; SkASSERT((unsigned)d <= 31); // convert from 0..31 to 0..32 d += d >> 4; d = scale_dist_14(d, mul, sub); SkASSERT(d <= 32); if (d > 0) { if (aa) { d = SkAlphaMul(d, Accurate255To256(*aa++)); if (0 == d) { continue; } } dst[i] = SkBlend3216(src[i], dst[i], d); } } }
// our std SkAlpha255To256 static int test_srcover0(unsigned dst, unsigned alpha) { return alpha + SkAlphaMul(dst, SkAlpha255To256(255 - alpha)); }
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; } }
// faster hack +1 static int test_srcover1(unsigned dst, unsigned alpha) { return alpha + SkAlphaMul(dst, 256 - alpha); }