void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override { fDst = dst; fLeft = left; fTop = top; fPaintColor = paint.getColor4f(); SkRasterPipeline p(fAlloc); p.append_load(fSource.colorType(), &fSrcPtr); if (fSource.colorType() == kAlpha_8_SkColorType) { // The color for A8 images comes from the (sRGB) paint color. p.append_set_rgb(fAlloc, fPaintColor); p.append(SkRasterPipeline::premul); } if (auto dstCS = fDst.colorSpace()) { auto srcCS = fSource.colorSpace(); if (!srcCS || fSource.colorType() == kAlpha_8_SkColorType) { // We treat untagged images as sRGB. // A8 images get their r,g,b from the paint color, so they're also sRGB. srcCS = sk_srgb_singleton(); } auto srcAT = fSource.isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType; fAlloc->make<SkColorSpaceXformSteps>(srcCS, srcAT, dstCS, kPremul_SkAlphaType) ->apply(&p, fSource.colorType()); } if (fPaintColor.fA != 1.0f) { p.append(SkRasterPipeline::scale_1_float, &fPaintColor.fA); } bool is_opaque = fSource.isOpaque() && fPaintColor.fA == 1.0f; fBlitter = SkCreateRasterPipelineBlitter(fDst, paint, p, is_opaque, fAlloc); }
SkColorSpaceXformer::SkColorSpaceXformer(sk_sp<SkColorSpace> dst) : fDst(std::move(dst)) , fFromSRGBSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType, fDst.get() , kUnpremul_SkAlphaType) , fReentryCount(0) { SkRasterPipeline p(&fAlloc); p.append(SkRasterPipeline::load_bgra, &fFromSRGBSrc); fFromSRGBSteps.apply(&p); p.append(SkRasterPipeline::store_bgra, &fFromSRGBDst); fFromSRGB = p.compile(); }
DEF_TEST(ColorSpace_sRGB, r) { test_space(r, sk_srgb_singleton(), g_sRGB_R, g_sRGB_G, g_sRGB_B, true); }
DEF_TEST(ColorSpace_skcms_sRGB_exact, r) { skcms_ICCProfile profile; sk_srgb_singleton()->toProfile(&profile); REPORTER_ASSERT(r, 0 == memcmp(&profile, skcms_sRGB_profile(), sizeof(skcms_ICCProfile))); }
sk_sp<SkColorSpace> SkColorSpace::MakeSRGB() { return sk_ref_sp(sk_srgb_singleton()); }
bool SkColorSpace::isSRGB() const { return sk_srgb_singleton() == this; }
// Even with kEntirePaint_Bits, we always ensure that the master paint's // text-encoding is respected, since that controls how we interpret the // text/length parameters of a draw[Pos]Text call. void SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo( SkPaint* dst, const SkPaint& src, const LayerInfo& info) { SkColor4f srcColor = src.getColor4f(); #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK // The framework may respect the alpha value on the original paint. // Match this legacy behavior. if (src.getAlpha() == 255) { srcColor.fA = dst->getColor4f().fA; } #endif dst->setColor4f(xferColor(srcColor, dst->getColor4f(), (SkBlendMode)info.fColorMode), sk_srgb_singleton()); BitFlags bits = info.fPaintBits; SkPaint::TextEncoding encoding = dst->getTextEncoding(); if (0 == bits) { return; } if (kEntirePaint_Bits == bits) { // we've already computed these, so save it from the assignment uint32_t f = dst->getFlags(); SkColor4f c = dst->getColor4f(); *dst = src; dst->setFlags(f); dst->setColor4f(c, sk_srgb_singleton()); dst->setTextEncoding(encoding); return; } if (bits & kStyle_Bit) { dst->setStyle(src.getStyle()); dst->setStrokeWidth(src.getStrokeWidth()); dst->setStrokeMiter(src.getStrokeMiter()); dst->setStrokeCap(src.getStrokeCap()); dst->setStrokeJoin(src.getStrokeJoin()); } if (bits & kTextSkewX_Bit) { dst->setTextSkewX(src.getTextSkewX()); } if (bits & kPathEffect_Bit) { dst->setPathEffect(src.refPathEffect()); } if (bits & kMaskFilter_Bit) { dst->setMaskFilter(src.refMaskFilter()); } if (bits & kShader_Bit) { dst->setShader(src.refShader()); } if (bits & kColorFilter_Bit) { dst->setColorFilter(src.refColorFilter()); } if (bits & kXfermode_Bit) { dst->setBlendMode(src.getBlendMode()); } // we don't override these #if 0 dst->setTypeface(src.getTypeface()); dst->setTextSize(src.getTextSize()); dst->setTextScaleX(src.getTextScaleX()); dst->setRasterizer(src.getRasterizer()); dst->setLooper(src.getLooper()); dst->setTextEncoding(src.getTextEncoding()); dst->setHinting(src.getHinting()); #endif }
void SkPaint::setColor4f(const SkColor4f& color, SkColorSpace* colorSpace) { SkColorSpaceXformSteps steps{colorSpace, kUnpremul_SkAlphaType, sk_srgb_singleton(), kUnpremul_SkAlphaType}; fColor4f = color; steps.apply(fColor4f.vec()); }