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/. */
6 #ifndef MOZILLA_GFX_HELPERSSKIA_H_
7 #define MOZILLA_GFX_HELPERSSKIA_H_
10 #include "skia/SkCanvas.h"
11 #include "skia/SkDashPathEffect.h"
12 #include "skia/SkShader.h"
14 #include "skia/GrTypes.h"
16 #include "mozilla/Assertions.h"
22 static inline SkColorType
23 GfxFormatToSkiaColorType(SurfaceFormat format
)
27 case SurfaceFormat::B8G8R8A8
:
28 return kBGRA_8888_SkColorType
;
29 case SurfaceFormat::B8G8R8X8
:
30 // We probably need to do something here.
31 return kBGRA_8888_SkColorType
;
32 case SurfaceFormat::R5G6B5
:
33 return kRGB_565_SkColorType
;
34 case SurfaceFormat::A8
:
35 return kAlpha_8_SkColorType
;
37 return kRGBA_8888_SkColorType
;
41 static inline SurfaceFormat
42 SkiaColorTypeToGfxFormat(SkColorType type
)
46 case kBGRA_8888_SkColorType
:
47 return SurfaceFormat::B8G8R8A8
;
48 case kRGB_565_SkColorType
:
49 return SurfaceFormat::R5G6B5
;
50 case kAlpha_8_SkColorType
:
51 return SurfaceFormat::A8
;
53 return SurfaceFormat::B8G8R8A8
;
58 static inline GrPixelConfig
59 GfxFormatToGrConfig(SurfaceFormat format
)
63 case SurfaceFormat::B8G8R8A8
:
64 return kBGRA_8888_GrPixelConfig
;
65 case SurfaceFormat::B8G8R8X8
:
66 // We probably need to do something here.
67 return kBGRA_8888_GrPixelConfig
;
68 case SurfaceFormat::R5G6B5
:
69 return kRGB_565_GrPixelConfig
;
70 case SurfaceFormat::A8
:
71 return kAlpha_8_GrPixelConfig
;
73 return kRGBA_8888_GrPixelConfig
;
79 GfxMatrixToSkiaMatrix(const Matrix
& mat
, SkMatrix
& retval
)
81 retval
.setAll(SkFloatToScalar(mat
._11
), SkFloatToScalar(mat
._21
), SkFloatToScalar(mat
._31
),
82 SkFloatToScalar(mat
._12
), SkFloatToScalar(mat
._22
), SkFloatToScalar(mat
._32
),
86 static inline SkPaint::Cap
87 CapStyleToSkiaCap(CapStyle aCap
)
92 return SkPaint::kButt_Cap
;
94 return SkPaint::kRound_Cap
;
95 case CapStyle::SQUARE
:
96 return SkPaint::kSquare_Cap
;
98 return SkPaint::kDefault_Cap
;
101 static inline SkPaint::Join
102 JoinStyleToSkiaJoin(JoinStyle aJoin
)
106 case JoinStyle::BEVEL
:
107 return SkPaint::kBevel_Join
;
108 case JoinStyle::ROUND
:
109 return SkPaint::kRound_Join
;
110 case JoinStyle::MITER
:
111 case JoinStyle::MITER_OR_BEVEL
:
112 return SkPaint::kMiter_Join
;
114 return SkPaint::kDefault_Join
;
118 StrokeOptionsToPaint(SkPaint
& aPaint
, const StrokeOptions
&aOptions
)
120 // Skia renders 0 width strokes with a width of 1 (and in black),
121 // so we should just skip the draw call entirely.
122 if (!aOptions
.mLineWidth
) {
125 aPaint
.setStrokeWidth(SkFloatToScalar(aOptions
.mLineWidth
));
126 aPaint
.setStrokeMiter(SkFloatToScalar(aOptions
.mMiterLimit
));
127 aPaint
.setStrokeCap(CapStyleToSkiaCap(aOptions
.mLineCap
));
128 aPaint
.setStrokeJoin(JoinStyleToSkiaJoin(aOptions
.mLineJoin
));
130 if (aOptions
.mDashLength
> 0) {
131 // Skia only supports dash arrays that are multiples of 2.
134 if (aOptions
.mDashLength
% 2 == 0) {
135 dashCount
= aOptions
.mDashLength
;
137 dashCount
= aOptions
.mDashLength
* 2;
140 std::vector
<SkScalar
> pattern
;
141 pattern
.resize(dashCount
);
143 for (uint32_t i
= 0; i
< dashCount
; i
++) {
144 pattern
[i
] = SkFloatToScalar(aOptions
.mDashPattern
[i
% aOptions
.mDashLength
]);
147 SkDashPathEffect
* dash
= SkDashPathEffect::Create(&pattern
.front(),
149 SkFloatToScalar(aOptions
.mDashOffset
));
150 SkSafeUnref(aPaint
.setPathEffect(dash
));
153 aPaint
.setStyle(SkPaint::kStroke_Style
);
157 static inline SkXfermode::Mode
158 GfxOpToSkiaOp(CompositionOp op
)
162 case CompositionOp::OP_OVER
:
163 return SkXfermode::kSrcOver_Mode
;
164 case CompositionOp::OP_ADD
:
165 return SkXfermode::kPlus_Mode
;
166 case CompositionOp::OP_ATOP
:
167 return SkXfermode::kSrcATop_Mode
;
168 case CompositionOp::OP_OUT
:
169 return SkXfermode::kSrcOut_Mode
;
170 case CompositionOp::OP_IN
:
171 return SkXfermode::kSrcIn_Mode
;
172 case CompositionOp::OP_SOURCE
:
173 return SkXfermode::kSrc_Mode
;
174 case CompositionOp::OP_DEST_IN
:
175 return SkXfermode::kDstIn_Mode
;
176 case CompositionOp::OP_DEST_OUT
:
177 return SkXfermode::kDstOut_Mode
;
178 case CompositionOp::OP_DEST_OVER
:
179 return SkXfermode::kDstOver_Mode
;
180 case CompositionOp::OP_DEST_ATOP
:
181 return SkXfermode::kDstATop_Mode
;
182 case CompositionOp::OP_XOR
:
183 return SkXfermode::kXor_Mode
;
184 case CompositionOp::OP_MULTIPLY
:
185 return SkXfermode::kMultiply_Mode
;
186 case CompositionOp::OP_SCREEN
:
187 return SkXfermode::kScreen_Mode
;
188 case CompositionOp::OP_OVERLAY
:
189 return SkXfermode::kOverlay_Mode
;
190 case CompositionOp::OP_DARKEN
:
191 return SkXfermode::kDarken_Mode
;
192 case CompositionOp::OP_LIGHTEN
:
193 return SkXfermode::kLighten_Mode
;
194 case CompositionOp::OP_COLOR_DODGE
:
195 return SkXfermode::kColorDodge_Mode
;
196 case CompositionOp::OP_COLOR_BURN
:
197 return SkXfermode::kColorBurn_Mode
;
198 case CompositionOp::OP_HARD_LIGHT
:
199 return SkXfermode::kHardLight_Mode
;
200 case CompositionOp::OP_SOFT_LIGHT
:
201 return SkXfermode::kSoftLight_Mode
;
202 case CompositionOp::OP_DIFFERENCE
:
203 return SkXfermode::kDifference_Mode
;
204 case CompositionOp::OP_EXCLUSION
:
205 return SkXfermode::kExclusion_Mode
;
206 case CompositionOp::OP_HUE
:
207 return SkXfermode::kHue_Mode
;
208 case CompositionOp::OP_SATURATION
:
209 return SkXfermode::kSaturation_Mode
;
210 case CompositionOp::OP_COLOR
:
211 return SkXfermode::kColor_Mode
;
212 case CompositionOp::OP_LUMINOSITY
:
213 return SkXfermode::kLuminosity_Mode
;
215 return SkXfermode::kSrcOver_Mode
;
219 /* There's quite a bit of inconsistency about
220 * whether float colors should be rounded with .5f.
221 * We choose to do it to match cairo which also
222 * happens to match the Direct3D specs */
223 static inline U8CPU
ColorFloatToByte(Float color
)
225 //XXX: do a better job converting to int
226 return U8CPU(color
*255.f
+ .5f
);
229 static inline SkColor
ColorToSkColor(const Color
&color
, Float aAlpha
)
231 return SkColorSetARGB(ColorFloatToByte(color
.a
*aAlpha
), ColorFloatToByte(color
.r
),
232 ColorFloatToByte(color
.g
), ColorFloatToByte(color
.b
));
236 RectToSkRect(const Rect
& aRect
)
238 return SkRect::MakeXYWH(SkFloatToScalar(aRect
.x
), SkFloatToScalar(aRect
.y
),
239 SkFloatToScalar(aRect
.width
), SkFloatToScalar(aRect
.height
));
243 IntRectToSkRect(const IntRect
& aRect
)
245 return SkRect::MakeXYWH(SkIntToScalar(aRect
.x
), SkIntToScalar(aRect
.y
),
246 SkIntToScalar(aRect
.width
), SkIntToScalar(aRect
.height
));
249 static inline SkIRect
250 RectToSkIRect(const Rect
& aRect
)
252 return SkIRect::MakeXYWH(int32_t(aRect
.x
), int32_t(aRect
.y
),
253 int32_t(aRect
.width
), int32_t(aRect
.height
));
256 static inline SkIRect
257 IntRectToSkIRect(const IntRect
& aRect
)
259 return SkIRect::MakeXYWH(aRect
.x
, aRect
.y
, aRect
.width
, aRect
.height
);
263 SkPointToPoint(const SkPoint
&aPoint
)
265 return Point(SkScalarToFloat(aPoint
.x()), SkScalarToFloat(aPoint
.y()));
269 SkRectToRect(const SkRect
&aRect
)
271 return Rect(SkScalarToFloat(aRect
.x()), SkScalarToFloat(aRect
.y()),
272 SkScalarToFloat(aRect
.width()), SkScalarToFloat(aRect
.height()));
275 static inline SkShader::TileMode
276 ExtendModeToTileMode(ExtendMode aMode
)
280 case ExtendMode::CLAMP
:
281 return SkShader::kClamp_TileMode
;
282 case ExtendMode::REPEAT
:
283 return SkShader::kRepeat_TileMode
;
284 case ExtendMode::REFLECT
:
285 return SkShader::kMirror_TileMode
;
287 return SkShader::kClamp_TileMode
;
290 // The following class was imported from Skia, which is under the
291 // following licence:
293 // Copyright (c) 2011 Google Inc. All rights reserved.
295 // Redistribution and use in source and binary forms, with or without
296 // modification, are permitted provided that the following conditions are
299 // * Redistributions of source code must retain the above copyright
300 // notice, this list of conditions and the following disclaimer.
301 // * Redistributions in binary form must reproduce the above
302 // copyright notice, this list of conditions and the following disclaimer
303 // in the documentation and/or other materials provided with the
305 // * Neither the name of Google Inc. nor the names of its
306 // contributors may be used to endorse or promote products derived from
307 // this software without specific prior written permission.
309 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
310 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
311 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
313 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
314 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
315 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
316 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
317 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
318 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
319 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
321 template <typename T
> class RefPtrSkia
{
323 RefPtrSkia() : fObj(NULL
) {}
324 explicit RefPtrSkia(T
* obj
) : fObj(obj
) { SkSafeRef(fObj
); }
325 RefPtrSkia(const RefPtrSkia
& o
) : fObj(o
.fObj
) { SkSafeRef(fObj
); }
326 ~RefPtrSkia() { SkSafeUnref(fObj
); }
328 RefPtrSkia
& operator=(const RefPtrSkia
& rp
) {
329 SkRefCnt_SafeAssign(fObj
, rp
.fObj
);
332 RefPtrSkia
& operator=(T
* obj
) {
333 SkRefCnt_SafeAssign(fObj
, obj
);
337 T
* get() const { return fObj
; }
338 T
& operator*() const { return *fObj
; }
339 T
* operator->() const { return fObj
; }
341 RefPtrSkia
& adopt(T
* obj
) {
347 typedef T
* RefPtrSkia::*unspecified_bool_type
;
348 operator unspecified_bool_type() const {
349 return fObj
? &RefPtrSkia::fObj
: NULL
;
356 // End of code imported from Skia.
361 #endif /* MOZILLA_GFX_HELPERSSKIA_H_ */