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/DefineEnum.h" // for MOZ_DEFINE_ENUM_CLASS_WITH_BASE
11 #include "mozilla/EndianUtils.h"
12 #include "mozilla/EnumeratedRange.h"
13 #include "mozilla/MacroArgs.h" // for MOZ_CONCAT
14 #include "mozilla/TypedEnumBits.h"
15
16 #include <iosfwd> // for ostream
17 #include <stddef.h>
18 #include <stdint.h>
19
20 namespace mozilla {
21 namespace gfx {
22
23 typedef float Float;
24 typedef double Double;
25
26 enum class SurfaceType : int8_t {
27 DATA, /* Data surface - bitmap in memory */
28 D2D1_BITMAP, /* Surface wrapping a ID2D1Bitmap */
29 D2D1_DRAWTARGET, /* Surface made from a D2D draw target */
30 CAIRO, /* Surface wrapping a cairo surface */
31 CAIRO_IMAGE, /* Data surface wrapping a cairo image surface */
32 COREGRAPHICS_IMAGE, /* Surface wrapping a CoreGraphics Image */
33 COREGRAPHICS_CGCONTEXT, /* Surface wrapping a CG context */
34 SKIA, /* Surface wrapping a Skia bitmap */
35 DUAL_DT, /* Snapshot of a dual drawtarget */
36 D2D1_1_IMAGE, /* A D2D 1.1 ID2D1Image SourceSurface */
37 RECORDING, /* Surface used for recording */
38 WRAP_AND_RECORD, /* Surface used for wrap and record */
39 TILED, /* Surface from a tiled DrawTarget */
40 DATA_SHARED, /* Data surface using shared memory */
41 CAPTURE, /* Data from a DrawTargetCapture */
42 DATA_RECYCLING_SHARED, /* Data surface using shared memory */
43 OFFSET, /* Offset */
44 DATA_ALIGNED, /* Data surface using aligned heap memory */
45 DATA_SHARED_WRAPPER, /* Shared memory mapped in from another process */
46 BLOB_IMAGE, /* Recorded blob image */
47 DATA_MAPPED, /* Data surface wrapping a ScopedMap */
48 };
49
50 enum class SurfaceFormat : int8_t {
51 // The following values are named to reflect layout of colors in memory, from
52 // lowest byte to highest byte. The 32-bit value layout depends on machine
53 // endianness.
54 // in-memory 32-bit LE value 32-bit BE value
55 B8G8R8A8, // [BB, GG, RR, AA] 0xAARRGGBB 0xBBGGRRAA
56 B8G8R8X8, // [BB, GG, RR, 00] 0x00RRGGBB 0xBBGGRR00
57 R8G8B8A8, // [RR, GG, BB, AA] 0xAABBGGRR 0xRRGGBBAA
58 R8G8B8X8, // [RR, GG, BB, 00] 0x00BBGGRR 0xRRGGBB00
59 A8R8G8B8, // [AA, RR, GG, BB] 0xBBGGRRAA 0xAARRGGBB
60 X8R8G8B8, // [00, RR, GG, BB] 0xBBGGRR00 0x00RRGGBB
61
62 R8G8B8,
63 B8G8R8,
64
65 // The _UINT16 suffix here indicates that the name reflects the layout when
66 // viewed as a uint16_t value. In memory these values are stored using native
67 // endianness.
68 R5G6B5_UINT16, // 0bRRRRRGGGGGGBBBBB
69
70 // This one is a single-byte, so endianness isn't an issue.
71 A8,
72 A16,
73
74 R8G8,
75 R16G16,
76
77 // These ones are their own special cases.
78 YUV,
79 NV12, // YUV 4:2:0 image with a plane of 8 bit Y samples followed by
80 // an interleaved U/V plane containing 8 bit 2x2 subsampled
81 // colour difference samples.
82 P016, // Similar to NV12, but with 16 bits plane values
83 P010, // Identical to P016 but the 6 least significant bits are 0.
84 // With DXGI in theory entirely compatible, however practice has
85 // shown that it's not the case.
86 YUV422, // Single plane YUV 4:2:2 interleaved as Y`0 Cb Y`1 Cr.
87 HSV,
88 Lab,
89 Depth,
90
91 // This represents the unknown format.
92 UNKNOWN,
93
94 // The following values are endian-independent synonyms. The _UINT32 suffix
95 // indicates that the name reflects the layout when viewed as a uint32_t
96 // value.
97 A8R8G8B8_UINT32 = B8G8R8A8, // 0xAARRGGBB
98 X8R8G8B8_UINT32 = B8G8R8X8, // 0x00RRGGBB
99
100 // The following values are OS and endian-independent synonyms.
101 //
102 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
103 // can make this use R8B8G8A8 and R8B8G8X8 for non-Windows platforms.
104 OS_RGBA = A8R8G8B8_UINT32,
105 OS_RGBX = X8R8G8B8_UINT32
106 };
107
108 std::ostream& operator<<(std::ostream& aOut, const SurfaceFormat& aFormat);
109
110 // Represents the bit-shifts required to access color channels when the layout
111 // is viewed as a uint32_t value.
112 enum class SurfaceFormatBit : uint32_t {
113 #if MOZ_LITTLE_ENDIAN()
114 R8G8B8A8_R = 0,
115 R8G8B8A8_G = 8,
116 R8G8B8A8_B = 16,
117 R8G8B8A8_A = 24,
118 #elif MOZ_BIG_ENDIAN()
119 R8G8B8A8_A = 0,
120 R8G8B8A8_B = 8,
121 R8G8B8A8_G = 16,
122 R8G8B8A8_R = 24,
123 #else
124 # error "bad endianness"
125 #endif
126
127 // The following values are endian-independent for A8R8G8B8_UINT32.
128 A8R8G8B8_UINT32_B = 0,
129 A8R8G8B8_UINT32_G = 8,
130 A8R8G8B8_UINT32_R = 16,
131 A8R8G8B8_UINT32_A = 24,
132
133 // The following values are OS and endian-independent.
134 //
135 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
136 // can make this use R8G8B8A8_X for non-Windows platforms.
137 OS_R = A8R8G8B8_UINT32_R,
138 OS_G = A8R8G8B8_UINT32_G,
139 OS_B = A8R8G8B8_UINT32_B,
140 OS_A = A8R8G8B8_UINT32_A,
141 };
142
143 inline uint32_t operator<<(uint8_t a, SurfaceFormatBit b) {
144 return a << static_cast<uint32_t>(b);
145 }
146
147 inline uint32_t operator>>(uint32_t a, SurfaceFormatBit b) {
148 return a >> static_cast<uint32_t>(b);
149 }
150
BytesPerPixel(SurfaceFormat aFormat)151 static inline int BytesPerPixel(SurfaceFormat aFormat) {
152 switch (aFormat) {
153 case SurfaceFormat::A8:
154 return 1;
155 case SurfaceFormat::R5G6B5_UINT16:
156 case SurfaceFormat::A16:
157 return 2;
158 case SurfaceFormat::R8G8B8:
159 case SurfaceFormat::B8G8R8:
160 return 3;
161 case SurfaceFormat::HSV:
162 case SurfaceFormat::Lab:
163 return 3 * sizeof(float);
164 case SurfaceFormat::Depth:
165 return sizeof(uint16_t);
166 default:
167 return 4;
168 }
169 }
170
IsOpaque(SurfaceFormat aFormat)171 inline bool IsOpaque(SurfaceFormat aFormat) {
172 switch (aFormat) {
173 case SurfaceFormat::B8G8R8X8:
174 case SurfaceFormat::R8G8B8X8:
175 case SurfaceFormat::X8R8G8B8:
176 case SurfaceFormat::R5G6B5_UINT16:
177 case SurfaceFormat::R8G8B8:
178 case SurfaceFormat::B8G8R8:
179 case SurfaceFormat::R8G8:
180 case SurfaceFormat::HSV:
181 case SurfaceFormat::Lab:
182 case SurfaceFormat::Depth:
183 case SurfaceFormat::YUV:
184 case SurfaceFormat::NV12:
185 case SurfaceFormat::P010:
186 case SurfaceFormat::P016:
187 case SurfaceFormat::YUV422:
188 return true;
189 default:
190 return false;
191 }
192 }
193
194 // The matrix coeffiecients used for YUV to RGB conversion.
195 enum class YUVColorSpace : uint8_t {
196 BT601,
197 BT709,
198 BT2020,
199 Identity, // Todo: s/YUVColorSpace/ColorSpace/, s/Identity/SRGB/
200 Default = BT709,
201 _First = BT601,
202 _Last = Identity,
203 };
204
205 enum class ColorDepth : uint8_t {
206 COLOR_8,
207 COLOR_10,
208 COLOR_12,
209 COLOR_16,
210 _First = COLOR_8,
211 _Last = COLOR_16,
212 };
213
214 enum class ColorRange : uint8_t {
215 LIMITED,
216 FULL,
217 _First = LIMITED,
218 _Last = FULL,
219 };
220
221 // Really "YcbcrColorSpace"
222 enum class YUVRangedColorSpace : uint8_t {
223 BT601_Narrow = 0,
224 BT601_Full,
225 BT709_Narrow,
226 BT709_Full,
227 BT2020_Narrow,
228 BT2020_Full,
229 GbrIdentity,
230
231 _First = BT601_Narrow,
232 _Last = GbrIdentity,
233 Default = BT709_Narrow,
234 };
235
236 struct FromYUVRangedColorSpaceT final {
237 const YUVColorSpace space;
238 const ColorRange range;
239 };
240
FromYUVRangedColorSpace(const YUVRangedColorSpace s)241 inline FromYUVRangedColorSpaceT FromYUVRangedColorSpace(
242 const YUVRangedColorSpace s) {
243 switch (s) {
244 case YUVRangedColorSpace::BT601_Narrow:
245 return {YUVColorSpace::BT601, ColorRange::LIMITED};
246 case YUVRangedColorSpace::BT601_Full:
247 return {YUVColorSpace::BT601, ColorRange::FULL};
248
249 case YUVRangedColorSpace::BT709_Narrow:
250 return {YUVColorSpace::BT709, ColorRange::LIMITED};
251 case YUVRangedColorSpace::BT709_Full:
252 return {YUVColorSpace::BT709, ColorRange::FULL};
253
254 case YUVRangedColorSpace::BT2020_Narrow:
255 return {YUVColorSpace::BT2020, ColorRange::LIMITED};
256 case YUVRangedColorSpace::BT2020_Full:
257 return {YUVColorSpace::BT2020, ColorRange::FULL};
258
259 case YUVRangedColorSpace::GbrIdentity:
260 return {YUVColorSpace::Identity, ColorRange::FULL};
261 }
262 MOZ_CRASH("bad YUVRangedColorSpace");
263 }
264
265 // Todo: This should go in the CPP.
ToYUVRangedColorSpace(const YUVColorSpace space,const ColorRange range)266 inline YUVRangedColorSpace ToYUVRangedColorSpace(const YUVColorSpace space,
267 const ColorRange range) {
268 bool narrow;
269 switch (range) {
270 case ColorRange::FULL:
271 narrow = false;
272 break;
273 case ColorRange::LIMITED:
274 narrow = true;
275 break;
276 }
277
278 switch (space) {
279 case YUVColorSpace::Identity:
280 MOZ_ASSERT(range == ColorRange::FULL);
281 return YUVRangedColorSpace::GbrIdentity;
282
283 case YUVColorSpace::BT601:
284 return narrow ? YUVRangedColorSpace::BT601_Narrow
285 : YUVRangedColorSpace::BT601_Full;
286
287 case YUVColorSpace::BT709:
288 return narrow ? YUVRangedColorSpace::BT709_Narrow
289 : YUVRangedColorSpace::BT709_Full;
290
291 case YUVColorSpace::BT2020:
292 return narrow ? YUVRangedColorSpace::BT2020_Narrow
293 : YUVRangedColorSpace::BT2020_Full;
294 }
295 MOZ_CRASH("bad YUVColorSpace");
296 }
297
298 template <typename DescriptorT>
GetYUVRangedColorSpace(const DescriptorT & d)299 inline YUVRangedColorSpace GetYUVRangedColorSpace(const DescriptorT& d) {
300 return ToYUVRangedColorSpace(d.yUVColorSpace(), d.colorRange());
301 }
302
SurfaceFormatForColorDepth(ColorDepth aColorDepth)303 static inline SurfaceFormat SurfaceFormatForColorDepth(ColorDepth aColorDepth) {
304 SurfaceFormat format = SurfaceFormat::A8;
305 switch (aColorDepth) {
306 case ColorDepth::COLOR_8:
307 break;
308 case ColorDepth::COLOR_10:
309 case ColorDepth::COLOR_12:
310 case ColorDepth::COLOR_16:
311 format = SurfaceFormat::A16;
312 break;
313 }
314 return format;
315 }
316
BitDepthForColorDepth(ColorDepth aColorDepth)317 static inline uint32_t BitDepthForColorDepth(ColorDepth aColorDepth) {
318 uint32_t depth = 8;
319 switch (aColorDepth) {
320 case ColorDepth::COLOR_8:
321 break;
322 case ColorDepth::COLOR_10:
323 depth = 10;
324 break;
325 case ColorDepth::COLOR_12:
326 depth = 12;
327 break;
328 case ColorDepth::COLOR_16:
329 depth = 16;
330 break;
331 }
332 return depth;
333 }
334
ColorDepthForBitDepth(uint8_t aBitDepth)335 static inline ColorDepth ColorDepthForBitDepth(uint8_t aBitDepth) {
336 ColorDepth depth = ColorDepth::COLOR_8;
337 switch (aBitDepth) {
338 case 8:
339 break;
340 case 10:
341 depth = ColorDepth::COLOR_10;
342 break;
343 case 12:
344 depth = ColorDepth::COLOR_12;
345 break;
346 case 16:
347 depth = ColorDepth::COLOR_16;
348 break;
349 }
350 return depth;
351 }
352
353 // 10 and 12 bits color depth image are using 16 bits integers for storage
354 // As such we need to rescale the value from 10 or 12 bits to 16.
RescalingFactorForColorDepth(ColorDepth aColorDepth)355 static inline uint32_t RescalingFactorForColorDepth(ColorDepth aColorDepth) {
356 uint32_t factor = 1;
357 switch (aColorDepth) {
358 case ColorDepth::COLOR_8:
359 break;
360 case ColorDepth::COLOR_10:
361 factor = 64;
362 break;
363 case ColorDepth::COLOR_12:
364 factor = 16;
365 break;
366 case ColorDepth::COLOR_16:
367 break;
368 }
369 return factor;
370 }
371
372 enum class FilterType : int8_t {
373 BLEND = 0,
374 TRANSFORM,
375 MORPHOLOGY,
376 COLOR_MATRIX,
377 FLOOD,
378 TILE,
379 TABLE_TRANSFER,
380 DISCRETE_TRANSFER,
381 LINEAR_TRANSFER,
382 GAMMA_TRANSFER,
383 CONVOLVE_MATRIX,
384 DISPLACEMENT_MAP,
385 TURBULENCE,
386 ARITHMETIC_COMBINE,
387 COMPOSITE,
388 DIRECTIONAL_BLUR,
389 GAUSSIAN_BLUR,
390 POINT_DIFFUSE,
391 POINT_SPECULAR,
392 SPOT_DIFFUSE,
393 SPOT_SPECULAR,
394 DISTANT_DIFFUSE,
395 DISTANT_SPECULAR,
396 CROP,
397 PREMULTIPLY,
398 UNPREMULTIPLY,
399 OPACITY
400 };
401
402 enum class DrawTargetType : int8_t {
403 SOFTWARE_RASTER = 0,
404 HARDWARE_RASTER,
405 VECTOR
406 };
407
408 enum class BackendType : int8_t {
409 NONE = 0,
410 DIRECT2D, // Used for version independent D2D objects.
411 CAIRO,
412 SKIA,
413 RECORDING,
414 DIRECT2D1_1,
415 WEBRENDER_TEXT,
416 CAPTURE, // Used for paths
417
418 // Add new entries above this line.
419 BACKEND_LAST
420 };
421
422 enum class FontType : int8_t {
423 DWRITE,
424 GDI,
425 MAC,
426 FONTCONFIG,
427 FREETYPE,
428 UNKNOWN
429 };
430
431 enum class NativeSurfaceType : int8_t {
432 D3D10_TEXTURE,
433 CAIRO_CONTEXT,
434 CGCONTEXT,
435 CGCONTEXT_ACCELERATED,
436 OPENGL_TEXTURE
437 };
438
439 enum class FontStyle : int8_t { NORMAL, ITALIC, BOLD, BOLD_ITALIC };
440
441 enum class FontHinting : int8_t { NONE, LIGHT, NORMAL, FULL };
442
443 enum class CompositionOp : int8_t {
444 OP_OVER,
445 OP_ADD,
446 OP_ATOP,
447 OP_OUT,
448 OP_IN,
449 OP_SOURCE,
450 OP_DEST_IN,
451 OP_DEST_OUT,
452 OP_DEST_OVER,
453 OP_DEST_ATOP,
454 OP_XOR,
455 OP_MULTIPLY,
456 OP_SCREEN,
457 OP_OVERLAY,
458 OP_DARKEN,
459 OP_LIGHTEN,
460 OP_COLOR_DODGE,
461 OP_COLOR_BURN,
462 OP_HARD_LIGHT,
463 OP_SOFT_LIGHT,
464 OP_DIFFERENCE,
465 OP_EXCLUSION,
466 OP_HUE,
467 OP_SATURATION,
468 OP_COLOR,
469 OP_LUMINOSITY,
470 OP_COUNT
471 };
472
473 enum class Axis : int8_t { X_AXIS, Y_AXIS, BOTH };
474
475 enum class ExtendMode : int8_t {
476 CLAMP, // Do not repeat
477 REPEAT, // Repeat in both axis
478 REPEAT_X, // Only X axis
479 REPEAT_Y, // Only Y axis
480 REFLECT // Mirror the image
481 };
482
483 enum class FillRule : int8_t { FILL_WINDING, FILL_EVEN_ODD };
484
485 enum class AntialiasMode : int8_t { NONE, GRAY, SUBPIXEL, DEFAULT };
486
487 // See https://en.wikipedia.org/wiki/Texture_filtering
488 enum class SamplingFilter : int8_t {
489 GOOD,
490 LINEAR,
491 POINT,
492 SENTINEL // one past the last valid value
493 };
494
495 std::ostream& operator<<(std::ostream& aOut, const SamplingFilter& aFilter);
496
497 // clang-format off
498 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(PatternType, int8_t, (
499 COLOR,
500 SURFACE,
501 LINEAR_GRADIENT,
502 RADIAL_GRADIENT,
503 CONIC_GRADIENT
504 ));
505 // clang-format on
506
507 enum class JoinStyle : int8_t {
508 BEVEL,
509 ROUND,
510 MITER, //!< Mitered if within the miter limit, else, if the backed supports
511 //!< it (D2D), the miter is clamped. If the backend does not support
512 //!< miter clamping the behavior is as for MITER_OR_BEVEL.
513 MITER_OR_BEVEL //!< Mitered if within the miter limit, else beveled.
514 };
515
516 enum class CapStyle : int8_t { BUTT, ROUND, SQUARE };
517
518 enum class SamplingBounds : int8_t { UNBOUNDED, BOUNDED };
519
520 // Moz2d version for SVG mask types
521 enum class LuminanceType : int8_t {
522 LUMINANCE,
523 LINEARRGB,
524 };
525
526 /* Color is stored in non-premultiplied form in sRGB color space */
527 struct sRGBColor {
528 public:
sRGBColorsRGBColor529 constexpr sRGBColor() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {}
sRGBColorsRGBColor530 constexpr sRGBColor(Float aR, Float aG, Float aB, Float aA)
531 : r(aR), g(aG), b(aB), a(aA) {}
sRGBColorsRGBColor532 constexpr sRGBColor(Float aR, Float aG, Float aB)
533 : r(aR), g(aG), b(aB), a(1.0f) {}
534
WhitesRGBColor535 static constexpr sRGBColor White(float aA) {
536 return sRGBColor(1.f, 1.f, 1.f, aA);
537 }
538
BlacksRGBColor539 static constexpr sRGBColor Black(float aA) {
540 return sRGBColor(0.f, 0.f, 0.f, aA);
541 }
542
OpaqueWhitesRGBColor543 static constexpr sRGBColor OpaqueWhite() { return White(1.f); }
544
OpaqueBlacksRGBColor545 static constexpr sRGBColor OpaqueBlack() { return Black(1.f); }
546
FromU8sRGBColor547 static constexpr sRGBColor FromU8(uint8_t aR, uint8_t aG, uint8_t aB,
548 uint8_t aA) {
549 return sRGBColor(float(aR) / 255.f, float(aG) / 255.f, float(aB) / 255.f,
550 float(aA) / 255.f);
551 }
552
FromABGRsRGBColor553 static constexpr sRGBColor FromABGR(uint32_t aColor) {
554 return sRGBColor(((aColor >> 0) & 0xff) * (1.0f / 255.0f),
555 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
556 ((aColor >> 16) & 0xff) * (1.0f / 255.0f),
557 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
558 }
559
560 // The "Unusual" prefix is to avoid unintentionally using this function when
561 // FromABGR(), which is much more common, is needed.
UnusualFromARGBsRGBColor562 static constexpr sRGBColor UnusualFromARGB(uint32_t aColor) {
563 return sRGBColor(((aColor >> 16) & 0xff) * (1.0f / 255.0f),
564 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
565 ((aColor >> 0) & 0xff) * (1.0f / 255.0f),
566 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
567 }
568
ToABGRsRGBColor569 constexpr uint32_t ToABGR() const {
570 return uint32_t(r * 255.0f) | uint32_t(g * 255.0f) << 8 |
571 uint32_t(b * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
572 }
573
PremultipliedsRGBColor574 constexpr sRGBColor Premultiplied() const {
575 return sRGBColor(r * a, g * a, b * a, a);
576 }
577
UnpremultipliedsRGBColor578 constexpr sRGBColor Unpremultiplied() const {
579 return a > 0.f ? sRGBColor(r / a, g / a, b / a, a) : *this;
580 }
581
582 // Returns aFrac*aC2 + (1 - aFrac)*C1. The interpolation is done in
583 // unpremultiplied space, which is what SVG gradients and cairo gradients
584 // expect.
InterpolatePremultipliedsRGBColor585 constexpr static sRGBColor InterpolatePremultiplied(const sRGBColor& aC1,
586 const sRGBColor& aC2,
587 float aFrac) {
588 double other = 1 - aFrac;
589 return sRGBColor(
590 aC2.r * aFrac + aC1.r * other, aC2.g * aFrac + aC1.g * other,
591 aC2.b * aFrac + aC1.b * other, aC2.a * aFrac + aC1.a * other);
592 }
593
InterpolatesRGBColor594 constexpr static sRGBColor Interpolate(const sRGBColor& aC1,
595 const sRGBColor& aC2, float aFrac) {
596 return InterpolatePremultiplied(aC1.Premultiplied(), aC2.Premultiplied(),
597 aFrac)
598 .Unpremultiplied();
599 }
600
601 // The "Unusual" prefix is to avoid unintentionally using this function when
602 // ToABGR(), which is much more common, is needed.
UnusualToARGBsRGBColor603 uint32_t UnusualToARGB() const {
604 return uint32_t(b * 255.0f) | uint32_t(g * 255.0f) << 8 |
605 uint32_t(r * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
606 }
607
608 bool operator==(const sRGBColor& aColor) const {
609 return r == aColor.r && g == aColor.g && b == aColor.b && a == aColor.a;
610 }
611
612 bool operator!=(const sRGBColor& aColor) const { return !(*this == aColor); }
613
614 Float r, g, b, a;
615 };
616
617 /* Color is stored in non-premultiplied form in device color space */
618 struct DeviceColor {
619 public:
DeviceColorDeviceColor620 DeviceColor() : r(0.0f), g(0.0f), b(0.0f), a(0.0f) {}
DeviceColorDeviceColor621 DeviceColor(Float aR, Float aG, Float aB, Float aA)
622 : r(aR), g(aG), b(aB), a(aA) {}
DeviceColorDeviceColor623 DeviceColor(Float aR, Float aG, Float aB) : r(aR), g(aG), b(aB), a(1.0f) {}
624
625 /* The following Mask* variants are helpers used to make it clear when a
626 * particular color is being used for masking purposes. These masks should
627 * never be colored managed. */
MaskDeviceColor628 static DeviceColor Mask(float aC, float aA) {
629 return DeviceColor(aC, aC, aC, aA);
630 }
631
MaskWhiteDeviceColor632 static DeviceColor MaskWhite(float aA) { return Mask(1.f, aA); }
633
MaskBlackDeviceColor634 static DeviceColor MaskBlack(float aA) { return Mask(0.f, aA); }
635
MaskOpaqueWhiteDeviceColor636 static DeviceColor MaskOpaqueWhite() { return MaskWhite(1.f); }
637
MaskOpaqueBlackDeviceColor638 static DeviceColor MaskOpaqueBlack() { return MaskBlack(1.f); }
639
FromU8DeviceColor640 static DeviceColor FromU8(uint8_t aR, uint8_t aG, uint8_t aB, uint8_t aA) {
641 return DeviceColor(float(aR) / 255.f, float(aG) / 255.f, float(aB) / 255.f,
642 float(aA) / 255.f);
643 }
644
FromABGRDeviceColor645 static DeviceColor FromABGR(uint32_t aColor) {
646 DeviceColor newColor(((aColor >> 0) & 0xff) * (1.0f / 255.0f),
647 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
648 ((aColor >> 16) & 0xff) * (1.0f / 255.0f),
649 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
650
651 return newColor;
652 }
653
654 // The "Unusual" prefix is to avoid unintentionally using this function when
655 // FromABGR(), which is much more common, is needed.
UnusualFromARGBDeviceColor656 static DeviceColor UnusualFromARGB(uint32_t aColor) {
657 DeviceColor newColor(((aColor >> 16) & 0xff) * (1.0f / 255.0f),
658 ((aColor >> 8) & 0xff) * (1.0f / 255.0f),
659 ((aColor >> 0) & 0xff) * (1.0f / 255.0f),
660 ((aColor >> 24) & 0xff) * (1.0f / 255.0f));
661
662 return newColor;
663 }
664
ToABGRDeviceColor665 uint32_t ToABGR() const {
666 return uint32_t(r * 255.0f) | uint32_t(g * 255.0f) << 8 |
667 uint32_t(b * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
668 }
669
670 // The "Unusual" prefix is to avoid unintentionally using this function when
671 // ToABGR(), which is much more common, is needed.
UnusualToARGBDeviceColor672 uint32_t UnusualToARGB() const {
673 return uint32_t(b * 255.0f) | uint32_t(g * 255.0f) << 8 |
674 uint32_t(r * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
675 }
676
677 bool operator==(const DeviceColor& aColor) const {
678 return r == aColor.r && g == aColor.g && b == aColor.b && a == aColor.a;
679 }
680
681 bool operator!=(const DeviceColor& aColor) const {
682 return !(*this == aColor);
683 }
684
685 friend std::ostream& operator<<(std::ostream& aOut,
686 const DeviceColor& aColor);
687
688 Float r, g, b, a;
689 };
690
691 struct GradientStop {
692 bool operator<(const GradientStop& aOther) const {
693 return offset < aOther.offset;
694 }
695
696 Float offset;
697 DeviceColor color;
698 };
699
700 enum class JobStatus { Complete, Wait, Yield, Error };
701
702 } // namespace gfx
703 } // namespace mozilla
704
705 // XXX: temporary
706 typedef mozilla::gfx::SurfaceFormat gfxImageFormat;
707
708 #if defined(XP_WIN) && defined(MOZ_GFX)
709 # ifdef GFX2D_INTERNAL
710 # define GFX2D_API __declspec(dllexport)
711 # else
712 # define GFX2D_API __declspec(dllimport)
713 # endif
714 #else
715 # define GFX2D_API
716 #endif
717
718 namespace mozilla {
719
720 // Side constants for use in various places.
721 enum Side : uint8_t { eSideTop, eSideRight, eSideBottom, eSideLeft };
722
AllPhysicalSides()723 constexpr auto AllPhysicalSides() {
724 return mozilla::MakeInclusiveEnumeratedRange(eSideTop, eSideLeft);
725 }
726
727 enum class SideBits {
728 eNone = 0,
729 eTop = 1 << eSideTop,
730 eRight = 1 << eSideRight,
731 eBottom = 1 << eSideBottom,
732 eLeft = 1 << eSideLeft,
733 eTopBottom = SideBits::eTop | SideBits::eBottom,
734 eLeftRight = SideBits::eLeft | SideBits::eRight,
735 eAll = SideBits::eTopBottom | SideBits::eLeftRight
736 };
737
738 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SideBits)
739
740 enum Corner : uint8_t {
741 // This order is important!
742 eCornerTopLeft = 0,
743 eCornerTopRight = 1,
744 eCornerBottomRight = 2,
745 eCornerBottomLeft = 3
746 };
747
748 // RectCornerRadii::radii depends on this value. It is not being added to
749 // Corner because we want to lift the responsibility to handle it in the
750 // switch-case.
751 constexpr int eCornerCount = 4;
752
AllPhysicalCorners()753 constexpr auto AllPhysicalCorners() {
754 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeft,
755 eCornerBottomLeft);
756 }
757
758 // Indices into "half corner" arrays (nsStyleCorners e.g.)
759 enum HalfCorner : uint8_t {
760 // This order is important!
761 eCornerTopLeftX = 0,
762 eCornerTopLeftY = 1,
763 eCornerTopRightX = 2,
764 eCornerTopRightY = 3,
765 eCornerBottomRightX = 4,
766 eCornerBottomRightY = 5,
767 eCornerBottomLeftX = 6,
768 eCornerBottomLeftY = 7
769 };
770
AllPhysicalHalfCorners()771 constexpr auto AllPhysicalHalfCorners() {
772 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeftX,
773 eCornerBottomLeftY);
774 }
775
776 // The result of these conversion functions are exhaustively checked in
777 // nsFrame.cpp, which also serves as usage examples.
778
HalfCornerIsX(HalfCorner aHalfCorner)779 constexpr bool HalfCornerIsX(HalfCorner aHalfCorner) {
780 return !(aHalfCorner % 2);
781 }
782
HalfToFullCorner(HalfCorner aHalfCorner)783 constexpr Corner HalfToFullCorner(HalfCorner aHalfCorner) {
784 return Corner(aHalfCorner / 2);
785 }
786
FullToHalfCorner(Corner aCorner,bool aIsVertical)787 constexpr HalfCorner FullToHalfCorner(Corner aCorner, bool aIsVertical) {
788 return HalfCorner(aCorner * 2 + aIsVertical);
789 }
790
SideIsVertical(mozilla::Side aSide)791 constexpr bool SideIsVertical(mozilla::Side aSide) { return aSide % 2; }
792
793 // @param aIsSecond when true, return the clockwise second of the two
794 // corners associated with aSide. For example, with aSide = eSideBottom the
795 // result is eCornerBottomRight when aIsSecond is false, and
796 // eCornerBottomLeft when aIsSecond is true.
SideToFullCorner(mozilla::Side aSide,bool aIsSecond)797 constexpr Corner SideToFullCorner(mozilla::Side aSide, bool aIsSecond) {
798 return Corner((aSide + aIsSecond) % 4);
799 }
800
801 // @param aIsSecond see SideToFullCorner.
802 // @param aIsParallel return the half-corner that is parallel with aSide
803 // when aIsParallel is true. For example with aSide=eSideTop, aIsSecond=true
804 // the result is eCornerTopRightX when aIsParallel is true, and
805 // eCornerTopRightY when aIsParallel is false (because "X" is parallel with
806 // eSideTop/eSideBottom, similarly "Y" is parallel with
807 // eSideLeft/eSideRight)
SideToHalfCorner(mozilla::Side aSide,bool aIsSecond,bool aIsParallel)808 constexpr HalfCorner SideToHalfCorner(mozilla::Side aSide, bool aIsSecond,
809 bool aIsParallel) {
810 return HalfCorner(((aSide + aIsSecond) * 2 + (aSide + !aIsParallel) % 2) % 8);
811 }
812
813 } // namespace mozilla
814
815 #endif /* MOZILLA_GFX_TYPES_H_ */
816