1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/2d/HelpersSkia.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,303 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef MOZILLA_GFX_HELPERSSKIA_H_ 1.10 +#define MOZILLA_GFX_HELPERSSKIA_H_ 1.11 + 1.12 +#include "2D.h" 1.13 +#include "skia/SkCanvas.h" 1.14 +#include "skia/SkDashPathEffect.h" 1.15 +#include "skia/SkShader.h" 1.16 +#ifdef USE_SKIA_GPU 1.17 +#include "skia/GrTypes.h" 1.18 +#endif 1.19 +#include "mozilla/Assertions.h" 1.20 +#include <vector> 1.21 + 1.22 +namespace mozilla { 1.23 +namespace gfx { 1.24 + 1.25 +static inline SkBitmap::Config 1.26 +GfxFormatToSkiaConfig(SurfaceFormat format) 1.27 +{ 1.28 + switch (format) 1.29 + { 1.30 + case SurfaceFormat::B8G8R8A8: 1.31 + return SkBitmap::kARGB_8888_Config; 1.32 + case SurfaceFormat::B8G8R8X8: 1.33 + // We probably need to do something here. 1.34 + return SkBitmap::kARGB_8888_Config; 1.35 + case SurfaceFormat::R5G6B5: 1.36 + return SkBitmap::kRGB_565_Config; 1.37 + case SurfaceFormat::A8: 1.38 + return SkBitmap::kA8_Config; 1.39 + default: 1.40 + return SkBitmap::kARGB_8888_Config; 1.41 + } 1.42 +} 1.43 + 1.44 +static inline SkColorType 1.45 +GfxFormatToSkiaColorType(SurfaceFormat format) 1.46 +{ 1.47 + switch (format) 1.48 + { 1.49 + case SurfaceFormat::B8G8R8A8: 1.50 + return kBGRA_8888_SkColorType; 1.51 + case SurfaceFormat::B8G8R8X8: 1.52 + // We probably need to do something here. 1.53 + return kBGRA_8888_SkColorType; 1.54 + case SurfaceFormat::R5G6B5: 1.55 + return kRGB_565_SkColorType; 1.56 + case SurfaceFormat::A8: 1.57 + return kAlpha_8_SkColorType; 1.58 + default: 1.59 + return kRGBA_8888_SkColorType; 1.60 + } 1.61 +} 1.62 + 1.63 +static inline SurfaceFormat 1.64 +SkiaConfigToGfxFormat(SkBitmap::Config config) 1.65 +{ 1.66 + switch (config) 1.67 + { 1.68 + case SkBitmap::kARGB_8888_Config: 1.69 + return SurfaceFormat::B8G8R8A8; 1.70 + case SkBitmap::kRGB_565_Config: 1.71 + return SurfaceFormat::R5G6B5; 1.72 + case SkBitmap::kA8_Config: 1.73 + return SurfaceFormat::A8; 1.74 + default: 1.75 + return SurfaceFormat::B8G8R8A8; 1.76 + } 1.77 +} 1.78 + 1.79 +#ifdef USE_SKIA_GPU 1.80 +static inline GrPixelConfig 1.81 +GfxFormatToGrConfig(SurfaceFormat format) 1.82 +{ 1.83 + switch (format) 1.84 + { 1.85 + case SurfaceFormat::B8G8R8A8: 1.86 + return kBGRA_8888_GrPixelConfig; 1.87 + case SurfaceFormat::B8G8R8X8: 1.88 + // We probably need to do something here. 1.89 + return kBGRA_8888_GrPixelConfig; 1.90 + case SurfaceFormat::R5G6B5: 1.91 + return kRGB_565_GrPixelConfig; 1.92 + case SurfaceFormat::A8: 1.93 + return kAlpha_8_GrPixelConfig; 1.94 + default: 1.95 + return kRGBA_8888_GrPixelConfig; 1.96 + } 1.97 + 1.98 +} 1.99 +#endif 1.100 +static inline void 1.101 +GfxMatrixToSkiaMatrix(const Matrix& mat, SkMatrix& retval) 1.102 +{ 1.103 + retval.setAll(SkFloatToScalar(mat._11), SkFloatToScalar(mat._21), SkFloatToScalar(mat._31), 1.104 + SkFloatToScalar(mat._12), SkFloatToScalar(mat._22), SkFloatToScalar(mat._32), 1.105 + 0, 0, SK_Scalar1); 1.106 +} 1.107 + 1.108 +static inline SkPaint::Cap 1.109 +CapStyleToSkiaCap(CapStyle aCap) 1.110 +{ 1.111 + switch (aCap) 1.112 + { 1.113 + case CapStyle::BUTT: 1.114 + return SkPaint::kButt_Cap; 1.115 + case CapStyle::ROUND: 1.116 + return SkPaint::kRound_Cap; 1.117 + case CapStyle::SQUARE: 1.118 + return SkPaint::kSquare_Cap; 1.119 + } 1.120 + return SkPaint::kDefault_Cap; 1.121 +} 1.122 + 1.123 +static inline SkPaint::Join 1.124 +JoinStyleToSkiaJoin(JoinStyle aJoin) 1.125 +{ 1.126 + switch (aJoin) 1.127 + { 1.128 + case JoinStyle::BEVEL: 1.129 + return SkPaint::kBevel_Join; 1.130 + case JoinStyle::ROUND: 1.131 + return SkPaint::kRound_Join; 1.132 + case JoinStyle::MITER: 1.133 + case JoinStyle::MITER_OR_BEVEL: 1.134 + return SkPaint::kMiter_Join; 1.135 + } 1.136 + return SkPaint::kDefault_Join; 1.137 +} 1.138 + 1.139 +static inline bool 1.140 +StrokeOptionsToPaint(SkPaint& aPaint, const StrokeOptions &aOptions) 1.141 +{ 1.142 + // Skia renders 0 width strokes with a width of 1 (and in black), 1.143 + // so we should just skip the draw call entirely. 1.144 + if (!aOptions.mLineWidth) { 1.145 + return false; 1.146 + } 1.147 + aPaint.setStrokeWidth(SkFloatToScalar(aOptions.mLineWidth)); 1.148 + aPaint.setStrokeMiter(SkFloatToScalar(aOptions.mMiterLimit)); 1.149 + aPaint.setStrokeCap(CapStyleToSkiaCap(aOptions.mLineCap)); 1.150 + aPaint.setStrokeJoin(JoinStyleToSkiaJoin(aOptions.mLineJoin)); 1.151 + 1.152 + if (aOptions.mDashLength > 0) { 1.153 + // Skia only supports dash arrays that are multiples of 2. 1.154 + uint32_t dashCount; 1.155 + 1.156 + if (aOptions.mDashLength % 2 == 0) { 1.157 + dashCount = aOptions.mDashLength; 1.158 + } else { 1.159 + dashCount = aOptions.mDashLength * 2; 1.160 + } 1.161 + 1.162 + std::vector<SkScalar> pattern; 1.163 + pattern.resize(dashCount); 1.164 + 1.165 + for (uint32_t i = 0; i < dashCount; i++) { 1.166 + pattern[i] = SkFloatToScalar(aOptions.mDashPattern[i % aOptions.mDashLength]); 1.167 + } 1.168 + 1.169 + SkDashPathEffect* dash = SkDashPathEffect::Create(&pattern.front(), 1.170 + dashCount, 1.171 + SkFloatToScalar(aOptions.mDashOffset)); 1.172 + SkSafeUnref(aPaint.setPathEffect(dash)); 1.173 + } 1.174 + 1.175 + aPaint.setStyle(SkPaint::kStroke_Style); 1.176 + return true; 1.177 +} 1.178 + 1.179 +static inline SkXfermode::Mode 1.180 +GfxOpToSkiaOp(CompositionOp op) 1.181 +{ 1.182 + switch (op) 1.183 + { 1.184 + case CompositionOp::OP_OVER: 1.185 + return SkXfermode::kSrcOver_Mode; 1.186 + case CompositionOp::OP_ADD: 1.187 + return SkXfermode::kPlus_Mode; 1.188 + case CompositionOp::OP_ATOP: 1.189 + return SkXfermode::kSrcATop_Mode; 1.190 + case CompositionOp::OP_OUT: 1.191 + return SkXfermode::kSrcOut_Mode; 1.192 + case CompositionOp::OP_IN: 1.193 + return SkXfermode::kSrcIn_Mode; 1.194 + case CompositionOp::OP_SOURCE: 1.195 + return SkXfermode::kSrc_Mode; 1.196 + case CompositionOp::OP_DEST_IN: 1.197 + return SkXfermode::kDstIn_Mode; 1.198 + case CompositionOp::OP_DEST_OUT: 1.199 + return SkXfermode::kDstOut_Mode; 1.200 + case CompositionOp::OP_DEST_OVER: 1.201 + return SkXfermode::kDstOver_Mode; 1.202 + case CompositionOp::OP_DEST_ATOP: 1.203 + return SkXfermode::kDstATop_Mode; 1.204 + case CompositionOp::OP_XOR: 1.205 + return SkXfermode::kXor_Mode; 1.206 + case CompositionOp::OP_MULTIPLY: 1.207 + return SkXfermode::kMultiply_Mode; 1.208 + case CompositionOp::OP_SCREEN: 1.209 + return SkXfermode::kScreen_Mode; 1.210 + case CompositionOp::OP_OVERLAY: 1.211 + return SkXfermode::kOverlay_Mode; 1.212 + case CompositionOp::OP_DARKEN: 1.213 + return SkXfermode::kDarken_Mode; 1.214 + case CompositionOp::OP_LIGHTEN: 1.215 + return SkXfermode::kLighten_Mode; 1.216 + case CompositionOp::OP_COLOR_DODGE: 1.217 + return SkXfermode::kColorDodge_Mode; 1.218 + case CompositionOp::OP_COLOR_BURN: 1.219 + return SkXfermode::kColorBurn_Mode; 1.220 + case CompositionOp::OP_HARD_LIGHT: 1.221 + return SkXfermode::kHardLight_Mode; 1.222 + case CompositionOp::OP_SOFT_LIGHT: 1.223 + return SkXfermode::kSoftLight_Mode; 1.224 + case CompositionOp::OP_DIFFERENCE: 1.225 + return SkXfermode::kDifference_Mode; 1.226 + case CompositionOp::OP_EXCLUSION: 1.227 + return SkXfermode::kExclusion_Mode; 1.228 + case CompositionOp::OP_HUE: 1.229 + return SkXfermode::kHue_Mode; 1.230 + case CompositionOp::OP_SATURATION: 1.231 + return SkXfermode::kSaturation_Mode; 1.232 + case CompositionOp::OP_COLOR: 1.233 + return SkXfermode::kColor_Mode; 1.234 + case CompositionOp::OP_LUMINOSITY: 1.235 + return SkXfermode::kLuminosity_Mode; 1.236 + default: 1.237 + return SkXfermode::kSrcOver_Mode; 1.238 + } 1.239 +} 1.240 + 1.241 +static inline SkColor ColorToSkColor(const Color &color, Float aAlpha) 1.242 +{ 1.243 + //XXX: do a better job converting to int 1.244 + return SkColorSetARGB(U8CPU(color.a*aAlpha*255.0), U8CPU(color.r*255.0), 1.245 + U8CPU(color.g*255.0), U8CPU(color.b*255.0)); 1.246 +} 1.247 + 1.248 +static inline SkRect 1.249 +RectToSkRect(const Rect& aRect) 1.250 +{ 1.251 + return SkRect::MakeXYWH(SkFloatToScalar(aRect.x), SkFloatToScalar(aRect.y), 1.252 + SkFloatToScalar(aRect.width), SkFloatToScalar(aRect.height)); 1.253 +} 1.254 + 1.255 +static inline SkRect 1.256 +IntRectToSkRect(const IntRect& aRect) 1.257 +{ 1.258 + return SkRect::MakeXYWH(SkIntToScalar(aRect.x), SkIntToScalar(aRect.y), 1.259 + SkIntToScalar(aRect.width), SkIntToScalar(aRect.height)); 1.260 +} 1.261 + 1.262 +static inline SkIRect 1.263 +RectToSkIRect(const Rect& aRect) 1.264 +{ 1.265 + return SkIRect::MakeXYWH(int32_t(aRect.x), int32_t(aRect.y), 1.266 + int32_t(aRect.width), int32_t(aRect.height)); 1.267 +} 1.268 + 1.269 +static inline SkIRect 1.270 +IntRectToSkIRect(const IntRect& aRect) 1.271 +{ 1.272 + return SkIRect::MakeXYWH(aRect.x, aRect.y, aRect.width, aRect.height); 1.273 +} 1.274 + 1.275 +static inline Point 1.276 +SkPointToPoint(const SkPoint &aPoint) 1.277 +{ 1.278 + return Point(SkScalarToFloat(aPoint.x()), SkScalarToFloat(aPoint.y())); 1.279 +} 1.280 + 1.281 +static inline Rect 1.282 +SkRectToRect(const SkRect &aRect) 1.283 +{ 1.284 + return Rect(SkScalarToFloat(aRect.x()), SkScalarToFloat(aRect.y()), 1.285 + SkScalarToFloat(aRect.width()), SkScalarToFloat(aRect.height())); 1.286 +} 1.287 + 1.288 +static inline SkShader::TileMode 1.289 +ExtendModeToTileMode(ExtendMode aMode) 1.290 +{ 1.291 + switch (aMode) 1.292 + { 1.293 + case ExtendMode::CLAMP: 1.294 + return SkShader::kClamp_TileMode; 1.295 + case ExtendMode::REPEAT: 1.296 + return SkShader::kRepeat_TileMode; 1.297 + case ExtendMode::REFLECT: 1.298 + return SkShader::kMirror_TileMode; 1.299 + } 1.300 + return SkShader::kClamp_TileMode; 1.301 +} 1.302 + 1.303 +} 1.304 +} 1.305 + 1.306 +#endif /* MOZILLA_GFX_HELPERSSKIA_H_ */