1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef MOZILLA_GFX_TYPES_H_
8 #define MOZILLA_GFX_TYPES_H_
9
10 #include "mozilla/EndianUtils.h"
11 #include "mozilla/MacroArgs.h" // for MOZ_CONCAT
12
13 #include <stddef.h>
14 #include <stdint.h>
15
16 namespace mozilla {
17 namespace gfx {
18
19 typedef float Float;
20 typedef double Double;
21
22 enum class SurfaceType : int8_t {
23 DATA, /* Data surface - bitmap in memory */
24 D2D1_BITMAP, /* Surface wrapping a ID2D1Bitmap */
25 D2D1_DRAWTARGET, /* Surface made from a D2D draw target */
26 CAIRO, /* Surface wrapping a cairo surface */
27 CAIRO_IMAGE, /* Data surface wrapping a cairo image surface */
28 COREGRAPHICS_IMAGE, /* Surface wrapping a CoreGraphics Image */
29 COREGRAPHICS_CGCONTEXT, /* Surface wrapping a CG context */
30 SKIA, /* Surface wrapping a Skia bitmap */
31 DUAL_DT, /* Snapshot of a dual drawtarget */
32 D2D1_1_IMAGE, /* A D2D 1.1 ID2D1Image SourceSurface */
33 RECORDING, /* Surface used for recording */
34 TILED, /* Surface from a tiled DrawTarget */
35 DATA_SHARED, /* Data surface using shared memory */
36 CAPTURE /* Data from a DrawTargetCapture */
37 };
38
39 enum class SurfaceFormat : int8_t {
40 // The following values are named to reflect layout of colors in memory, from
41 // lowest byte to highest byte. The 32-bit value layout depends on machine
42 // endianness.
43 // in-memory 32-bit LE value 32-bit BE value
44 B8G8R8A8, // [BB, GG, RR, AA] 0xAARRGGBB 0xBBGGRRAA
45 B8G8R8X8, // [BB, GG, RR, 00] 0x00RRGGBB 0xBBGGRR00
46 R8G8B8A8, // [RR, GG, BB, AA] 0xAABBGGRR 0xRRGGBBAA
47 R8G8B8X8, // [RR, GG, BB, 00] 0x00BBGGRR 0xRRGGBB00
48 A8R8G8B8, // [AA, RR, GG, BB] 0xBBGGRRAA 0xAARRGGBB
49 X8R8G8B8, // [00, RR, GG, BB] 0xBBGGRR00 0x00RRGGBB
50
51 R8G8B8,
52 B8G8R8,
53
54 // The _UINT16 suffix here indicates that the name reflects the layout when
55 // viewed as a uint16_t value. In memory these values are stored using native
56 // endianness.
57 R5G6B5_UINT16, // 0bRRRRRGGGGGGBBBBB
58
59 // This one is a single-byte, so endianness isn't an issue.
60 A8,
61 A16,
62
63 R8G8,
64
65 // These ones are their own special cases.
66 YUV,
67 NV12,
68 YUV422,
69 HSV,
70 Lab,
71 Depth,
72
73 // This represents the unknown format.
74 UNKNOWN,
75
76 // The following values are endian-independent synonyms. The _UINT32 suffix
77 // indicates that the name reflects the layout when viewed as a uint32_t
78 // value.
79 #if MOZ_LITTLE_ENDIAN
80 A8R8G8B8_UINT32 = B8G8R8A8, // 0xAARRGGBB
81 X8R8G8B8_UINT32 = B8G8R8X8 // 0x00RRGGBB
82 #elif MOZ_BIG_ENDIAN
83 A8R8G8B8_UINT32 = A8R8G8B8, // 0xAARRGGBB
84 X8R8G8B8_UINT32 = X8R8G8B8 // 0x00RRGGBB
85 #else
86 #error "bad endianness"
87 #endif
88 };
89
IsOpaque(SurfaceFormat aFormat)90 inline bool IsOpaque(SurfaceFormat aFormat) {
91 switch (aFormat) {
92 case SurfaceFormat::B8G8R8X8:
93 case SurfaceFormat::R8G8B8X8:
94 case SurfaceFormat::R5G6B5_UINT16:
95 case SurfaceFormat::YUV:
96 case SurfaceFormat::NV12:
97 case SurfaceFormat::YUV422:
98 return true;
99 default:
100 return false;
101 }
102 }
103
104 enum class FilterType : int8_t {
105 BLEND = 0,
106 TRANSFORM,
107 MORPHOLOGY,
108 COLOR_MATRIX,
109 FLOOD,
110 TILE,
111 TABLE_TRANSFER,
112 DISCRETE_TRANSFER,
113 LINEAR_TRANSFER,
114 GAMMA_TRANSFER,
115 CONVOLVE_MATRIX,
116 DISPLACEMENT_MAP,
117 TURBULENCE,
118 ARITHMETIC_COMBINE,
119 COMPOSITE,
120 DIRECTIONAL_BLUR,
121 GAUSSIAN_BLUR,
122 POINT_DIFFUSE,
123 POINT_SPECULAR,
124 SPOT_DIFFUSE,
125 SPOT_SPECULAR,
126 DISTANT_DIFFUSE,
127 DISTANT_SPECULAR,
128 CROP,
129 PREMULTIPLY,
130 UNPREMULTIPLY
131 };
132
133 enum class DrawTargetType : int8_t {
134 SOFTWARE_RASTER = 0,
135 HARDWARE_RASTER,
136 VECTOR
137 };
138
139 enum class BackendType : int8_t {
140 NONE = 0,
141 DIRECT2D, // Used for version independent D2D objects.
142 CAIRO,
143 SKIA,
144 RECORDING,
145 DIRECT2D1_1,
146 WEBRENDER_TEXT,
147
148 // Add new entries above this line.
149 BACKEND_LAST
150 };
151
152 enum class FontType : int8_t {
153 DWRITE,
154 GDI,
155 MAC,
156 SKIA,
157 CAIRO,
158 COREGRAPHICS,
159 FONTCONFIG,
160 FREETYPE
161 };
162
163 enum class NativeSurfaceType : int8_t {
164 D3D10_TEXTURE,
165 CAIRO_CONTEXT,
166 CGCONTEXT,
167 CGCONTEXT_ACCELERATED,
168 OPENGL_TEXTURE
169 };
170
171 enum class NativeFontType : int8_t {
172 DWRITE_FONT_FACE,
173 GDI_FONT_FACE,
174 MAC_FONT_FACE,
175 SKIA_FONT_FACE,
176 CAIRO_FONT_FACE
177 };
178
179 enum class FontStyle : int8_t { NORMAL, ITALIC, BOLD, BOLD_ITALIC };
180
181 enum class FontHinting : int8_t { NONE, LIGHT, NORMAL, FULL };
182
183 enum class CompositionOp : int8_t {
184 OP_OVER,
185 OP_ADD,
186 OP_ATOP,
187 OP_OUT,
188 OP_IN,
189 OP_SOURCE,
190 OP_DEST_IN,
191 OP_DEST_OUT,
192 OP_DEST_OVER,
193 OP_DEST_ATOP,
194 OP_XOR,
195 OP_MULTIPLY,
196 OP_SCREEN,
197 OP_OVERLAY,
198 OP_DARKEN,
199 OP_LIGHTEN,
200 OP_COLOR_DODGE,
201 OP_COLOR_BURN,
202 OP_HARD_LIGHT,
203 OP_SOFT_LIGHT,
204 OP_DIFFERENCE,
205 OP_EXCLUSION,
206 OP_HUE,
207 OP_SATURATION,
208 OP_COLOR,
209 OP_LUMINOSITY,
210 OP_COUNT
211 };
212
213 enum class Axis : int8_t { X_AXIS, Y_AXIS, BOTH };
214
215 enum class ExtendMode : int8_t {
216 CLAMP, // Do not repeat
217 REPEAT, // Repeat in both axis
218 REPEAT_X, // Only X axis
219 REPEAT_Y, // Only Y axis
220 REFLECT // Mirror the image
221 };
222
223 enum class FillRule : int8_t { FILL_WINDING, FILL_EVEN_ODD };
224
225 enum class AntialiasMode : int8_t { NONE, GRAY, SUBPIXEL, DEFAULT };
226
227 // See https://en.wikipedia.org/wiki/Texture_filtering
228 enum class SamplingFilter : int8_t {
229 GOOD,
230 LINEAR,
231 POINT,
232 SENTINEL // one past the last valid value
233 };
234
235 enum class PatternType : int8_t {
236 COLOR,
237 SURFACE,
238 LINEAR_GRADIENT,
239 RADIAL_GRADIENT
240 };
241
242 enum class JoinStyle : int8_t {
243 BEVEL,
244 ROUND,
245 MITER, //!< Mitered if within the miter limit, else, if the backed supports
246 //!< it (D2D), the miter is clamped. If the backend does not support
247 //!< miter clamping the behavior is as for MITER_OR_BEVEL.
248 MITER_OR_BEVEL //!< Mitered if within the miter limit, else beveled.
249 };
250
251 enum class CapStyle : int8_t { BUTT, ROUND, SQUARE };
252
253 enum class SamplingBounds : int8_t { UNBOUNDED, BOUNDED };
254
255 // Moz2d version for SVG mask types
256 enum class LuminanceType : int8_t {
257 LUMINANCE,
258 LINEARRGB,
259 };
260
261 /* Color is stored in non-premultiplied form */
262 struct Color {
263 public:
ColorColor264 Color() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {}
ColorColor265 Color(Float aR, Float aG, Float aB, Float aA) : r(aR), g(aG), b(aB), a(aA) {}
ColorColor266 Color(Float aR, Float aG, Float aB) : r(aR), g(aG), b(aB), a(1.0f) {}
267
FromABGRColor268 static Color FromABGR(uint32_t aColor) {
269 Color newColor(((aColor >> 0) & 0xff) * (1.0f / 255.0f),
270 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
271 ((aColor >> 16) & 0xff) * (1.0f / 255.0f),
272 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
273
274 return newColor;
275 }
276
277 // The "Unusual" prefix is to avoid unintentionally using this function when
278 // FromABGR(), which is much more common, is needed.
UnusualFromARGBColor279 static Color UnusualFromARGB(uint32_t aColor) {
280 Color newColor(((aColor >> 16) & 0xff) * (1.0f / 255.0f),
281 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
282 ((aColor >> 0) & 0xff) * (1.0f / 255.0f),
283 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
284
285 return newColor;
286 }
287
ToABGRColor288 uint32_t ToABGR() const {
289 return uint32_t(r * 255.0f) | uint32_t(g * 255.0f) << 8 |
290 uint32_t(b * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
291 }
292
293 // The "Unusual" prefix is to avoid unintentionally using this function when
294 // ToABGR(), which is much more common, is needed.
UnusualToARGBColor295 uint32_t UnusualToARGB() const {
296 return uint32_t(b * 255.0f) | uint32_t(g * 255.0f) << 8 |
297 uint32_t(r * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
298 }
299
300 bool operator==(const Color& aColor) const {
301 return r == aColor.r && g == aColor.g && b == aColor.b && a == aColor.a;
302 }
303
304 bool operator!=(const Color& aColor) const { return !(*this == aColor); }
305
306 Float r, g, b, a;
307 };
308
309 struct GradientStop {
310 bool operator<(const GradientStop& aOther) const {
311 return offset < aOther.offset;
312 }
313
314 Float offset;
315 Color color;
316 };
317
318 enum class JobStatus { Complete, Wait, Yield, Error };
319
320 } // namespace gfx
321 } // namespace mozilla
322
323 // XXX: temporary
324 typedef mozilla::gfx::SurfaceFormat gfxImageFormat;
325
326 #if defined(XP_WIN) && defined(MOZ_GFX)
327 #ifdef GFX2D_INTERNAL
328 #define GFX2D_API __declspec(dllexport)
329 #else
330 #define GFX2D_API __declspec(dllimport)
331 #endif
332 #else
333 #define GFX2D_API
334 #endif
335
336 namespace mozilla {
337
338 // Side constants for use in various places.
339 enum Side { eSideTop, eSideRight, eSideBottom, eSideLeft };
340
341 enum SideBits {
342 eSideBitsNone = 0,
343 eSideBitsTop = 1 << eSideTop,
344 eSideBitsRight = 1 << eSideRight,
345 eSideBitsBottom = 1 << eSideBottom,
346 eSideBitsLeft = 1 << eSideLeft,
347 eSideBitsTopBottom = eSideBitsTop | eSideBitsBottom,
348 eSideBitsLeftRight = eSideBitsLeft | eSideBitsRight,
349 eSideBitsAll = eSideBitsTopBottom | eSideBitsLeftRight
350 };
351
352 // Creates a for loop that walks over the four mozilla::Side values.
353 // We use an int32_t helper variable (instead of a Side) for our loop counter,
354 // to avoid triggering undefined behavior just before we exit the loop (at
355 // which point the counter is incremented beyond the largest valid Side value).
356 #define NS_FOR_CSS_SIDES(var_) \
357 int32_t MOZ_CONCAT(var_, __LINE__) = mozilla::eSideTop; \
358 for (mozilla::Side var_; \
359 MOZ_CONCAT(var_, __LINE__) <= mozilla::eSideLeft && \
360 (static_cast<void>(var_ = mozilla::Side(MOZ_CONCAT(var_, __LINE__))), \
361 true); \
362 ++MOZ_CONCAT(var_, __LINE__))
363
364 static inline Side& operator++(Side& side) {
365 MOZ_ASSERT(side >= eSideTop && side <= eSideLeft, "Out of range side");
366 side = Side(side + 1);
367 return side;
368 }
369
370 enum Corner {
371 // This order is important!
372 eCornerTopLeft = 0,
373 eCornerTopRight = 1,
374 eCornerBottomRight = 2,
375 eCornerBottomLeft = 3
376 };
377
378 // RectCornerRadii::radii depends on this value. It is not being added to
379 // Corner because we want to lift the responsibility to handle it in the
380 // switch-case.
381 constexpr int eCornerCount = 4;
382
383 // Creates a for loop that walks over the four mozilla::Corner values. This
384 // implementation uses the same technique as NS_FOR_CSS_SIDES.
385 #define NS_FOR_CSS_FULL_CORNERS(var_) \
386 int32_t MOZ_CONCAT(var_, __LINE__) = mozilla::eCornerTopLeft; \
387 for (mozilla::Corner var_; \
388 MOZ_CONCAT(var_, __LINE__) <= mozilla::eCornerBottomLeft && \
389 (static_cast<void>(var_ = mozilla::Corner(MOZ_CONCAT(var_, __LINE__))), \
390 true); \
391 ++MOZ_CONCAT(var_, __LINE__))
392
393 static inline Corner operator++(Corner& aCorner) {
394 MOZ_ASSERT(aCorner >= eCornerTopLeft && aCorner <= eCornerBottomLeft,
395 "Out of range corner!");
396 aCorner = Corner(aCorner + 1);
397 return aCorner;
398 }
399
400 // Indices into "half corner" arrays (nsStyleCorners e.g.)
401 enum HalfCorner {
402 // This order is important!
403 eCornerTopLeftX = 0,
404 eCornerTopLeftY = 1,
405 eCornerTopRightX = 2,
406 eCornerTopRightY = 3,
407 eCornerBottomRightX = 4,
408 eCornerBottomRightY = 5,
409 eCornerBottomLeftX = 6,
410 eCornerBottomLeftY = 7
411 };
412
413 // Creates a for loop that walks over the eight mozilla::HalfCorner values.
414 // This implementation uses the same technique as NS_FOR_CSS_SIDES.
415 #define NS_FOR_CSS_HALF_CORNERS(var_) \
416 int32_t MOZ_CONCAT(var_, __LINE__) = mozilla::eCornerTopLeftX; \
417 for (mozilla::HalfCorner var_; \
418 MOZ_CONCAT(var_, __LINE__) <= mozilla::eCornerBottomLeftY && \
419 (static_cast<void>( \
420 var_ = mozilla::HalfCorner(MOZ_CONCAT(var_, __LINE__))), \
421 true); \
422 ++MOZ_CONCAT(var_, __LINE__))
423
424 static inline HalfCorner operator++(HalfCorner& aHalfCorner) {
425 MOZ_ASSERT(
426 aHalfCorner >= eCornerTopLeftX && aHalfCorner <= eCornerBottomLeftY,
427 "Out of range half corner!");
428 aHalfCorner = HalfCorner(aHalfCorner + 1);
429 return aHalfCorner;
430 }
431
432 // The result of these conversion functions are exhaustively checked in
433 // nsStyleCoord.cpp, which also serves as usage examples.
434
HalfCornerIsX(HalfCorner aHalfCorner)435 constexpr bool HalfCornerIsX(HalfCorner aHalfCorner) {
436 return !(aHalfCorner % 2);
437 }
438
HalfToFullCorner(HalfCorner aHalfCorner)439 constexpr Corner HalfToFullCorner(HalfCorner aHalfCorner) {
440 return Corner(aHalfCorner / 2);
441 }
442
FullToHalfCorner(Corner aCorner,bool aIsVertical)443 constexpr HalfCorner FullToHalfCorner(Corner aCorner, bool aIsVertical) {
444 return HalfCorner(aCorner * 2 + aIsVertical);
445 }
446
SideIsVertical(Side aSide)447 constexpr bool SideIsVertical(Side aSide) { return aSide % 2; }
448
449 // @param aIsSecond when true, return the clockwise second of the two
450 // corners associated with aSide. For example, with aSide = eSideBottom the
451 // result is eCornerBottomRight when aIsSecond is false, and
452 // eCornerBottomLeft when aIsSecond is true.
SideToFullCorner(Side aSide,bool aIsSecond)453 constexpr Corner SideToFullCorner(Side aSide, bool aIsSecond) {
454 return Corner((aSide + aIsSecond) % 4);
455 }
456
457 // @param aIsSecond see SideToFullCorner.
458 // @param aIsParallel return the half-corner that is parallel with aSide
459 // when aIsParallel is true. For example with aSide=eSideTop, aIsSecond=true
460 // the result is eCornerTopRightX when aIsParallel is true, and
461 // eCornerTopRightY when aIsParallel is false (because "X" is parallel with
462 // eSideTop/eSideBottom, similarly "Y" is parallel with
463 // eSideLeft/eSideRight)
SideToHalfCorner(Side aSide,bool aIsSecond,bool aIsParallel)464 constexpr HalfCorner SideToHalfCorner(Side aSide, bool aIsSecond,
465 bool aIsParallel) {
466 return HalfCorner(((aSide + aIsSecond) * 2 + (aSide + !aIsParallel) % 2) % 8);
467 }
468
469 } // namespace mozilla
470
471 #endif /* MOZILLA_GFX_TYPES_H_ */
472