diff --git a/include/core/SkLights.h b/include/core/SkLights.h index d91d91935d..5c6648751d 100644 --- a/include/core/SkLights.h +++ b/include/core/SkLights.h @@ -113,6 +113,8 @@ public: bool operator!= (const Light& b) { return !(this->operator==(b)); } private: + friend class SkLights; + LightType fType; SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel. @@ -191,6 +193,10 @@ private: SkLights() { fAmbientLightColor.set(0.0f, 0.0f, 0.0f); } + + friend class SkLightingShaderImpl; + sk_sp makeColorSpace(SkColorSpaceXformer* xformer) const; + SkTArray fLights; SkColor3f fAmbientLightColor; typedef SkRefCnt INHERITED; diff --git a/include/core/SkShader.h b/include/core/SkShader.h index b3b5faaa1f..ba61314f77 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -517,7 +517,9 @@ private: friend class SkLocalMatrixShader; friend class SkBitmapProcLegacyShader; // for computeTotalInverse() friend class SkComposeShader; + friend class SkColorFilterShader; friend class SkColorSpaceXformer; + friend class SkLightingShaderImpl; typedef SkFlattenable INHERITED; }; diff --git a/src/core/SkColorFilterShader.cpp b/src/core/SkColorFilterShader.cpp index 5e96b24b41..bfe74611cd 100644 --- a/src/core/SkColorFilterShader.cpp +++ b/src/core/SkColorFilterShader.cpp @@ -7,6 +7,7 @@ #include "SkArenaAlloc.h" #include "SkColorFilterShader.h" +#include "SkColorSpaceXformer.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" #include "SkShader.h" @@ -62,6 +63,9 @@ SkShader::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec, return alloc->make(*this, shaderContext, rec); } +sk_sp SkColorFilterShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const { + return fShader->makeColorSpace(xformer)->makeWithColorFilter(xformer->apply(fFilter.get())); +} SkColorFilterShader::FilterShaderContext::FilterShaderContext( const SkColorFilterShader& filterShader, diff --git a/src/core/SkColorFilterShader.h b/src/core/SkColorFilterShader.h index e697736ae8..18f65ba67f 100644 --- a/src/core/SkColorFilterShader.h +++ b/src/core/SkColorFilterShader.h @@ -48,6 +48,7 @@ public: protected: void flatten(SkWriteBuffer&) const override; Context* onMakeContext(const ContextRec&, SkArenaAlloc* alloc) const override; + sk_sp onMakeColorSpace(SkColorSpaceXformer* xformer) const override; private: sk_sp fShader; diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp index 1c8b1b4f58..600134ded3 100644 --- a/src/core/SkLightingShader.cpp +++ b/src/core/SkLightingShader.cpp @@ -83,6 +83,7 @@ public: protected: void flatten(SkWriteBuffer&) const override; Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override; + sk_sp onMakeColorSpace(SkColorSpaceXformer* xformer) const override; private: sk_sp fDiffuseShader; @@ -455,6 +456,13 @@ SkShader::Context* SkLightingShaderImpl::onMakeContext( return alloc->make(*this, rec, diffuseContext, normalProvider, nullptr); } +sk_sp SkLightingShaderImpl::onMakeColorSpace(SkColorSpaceXformer* xformer) const { + sk_sp xformedDiffuseShader = + fDiffuseShader ? fDiffuseShader->makeColorSpace(xformer) : nullptr; + return SkLightingShader::Make(std::move(xformedDiffuseShader), fNormalSource, + fLights->makeColorSpace(xformer)); +} + /////////////////////////////////////////////////////////////////////////////// sk_sp SkLightingShader::Make(sk_sp diffuseShader, diff --git a/src/core/SkLights.cpp b/src/core/SkLights.cpp index 56c9299437..1073ba0b82 100644 --- a/src/core/SkLights.cpp +++ b/src/core/SkLights.cpp @@ -6,6 +6,7 @@ * found in the LICENSE file. */ +#include "SkColorSpaceXformer.h" #include "SkLights.h" #include "SkReadBuffer.h" @@ -59,6 +60,28 @@ sk_sp SkLights::MakeFromBuffer(SkReadBuffer& buf) { return builder.finish(); } +static SkColor3f xform_color(const SkColor3f& color, SkColorSpaceXformer* xformer) { + SkColor origColor = SkColorSetARGBInline(0xFF, + SkScalarRoundToInt(color.fX), + SkScalarRoundToInt(color.fY), + SkScalarRoundToInt(color.fZ)); + SkColor xformedColor = xformer->apply(origColor); + return SkColor3f::Make(SkIntToScalar(SkGetPackedR32(xformedColor)), + SkIntToScalar(SkGetPackedG32(xformedColor)), + SkIntToScalar(SkGetPackedB32(xformedColor))); +} + +sk_sp SkLights::makeColorSpace(SkColorSpaceXformer* xformer) const { + SkLights::Builder builder; + for (int i = 0; i < this->numLights(); i++) { + Light light(fLights[i].type(), xform_color(fLights[i].color(), xformer), + fLights[i].fDirOrPos, fLights[i].fIntensity, fLights[i].isRadial()); + builder.add(light); + } + builder.setAmbientLightColor(xform_color(fAmbientLightColor, xformer)); + return builder.finish(); +} + void SkLights::flatten(SkWriteBuffer& buf) const { buf.writeScalarArray(&this->ambientLightColor().fX, 3);