gfx/2d/HelpersCairo.h

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:b0ed0f470143
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_HELPERSCAIRO_H_
7 #define MOZILLA_GFX_HELPERSCAIRO_H_
8
9 #include "2D.h"
10 #include "cairo.h"
11 #include "Logging.h"
12
13 namespace mozilla {
14 namespace gfx {
15
16 static inline cairo_operator_t
17 GfxOpToCairoOp(CompositionOp op)
18 {
19 switch (op)
20 {
21 case CompositionOp::OP_OVER:
22 return CAIRO_OPERATOR_OVER;
23 case CompositionOp::OP_ADD:
24 return CAIRO_OPERATOR_ADD;
25 case CompositionOp::OP_ATOP:
26 return CAIRO_OPERATOR_ATOP;
27 case CompositionOp::OP_OUT:
28 return CAIRO_OPERATOR_OUT;
29 case CompositionOp::OP_IN:
30 return CAIRO_OPERATOR_IN;
31 case CompositionOp::OP_SOURCE:
32 return CAIRO_OPERATOR_SOURCE;
33 case CompositionOp::OP_DEST_IN:
34 return CAIRO_OPERATOR_DEST_IN;
35 case CompositionOp::OP_DEST_OUT:
36 return CAIRO_OPERATOR_DEST_OUT;
37 case CompositionOp::OP_DEST_OVER:
38 return CAIRO_OPERATOR_DEST_OVER;
39 case CompositionOp::OP_DEST_ATOP:
40 return CAIRO_OPERATOR_DEST_ATOP;
41 case CompositionOp::OP_XOR:
42 return CAIRO_OPERATOR_XOR;
43 case CompositionOp::OP_MULTIPLY:
44 return CAIRO_OPERATOR_MULTIPLY;
45 case CompositionOp::OP_SCREEN:
46 return CAIRO_OPERATOR_SCREEN;
47 case CompositionOp::OP_OVERLAY:
48 return CAIRO_OPERATOR_OVERLAY;
49 case CompositionOp::OP_DARKEN:
50 return CAIRO_OPERATOR_DARKEN;
51 case CompositionOp::OP_LIGHTEN:
52 return CAIRO_OPERATOR_LIGHTEN;
53 case CompositionOp::OP_COLOR_DODGE:
54 return CAIRO_OPERATOR_COLOR_DODGE;
55 case CompositionOp::OP_COLOR_BURN:
56 return CAIRO_OPERATOR_COLOR_BURN;
57 case CompositionOp::OP_HARD_LIGHT:
58 return CAIRO_OPERATOR_HARD_LIGHT;
59 case CompositionOp::OP_SOFT_LIGHT:
60 return CAIRO_OPERATOR_SOFT_LIGHT;
61 case CompositionOp::OP_DIFFERENCE:
62 return CAIRO_OPERATOR_DIFFERENCE;
63 case CompositionOp::OP_EXCLUSION:
64 return CAIRO_OPERATOR_EXCLUSION;
65 case CompositionOp::OP_HUE:
66 return CAIRO_OPERATOR_HSL_HUE;
67 case CompositionOp::OP_SATURATION:
68 return CAIRO_OPERATOR_HSL_SATURATION;
69 case CompositionOp::OP_COLOR:
70 return CAIRO_OPERATOR_HSL_COLOR;
71 case CompositionOp::OP_LUMINOSITY:
72 return CAIRO_OPERATOR_HSL_LUMINOSITY;
73 case CompositionOp::OP_COUNT:
74 break;
75 }
76
77 return CAIRO_OPERATOR_OVER;
78 }
79
80 static inline cairo_antialias_t
81 GfxAntialiasToCairoAntialias(AntialiasMode antialias)
82 {
83 switch (antialias)
84 {
85 case AntialiasMode::NONE:
86 return CAIRO_ANTIALIAS_NONE;
87 case AntialiasMode::GRAY:
88 return CAIRO_ANTIALIAS_GRAY;
89 case AntialiasMode::SUBPIXEL:
90 return CAIRO_ANTIALIAS_SUBPIXEL;
91 case AntialiasMode::DEFAULT:
92 return CAIRO_ANTIALIAS_DEFAULT;
93 }
94 return CAIRO_ANTIALIAS_DEFAULT;
95 }
96
97 static inline cairo_filter_t
98 GfxFilterToCairoFilter(Filter filter)
99 {
100 switch (filter)
101 {
102 case Filter::GOOD:
103 return CAIRO_FILTER_GOOD;
104 case Filter::LINEAR:
105 return CAIRO_FILTER_BILINEAR;
106 case Filter::POINT:
107 return CAIRO_FILTER_NEAREST;
108 }
109
110 return CAIRO_FILTER_BILINEAR;
111 }
112
113 static inline cairo_extend_t
114 GfxExtendToCairoExtend(ExtendMode extend)
115 {
116 switch (extend)
117 {
118 case ExtendMode::CLAMP:
119 return CAIRO_EXTEND_PAD;
120 case ExtendMode::REPEAT:
121 return CAIRO_EXTEND_REPEAT;
122 case ExtendMode::REFLECT:
123 return CAIRO_EXTEND_REFLECT;
124 }
125
126 return CAIRO_EXTEND_PAD;
127 }
128
129 static inline cairo_format_t
130 GfxFormatToCairoFormat(SurfaceFormat format)
131 {
132 switch (format)
133 {
134 case SurfaceFormat::B8G8R8A8:
135 return CAIRO_FORMAT_ARGB32;
136 case SurfaceFormat::B8G8R8X8:
137 return CAIRO_FORMAT_RGB24;
138 case SurfaceFormat::A8:
139 return CAIRO_FORMAT_A8;
140 case SurfaceFormat::R5G6B5:
141 return CAIRO_FORMAT_RGB16_565;
142 default:
143 gfxWarning() << "Unknown image format";
144 return CAIRO_FORMAT_ARGB32;
145 }
146 }
147
148 static inline cairo_content_t
149 GfxFormatToCairoContent(SurfaceFormat format)
150 {
151 switch (format)
152 {
153 case SurfaceFormat::B8G8R8A8:
154 return CAIRO_CONTENT_COLOR_ALPHA;
155 case SurfaceFormat::B8G8R8X8:
156 case SurfaceFormat::R5G6B5: //fall through
157 return CAIRO_CONTENT_COLOR;
158 case SurfaceFormat::A8:
159 return CAIRO_CONTENT_ALPHA;
160 default:
161 gfxWarning() << "Unknown image format";
162 return CAIRO_CONTENT_COLOR_ALPHA;
163 }
164 }
165
166 static inline cairo_line_join_t
167 GfxLineJoinToCairoLineJoin(JoinStyle style)
168 {
169 switch (style)
170 {
171 case JoinStyle::BEVEL:
172 return CAIRO_LINE_JOIN_BEVEL;
173 case JoinStyle::ROUND:
174 return CAIRO_LINE_JOIN_ROUND;
175 case JoinStyle::MITER:
176 return CAIRO_LINE_JOIN_MITER;
177 case JoinStyle::MITER_OR_BEVEL:
178 return CAIRO_LINE_JOIN_MITER;
179 }
180
181 return CAIRO_LINE_JOIN_MITER;
182 }
183
184 static inline cairo_line_cap_t
185 GfxLineCapToCairoLineCap(CapStyle style)
186 {
187 switch (style)
188 {
189 case CapStyle::BUTT:
190 return CAIRO_LINE_CAP_BUTT;
191 case CapStyle::ROUND:
192 return CAIRO_LINE_CAP_ROUND;
193 case CapStyle::SQUARE:
194 return CAIRO_LINE_CAP_SQUARE;
195 }
196
197 return CAIRO_LINE_CAP_BUTT;
198 }
199
200 static inline SurfaceFormat
201 CairoContentToGfxFormat(cairo_content_t content)
202 {
203 switch (content)
204 {
205 case CAIRO_CONTENT_COLOR_ALPHA:
206 return SurfaceFormat::B8G8R8A8;
207 case CAIRO_CONTENT_COLOR:
208 // BEWARE! format may be 565
209 return SurfaceFormat::B8G8R8X8;
210 case CAIRO_CONTENT_ALPHA:
211 return SurfaceFormat::A8;
212 }
213
214 return SurfaceFormat::B8G8R8A8;
215 }
216
217 static inline void
218 GfxMatrixToCairoMatrix(const Matrix& mat, cairo_matrix_t& retval)
219 {
220 cairo_matrix_init(&retval, mat._11, mat._12, mat._21, mat._22, mat._31, mat._32);
221 }
222
223 static inline void
224 SetCairoStrokeOptions(cairo_t* aCtx, const StrokeOptions& aStrokeOptions)
225 {
226 cairo_set_line_width(aCtx, aStrokeOptions.mLineWidth);
227
228 cairo_set_miter_limit(aCtx, aStrokeOptions.mMiterLimit);
229
230 if (aStrokeOptions.mDashPattern) {
231 // Convert array of floats to array of doubles
232 std::vector<double> dashes(aStrokeOptions.mDashLength);
233 for (size_t i = 0; i < aStrokeOptions.mDashLength; ++i) {
234 dashes[i] = aStrokeOptions.mDashPattern[i];
235 }
236 cairo_set_dash(aCtx, &dashes[0], aStrokeOptions.mDashLength,
237 aStrokeOptions.mDashOffset);
238 }
239
240 cairo_set_line_join(aCtx, GfxLineJoinToCairoLineJoin(aStrokeOptions.mLineJoin));
241
242 cairo_set_line_cap(aCtx, GfxLineCapToCairoLineCap(aStrokeOptions.mLineCap));
243 }
244
245 static inline cairo_fill_rule_t
246 GfxFillRuleToCairoFillRule(FillRule rule)
247 {
248 switch (rule)
249 {
250 case FillRule::FILL_WINDING:
251 return CAIRO_FILL_RULE_WINDING;
252 case FillRule::FILL_EVEN_ODD:
253 return CAIRO_FILL_RULE_EVEN_ODD;
254 }
255
256 return CAIRO_FILL_RULE_WINDING;
257 }
258
259 // RAII class for temporarily changing the cairo matrix transform. It will use
260 // the given matrix transform while it is in scope. When it goes out of scope
261 // it will put the cairo context back the way it was.
262
263 class CairoTempMatrix
264 {
265 public:
266 CairoTempMatrix(cairo_t* aCtx, const Matrix& aMatrix)
267 : mCtx(aCtx)
268 {
269 cairo_get_matrix(aCtx, &mSaveMatrix);
270 cairo_matrix_t matrix;
271 GfxMatrixToCairoMatrix(aMatrix, matrix);
272 cairo_set_matrix(aCtx, &matrix);
273 }
274
275 ~CairoTempMatrix()
276 {
277 cairo_set_matrix(mCtx, &mSaveMatrix);
278 }
279
280 private:
281 cairo_t* mCtx;
282 cairo_matrix_t mSaveMatrix;
283 };
284
285 }
286 }
287
288 #endif /* MOZILLA_GFX_HELPERSCAIRO_H_ */

mercurial