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