LCOV - code coverage report
Current view: top level - gfx/2d - HelpersSkia.h (source / functions) Hit Total Coverage
Test: output.info Lines: 68 136 50.0 %
Date: 2017-07-14 16:53:18 Functions: 18 22 81.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef MOZILLA_GFX_HELPERSSKIA_H_
       7             : #define MOZILLA_GFX_HELPERSSKIA_H_
       8             : 
       9             : #include "2D.h"
      10             : #include "skia/include/core/SkCanvas.h"
      11             : #include "skia/include/effects/SkDashPathEffect.h"
      12             : #include "skia/include/core/SkShader.h"
      13             : #ifdef USE_SKIA_GPU
      14             : #include "skia/include/gpu/GrTypes.h"
      15             : #endif
      16             : #include "mozilla/Assertions.h"
      17             : #include <vector>
      18             : #include "nsDebug.h"
      19             : 
      20             : namespace mozilla {
      21             : namespace gfx {
      22             : 
      23             : static inline SkColorType
      24         154 : GfxFormatToSkiaColorType(SurfaceFormat format)
      25             : {
      26         154 :   switch (format)
      27             :   {
      28             :     case SurfaceFormat::B8G8R8A8:
      29         117 :       return kBGRA_8888_SkColorType;
      30             :     case SurfaceFormat::B8G8R8X8:
      31             :       // We probably need to do something here.
      32          33 :       return kBGRA_8888_SkColorType;
      33             :     case SurfaceFormat::R5G6B5_UINT16:
      34           0 :       return kRGB_565_SkColorType;
      35             :     case SurfaceFormat::A8:
      36           4 :       return kAlpha_8_SkColorType;
      37             :     default:
      38           0 :       return kRGBA_8888_SkColorType;
      39             :   }
      40             : }
      41             : 
      42             : static inline SurfaceFormat
      43          18 : SkiaColorTypeToGfxFormat(SkColorType aColorType, SkAlphaType aAlphaType = kPremul_SkAlphaType)
      44             : {
      45          18 :   switch (aColorType)
      46             :   {
      47             :     case kBGRA_8888_SkColorType:
      48          18 :       return aAlphaType == kOpaque_SkAlphaType ?
      49          18 :                SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8;
      50             :     case kRGB_565_SkColorType:
      51           0 :       return SurfaceFormat::R5G6B5_UINT16;
      52             :     case kAlpha_8_SkColorType:
      53           0 :       return SurfaceFormat::A8;
      54             :     default:
      55           0 :       return SurfaceFormat::B8G8R8A8;
      56             :   }
      57             : }
      58             : 
      59             : static inline SkAlphaType
      60         390 : GfxFormatToSkiaAlphaType(SurfaceFormat format)
      61             : {
      62         390 :   switch (format)
      63             :   {
      64             :     case SurfaceFormat::B8G8R8X8:
      65             :     case SurfaceFormat::R5G6B5_UINT16:
      66          61 :       return kOpaque_SkAlphaType;
      67             :     default:
      68         329 :       return kPremul_SkAlphaType;
      69             :   }
      70             : }
      71             : 
      72             : static inline SkImageInfo
      73         154 : MakeSkiaImageInfo(const IntSize& aSize, SurfaceFormat aFormat)
      74             : {
      75         154 :   return SkImageInfo::Make(aSize.width, aSize.height,
      76             :                            GfxFormatToSkiaColorType(aFormat),
      77         308 :                            GfxFormatToSkiaAlphaType(aFormat));
      78             : }
      79             : 
      80             : #ifdef USE_SKIA_GPU
      81             : static inline GrPixelConfig
      82           0 : GfxFormatToGrConfig(SurfaceFormat format)
      83             : {
      84           0 :   switch (format)
      85             :   {
      86             :     case SurfaceFormat::B8G8R8A8:
      87           0 :       return kBGRA_8888_GrPixelConfig;
      88             :     case SurfaceFormat::B8G8R8X8:
      89             :       // We probably need to do something here.
      90           0 :       return kBGRA_8888_GrPixelConfig;
      91             :     case SurfaceFormat::R5G6B5_UINT16:
      92           0 :       return kRGB_565_GrPixelConfig;
      93             :     case SurfaceFormat::A8:
      94           0 :       return kAlpha_8_GrPixelConfig;
      95             :     default:
      96           0 :       return kRGBA_8888_GrPixelConfig;
      97             :   }
      98             : 
      99             : }
     100             : #endif
     101             : static inline void
     102        2160 : GfxMatrixToSkiaMatrix(const Matrix& mat, SkMatrix& retval)
     103             : {
     104        2160 :     retval.setAll(SkFloatToScalar(mat._11), SkFloatToScalar(mat._21), SkFloatToScalar(mat._31),
     105        2160 :                   SkFloatToScalar(mat._12), SkFloatToScalar(mat._22), SkFloatToScalar(mat._32),
     106        2160 :                   0, 0, SK_Scalar1);
     107        2160 : }
     108             : 
     109             : static inline void
     110           0 : GfxMatrixToSkiaMatrix(const Matrix4x4& aMatrix, SkMatrix& aResult)
     111             : {
     112           0 :   aResult.setAll(SkFloatToScalar(aMatrix._11), SkFloatToScalar(aMatrix._21), SkFloatToScalar(aMatrix._41),
     113           0 :                  SkFloatToScalar(aMatrix._12), SkFloatToScalar(aMatrix._22), SkFloatToScalar(aMatrix._42),
     114           0 :                  SkFloatToScalar(aMatrix._14), SkFloatToScalar(aMatrix._24), SkFloatToScalar(aMatrix._44));
     115           0 : }
     116             : 
     117             : static inline SkPaint::Cap
     118          15 : CapStyleToSkiaCap(CapStyle aCap)
     119             : {
     120          15 :   switch (aCap)
     121             :   {
     122             :     case CapStyle::BUTT:
     123          15 :       return SkPaint::kButt_Cap;
     124             :     case CapStyle::ROUND:
     125           0 :       return SkPaint::kRound_Cap;
     126             :     case CapStyle::SQUARE:
     127           0 :       return SkPaint::kSquare_Cap;
     128             :   }
     129           0 :   return SkPaint::kDefault_Cap;
     130             : }
     131             : 
     132             : static inline SkPaint::Join
     133          15 : JoinStyleToSkiaJoin(JoinStyle aJoin)
     134             : {
     135          15 :   switch (aJoin)
     136             :   {
     137             :     case JoinStyle::BEVEL:
     138           0 :       return SkPaint::kBevel_Join;
     139             :     case JoinStyle::ROUND:
     140           0 :       return SkPaint::kRound_Join;
     141             :     case JoinStyle::MITER:
     142             :     case JoinStyle::MITER_OR_BEVEL:
     143          15 :       return SkPaint::kMiter_Join;
     144             :   }
     145           0 :   return SkPaint::kDefault_Join;
     146             : }
     147             : 
     148             : static inline bool
     149          15 : StrokeOptionsToPaint(SkPaint& aPaint, const StrokeOptions &aOptions)
     150             : {
     151             :   // Skia renders 0 width strokes with a width of 1 (and in black),
     152             :   // so we should just skip the draw call entirely.
     153             :   // Skia does not handle non-finite line widths.
     154          15 :   if (!aOptions.mLineWidth || !IsFinite(aOptions.mLineWidth)) {
     155           0 :     return false;
     156             :   }
     157          15 :   aPaint.setStrokeWidth(SkFloatToScalar(aOptions.mLineWidth));
     158          15 :   aPaint.setStrokeMiter(SkFloatToScalar(aOptions.mMiterLimit));
     159          15 :   aPaint.setStrokeCap(CapStyleToSkiaCap(aOptions.mLineCap));
     160          15 :   aPaint.setStrokeJoin(JoinStyleToSkiaJoin(aOptions.mLineJoin));
     161             : 
     162          15 :   if (aOptions.mDashLength > 0) {
     163             :     // Skia only supports dash arrays that are multiples of 2.
     164             :     uint32_t dashCount;
     165             : 
     166           0 :     if (aOptions.mDashLength % 2 == 0) {
     167           0 :       dashCount = aOptions.mDashLength;
     168             :     } else {
     169           0 :       dashCount = aOptions.mDashLength * 2;
     170             :     }
     171             : 
     172           0 :     std::vector<SkScalar> pattern;
     173           0 :     pattern.resize(dashCount);
     174             : 
     175           0 :     for (uint32_t i = 0; i < dashCount; i++) {
     176           0 :       pattern[i] = SkFloatToScalar(aOptions.mDashPattern[i % aOptions.mDashLength]);
     177             :     }
     178             : 
     179           0 :     sk_sp<SkPathEffect> dash = SkDashPathEffect::Make(&pattern.front(),
     180             :                                                       dashCount,
     181           0 :                                                       SkFloatToScalar(aOptions.mDashOffset));
     182           0 :     aPaint.setPathEffect(dash);
     183             :   }
     184             : 
     185          15 :   aPaint.setStyle(SkPaint::kStroke_Style);
     186          15 :   return true;
     187             : }
     188             : 
     189             : static inline SkBlendMode
     190         424 : GfxOpToSkiaOp(CompositionOp op)
     191             : {
     192         424 :   switch (op)
     193             :   {
     194             :     case CompositionOp::OP_OVER:
     195         410 :       return SkBlendMode::kSrcOver;
     196             :     case CompositionOp::OP_ADD:
     197           0 :       return SkBlendMode::kPlus;
     198             :     case CompositionOp::OP_ATOP:
     199           0 :       return SkBlendMode::kSrcATop;
     200             :     case CompositionOp::OP_OUT:
     201           0 :       return SkBlendMode::kSrcOut;
     202             :     case CompositionOp::OP_IN:
     203           0 :       return SkBlendMode::kSrcIn;
     204             :     case CompositionOp::OP_SOURCE:
     205          14 :       return SkBlendMode::kSrc;
     206             :     case CompositionOp::OP_DEST_IN:
     207           0 :       return SkBlendMode::kDstIn;
     208             :     case CompositionOp::OP_DEST_OUT:
     209           0 :       return SkBlendMode::kDstOut;
     210             :     case CompositionOp::OP_DEST_OVER:
     211           0 :       return SkBlendMode::kDstOver;
     212             :     case CompositionOp::OP_DEST_ATOP:
     213           0 :       return SkBlendMode::kDstATop;
     214             :     case CompositionOp::OP_XOR:
     215           0 :       return SkBlendMode::kXor;
     216             :     case CompositionOp::OP_MULTIPLY:
     217           0 :       return SkBlendMode::kMultiply;
     218             :     case CompositionOp::OP_SCREEN:
     219           0 :       return SkBlendMode::kScreen;
     220             :     case CompositionOp::OP_OVERLAY:
     221           0 :       return SkBlendMode::kOverlay;
     222             :     case CompositionOp::OP_DARKEN:
     223           0 :       return SkBlendMode::kDarken;
     224             :     case CompositionOp::OP_LIGHTEN:
     225           0 :       return SkBlendMode::kLighten;
     226             :     case CompositionOp::OP_COLOR_DODGE:
     227           0 :       return SkBlendMode::kColorDodge;
     228             :     case CompositionOp::OP_COLOR_BURN:
     229           0 :       return SkBlendMode::kColorBurn;
     230             :     case CompositionOp::OP_HARD_LIGHT:
     231           0 :       return SkBlendMode::kHardLight;
     232             :     case CompositionOp::OP_SOFT_LIGHT:
     233           0 :       return SkBlendMode::kSoftLight;
     234             :     case CompositionOp::OP_DIFFERENCE:
     235           0 :       return SkBlendMode::kDifference;
     236             :     case CompositionOp::OP_EXCLUSION:
     237           0 :       return SkBlendMode::kExclusion;
     238             :     case CompositionOp::OP_HUE:
     239           0 :       return SkBlendMode::kHue;
     240             :     case CompositionOp::OP_SATURATION:
     241           0 :       return SkBlendMode::kSaturation;
     242             :     case CompositionOp::OP_COLOR:
     243           0 :       return SkBlendMode::kColor;
     244             :     case CompositionOp::OP_LUMINOSITY:
     245           0 :       return SkBlendMode::kLuminosity;
     246             :     default:
     247           0 :       return SkBlendMode::kSrcOver;
     248             :   }
     249             : }
     250             : 
     251             : /* There's quite a bit of inconsistency about
     252             :  * whether float colors should be rounded with .5f.
     253             :  * We choose to do it to match cairo which also
     254             :  * happens to match the Direct3D specs */
     255        1126 : static inline U8CPU ColorFloatToByte(Float color)
     256             : {
     257             :   //XXX: do a better job converting to int
     258        1126 :   return U8CPU(color*255.f + .5f);
     259             : };
     260             : 
     261         170 : static inline SkColor ColorToSkColor(const Color &color, Float aAlpha)
     262             : {
     263         170 :   return SkColorSetARGB(ColorFloatToByte(color.a*aAlpha), ColorFloatToByte(color.r),
     264             :                         ColorFloatToByte(color.g), ColorFloatToByte(color.b));
     265             : }
     266             : 
     267             : static inline SkPoint
     268           0 : PointToSkPoint(const Point &aPoint)
     269             : {
     270           0 :   return SkPoint::Make(SkFloatToScalar(aPoint.x), SkFloatToScalar(aPoint.y));
     271             : }
     272             : 
     273             : static inline SkRect
     274        1008 : RectToSkRect(const Rect& aRect)
     275             : {
     276        1008 :   return SkRect::MakeXYWH(SkFloatToScalar(aRect.x), SkFloatToScalar(aRect.y),
     277        2016 :                           SkFloatToScalar(aRect.width), SkFloatToScalar(aRect.height));
     278             : }
     279             : 
     280             : static inline SkRect
     281          22 : IntRectToSkRect(const IntRect& aRect)
     282             : {
     283          44 :   return SkRect::MakeXYWH(SkIntToScalar(aRect.x), SkIntToScalar(aRect.y),
     284          66 :                           SkIntToScalar(aRect.width), SkIntToScalar(aRect.height));
     285             : }
     286             : 
     287             : static inline SkIRect
     288             : RectToSkIRect(const Rect& aRect)
     289             : {
     290             :   return SkIRect::MakeXYWH(int32_t(aRect.x), int32_t(aRect.y),
     291             :                            int32_t(aRect.width), int32_t(aRect.height));
     292             : }
     293             : 
     294             : static inline SkIRect
     295         124 : IntRectToSkIRect(const IntRect& aRect)
     296             : {
     297         124 :   return SkIRect::MakeXYWH(aRect.x, aRect.y, aRect.width, aRect.height);
     298             : }
     299             : 
     300             : static inline IntRect
     301           0 : SkIRectToIntRect(const SkIRect& aRect)
     302             : {
     303           0 :   return IntRect(aRect.x(), aRect.y(), aRect.width(), aRect.height());
     304             : }
     305             : 
     306             : static inline Point
     307         112 : SkPointToPoint(const SkPoint &aPoint)
     308             : {
     309         112 :   return Point(SkScalarToFloat(aPoint.x()), SkScalarToFloat(aPoint.y()));
     310             : }
     311             : 
     312             : static inline Rect
     313         112 : SkRectToRect(const SkRect &aRect)
     314             : {
     315         224 :   return Rect(SkScalarToFloat(aRect.x()), SkScalarToFloat(aRect.y()),
     316         336 :               SkScalarToFloat(aRect.width()), SkScalarToFloat(aRect.height()));
     317             : }
     318             : 
     319             : static inline SkShader::TileMode
     320         223 : ExtendModeToTileMode(ExtendMode aMode, Axis aAxis)
     321             : {
     322         223 :   switch (aMode)
     323             :   {
     324             :     case ExtendMode::CLAMP:
     325         117 :       return SkShader::kClamp_TileMode;
     326             :     case ExtendMode::REPEAT:
     327          90 :       return SkShader::kRepeat_TileMode;
     328             :     case ExtendMode::REFLECT:
     329           0 :       return SkShader::kMirror_TileMode;
     330             :     case ExtendMode::REPEAT_X:
     331             :     {
     332             :       return aAxis == Axis::X_AXIS
     333          16 :              ? SkShader::kRepeat_TileMode
     334          16 :              : SkShader::kClamp_TileMode;
     335             :     }
     336             :     case ExtendMode::REPEAT_Y:
     337             :     {
     338             :       return aAxis == Axis::Y_AXIS
     339           0 :              ? SkShader::kRepeat_TileMode
     340           0 :              : SkShader::kClamp_TileMode;
     341             :     }
     342             :   }
     343           0 :   return SkShader::kClamp_TileMode;
     344             : }
     345             : 
     346             : static inline SkPaint::Hinting
     347             : GfxHintingToSkiaHinting(FontHinting aHinting)
     348             : {
     349             :   switch (aHinting) {
     350             :     case FontHinting::NONE:
     351             :       return SkPaint::kNo_Hinting;
     352             :     case FontHinting::LIGHT:
     353             :       return SkPaint::kSlight_Hinting;
     354             :     case FontHinting::NORMAL:
     355             :       return SkPaint::kNormal_Hinting;
     356             :     case FontHinting::FULL:
     357             :       return SkPaint::kFull_Hinting;
     358             :   }
     359             :   return SkPaint::kNormal_Hinting;
     360             : }
     361             : 
     362             : static inline FillRule GetFillRule(SkPath::FillType aFillType)
     363             : {
     364             :   switch (aFillType)
     365             :   {
     366             :   case SkPath::kWinding_FillType:
     367             :     return FillRule::FILL_WINDING;
     368             :   case SkPath::kEvenOdd_FillType:
     369             :     return FillRule::FILL_EVEN_ODD;
     370             :   case SkPath::kInverseWinding_FillType:
     371             :   case SkPath::kInverseEvenOdd_FillType:
     372             :   default:
     373             :     NS_WARNING("Unsupported fill type\n");
     374             :     break;
     375             :   }
     376             : 
     377             :   return FillRule::FILL_EVEN_ODD;
     378             : }
     379             : 
     380             : /**
     381             :  * Returns true if the canvas is backed by pixels.  Returns false if the canvas
     382             :  * wraps an SkPDFDocument, for example.
     383             :  *
     384             :  * Note: It is not clear whether the test used to implement this function may
     385             :  * result in it returning false in some circumstances even when the canvas
     386             :  * _is_ pixel backed.  In other words maybe it is possible for such a canvas to
     387             :  * have kUnknown_SkPixelGeometry?
     388             :  */
     389           3 : static inline bool IsBackedByPixels(const SkCanvas* aCanvas)
     390             : {
     391           3 :   SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
     392           6 :   if (!aCanvas->getProps(&props) ||
     393           3 :       props.pixelGeometry() == kUnknown_SkPixelGeometry) {
     394           0 :     return false;
     395             :   }
     396           3 :   return true;
     397             : }
     398             : 
     399             : } // namespace gfx
     400             : } // namespace mozilla
     401             : 
     402             : #endif /* MOZILLA_GFX_HELPERSSKIA_H_ */

Generated by: LCOV version 1.13