LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkColorSpaceXformer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 88 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2017 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #include "SkColorFilter.h"
       9             : #include "SkColorSpaceXformer.h"
      10             : #include "SkColorSpaceXform_Base.h"
      11             : #include "SkDrawLooper.h"
      12             : #include "SkGradientShader.h"
      13             : #include "SkImage_Base.h"
      14             : #include "SkImageFilter.h"
      15             : #include "SkImagePriv.h"
      16             : #include "SkMakeUnique.h"
      17             : 
      18           0 : std::unique_ptr<SkColorSpaceXformer> SkColorSpaceXformer::Make(sk_sp<SkColorSpace> dst) {
      19             :     std::unique_ptr<SkColorSpaceXform> fromSRGB = SkColorSpaceXform_Base::New(
      20           0 :             SkColorSpace::MakeSRGB().get(), dst.get(), SkTransferFunctionBehavior::kIgnore);
      21           0 :     if (!fromSRGB) {
      22           0 :         return nullptr;
      23             :     }
      24             : 
      25           0 :     auto xformer = std::unique_ptr<SkColorSpaceXformer>(new SkColorSpaceXformer());
      26           0 :     xformer->fDst      = std::move(dst);
      27           0 :     xformer->fFromSRGB = std::move(fromSRGB);
      28           0 :     return xformer;
      29             : }
      30             : 
      31           0 : sk_sp<SkImage> SkColorSpaceXformer::apply(const SkImage* src) {
      32           0 :     return src->makeColorSpace(fDst, SkTransferFunctionBehavior::kIgnore);
      33             : }
      34             : 
      35           0 : sk_sp<SkImage> SkColorSpaceXformer::apply(const SkBitmap& src) {
      36           0 :     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(src, kNever_SkCopyPixelsMode);
      37           0 :     if (!image) {
      38           0 :         return nullptr;
      39             :     }
      40             : 
      41           0 :     sk_sp<SkImage> xformed = image->makeColorSpace(fDst, SkTransferFunctionBehavior::kIgnore);
      42             :     // We want to be sure we don't let the kNever_SkCopyPixelsMode image escape this stack frame.
      43           0 :     SkASSERT(xformed != image);
      44           0 :     return xformed;
      45             : }
      46             : 
      47             : // As far as I know, SkModeColorFilter is the only color filter that holds a color.
      48           0 : sk_sp<SkColorFilter> SkColorSpaceXformer::apply(const SkColorFilter* colorFilter) {
      49             :     SkColor color;
      50             :     SkBlendMode mode;
      51           0 :     if (colorFilter->asColorMode(&color, &mode)) {
      52           0 :         return SkColorFilter::MakeModeFilter(this->apply(color), mode);
      53             :     }
      54             : 
      55           0 :     return sk_ref_sp(const_cast<SkColorFilter*>(colorFilter));
      56             : }
      57             : 
      58           0 : void SkColorSpaceXformer::apply(SkColor* xformed, const SkColor* srgb, int n) {
      59           0 :     SkAssertResult(fFromSRGB->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, xformed,
      60             :                                     SkColorSpaceXform::kBGRA_8888_ColorFormat, srgb,
      61             :                                     n, kUnpremul_SkAlphaType));
      62           0 : }
      63             : 
      64           0 : SkColor SkColorSpaceXformer::apply(SkColor srgb) {
      65             :     SkColor xformed;
      66           0 :     this->apply(&xformed, &srgb, 1);
      67           0 :     return xformed;
      68             : }
      69             : 
      70             : // TODO: Is this introspection going to be enough, or do we need a new SkShader method?
      71           0 : sk_sp<SkShader> SkColorSpaceXformer::apply(const SkShader* shader) {
      72             :     SkColor color;
      73           0 :     if (shader->isConstant() && shader->asLuminanceColor(&color)) {
      74           0 :         return SkShader::MakeColorShader(this->apply(color))
      75           0 :                 ->makeWithLocalMatrix(shader->getLocalMatrix());
      76             :     }
      77             : 
      78             :     SkShader::TileMode xy[2];
      79             :     SkMatrix local;
      80           0 :     if (auto img = shader->isAImage(&local, xy)) {
      81           0 :         return this->apply(img)->makeShader(xy[0], xy[1], &local);
      82             :     }
      83             : 
      84             :     SkShader::ComposeRec compose;
      85           0 :     if (shader->asACompose(&compose)) {
      86           0 :         auto A = this->apply(compose.fShaderA),
      87           0 :              B = this->apply(compose.fShaderB);
      88           0 :         if (A && B) {
      89           0 :             return SkShader::MakeComposeShader(std::move(A), std::move(B), compose.fBlendMode)
      90           0 :                     ->makeWithLocalMatrix(shader->getLocalMatrix());
      91             :         }
      92             :     }
      93             : 
      94             :     SkShader::GradientInfo gradient;
      95           0 :     sk_bzero(&gradient, sizeof(gradient));
      96           0 :     if (auto type = shader->asAGradient(&gradient)) {
      97           0 :         SkSTArray<8, SkColor>  colors(gradient.fColorCount);
      98           0 :         SkSTArray<8, SkScalar>    pos(gradient.fColorCount);
      99             : 
     100           0 :         gradient.fColors       = colors.begin();
     101           0 :         gradient.fColorOffsets =    pos.begin();
     102           0 :         shader->asAGradient(&gradient);
     103             : 
     104           0 :         SkSTArray<8, SkColor> xformed(gradient.fColorCount);
     105           0 :         this->apply(xformed.begin(), gradient.fColors, gradient.fColorCount);
     106             : 
     107           0 :         switch (type) {
     108             :             case SkShader::kNone_GradientType:
     109             :             case SkShader::kColor_GradientType:
     110           0 :                 SkASSERT(false);  // Should be unreachable.
     111           0 :                 break;
     112             : 
     113             :             case SkShader::kLinear_GradientType:
     114             :                 return SkGradientShader::MakeLinear(gradient.fPoint,
     115           0 :                                                     xformed.begin(),
     116           0 :                                                     gradient.fColorOffsets,
     117             :                                                     gradient.fColorCount,
     118             :                                                     gradient.fTileMode,
     119             :                                                     gradient.fGradientFlags,
     120           0 :                                                     &shader->getLocalMatrix());
     121             :             case SkShader::kRadial_GradientType:
     122             :                 return SkGradientShader::MakeRadial(gradient.fPoint[0],
     123             :                                                     gradient.fRadius[0],
     124           0 :                                                     xformed.begin(),
     125           0 :                                                     gradient.fColorOffsets,
     126             :                                                     gradient.fColorCount,
     127             :                                                     gradient.fTileMode,
     128             :                                                     gradient.fGradientFlags,
     129           0 :                                                     &shader->getLocalMatrix());
     130             :             case SkShader::kSweep_GradientType:
     131             :                 return SkGradientShader::MakeSweep(gradient.fPoint[0].fX,
     132             :                                                    gradient.fPoint[0].fY,
     133           0 :                                                    xformed.begin(),
     134           0 :                                                    gradient.fColorOffsets,
     135             :                                                    gradient.fColorCount,
     136             :                                                    gradient.fGradientFlags,
     137           0 :                                                    &shader->getLocalMatrix());
     138             :             case SkShader::kConical_GradientType:
     139             :                 return SkGradientShader::MakeTwoPointConical(gradient.fPoint[0],
     140             :                                                              gradient.fRadius[0],
     141             :                                                              gradient.fPoint[1],
     142             :                                                              gradient.fRadius[1],
     143           0 :                                                              xformed.begin(),
     144           0 :                                                              gradient.fColorOffsets,
     145             :                                                              gradient.fColorCount,
     146             :                                                              gradient.fTileMode,
     147             :                                                              gradient.fGradientFlags,
     148           0 :                                                              &shader->getLocalMatrix());
     149             :         }
     150             :     }
     151             : 
     152           0 :     return sk_ref_sp(const_cast<SkShader*>(shader));
     153             : }
     154             : 
     155           0 : const SkPaint& SkColorSpaceXformer::apply(const SkPaint& src) {
     156           0 :     const SkPaint* result = &src;
     157           0 :     auto get_dst = [&] {
     158           0 :         if (result == &src) {
     159           0 :             fDstPaint = src;
     160           0 :             result = &fDstPaint;
     161             :         }
     162           0 :         return &fDstPaint;
     163           0 :     };
     164             : 
     165             :     // All SkColorSpaces have the same black point.
     166           0 :     if (src.getColor() & 0xffffff) {
     167           0 :         get_dst()->setColor(this->apply(src.getColor()));
     168             :     }
     169             : 
     170           0 :     if (auto shader = src.getShader()) {
     171           0 :         if (auto replacement = this->apply(shader)) {
     172           0 :             get_dst()->setShader(std::move(replacement));
     173             :         }
     174             :     }
     175             : 
     176           0 :     if (auto cf = src.getColorFilter()) {
     177           0 :         auto replacement = this->apply(cf);
     178           0 :         if (replacement.get() != cf) {
     179           0 :             get_dst()->setColorFilter(std::move(replacement));
     180             :         }
     181             :     }
     182             : 
     183           0 :     if (auto looper = src.getDrawLooper()) {
     184           0 :         get_dst()->setDrawLooper(looper->makeColorSpace(this));
     185             :     }
     186             : 
     187           0 :     if (auto imageFilter = src.getImageFilter()) {
     188           0 :         get_dst()->setImageFilter(imageFilter->makeColorSpace(this));
     189             :     }
     190             : 
     191           0 :     return *result;
     192             : }
     193             : 
     194           0 : const SkPaint* SkColorSpaceXformer::apply(const SkPaint* src) {
     195           0 :     return src ? &this->apply(*src) : nullptr;
     196             : }

Generated by: LCOV version 1.13