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/. */
7 #ifndef MOZILLA_GFX_TYPES_H_
8 #define MOZILLA_GFX_TYPES_H_
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"
16 #include <iosfwd> // for ostream
25 typedef double Double
;
27 enum class SurfaceType
: int8_t {
28 DATA
, /* Data surface - bitmap in memory */
29 D2D1_BITMAP
, /* Surface wrapping a ID2D1Bitmap */
30 D2D1_DRAWTARGET
, /* Surface made from a D2D draw target */
31 CAIRO
, /* Surface wrapping a cairo surface */
32 CAIRO_IMAGE
, /* Data surface wrapping a cairo image surface */
33 COREGRAPHICS_IMAGE
, /* Surface wrapping a CoreGraphics Image */
34 COREGRAPHICS_CGCONTEXT
, /* Surface wrapping a CG context */
35 SKIA
, /* Surface wrapping a Skia bitmap */
36 D2D1_1_IMAGE
, /* A D2D 1.1 ID2D1Image SourceSurface */
37 RECORDING
, /* Surface used for recording */
38 DATA_SHARED
, /* Data surface using shared memory */
39 DATA_RECYCLING_SHARED
, /* Data surface using shared memory */
41 DATA_ALIGNED
, /* Data surface using aligned heap memory */
42 DATA_SHARED_WRAPPER
, /* Shared memory mapped in from another process */
43 BLOB_IMAGE
, /* Recorded blob image */
44 DATA_MAPPED
, /* Data surface wrapping a ScopedMap */
45 WEBGL
, /* Surface wrapping a DrawTargetWebgl texture */
48 enum class SurfaceFormat
: int8_t {
49 // The following values are named to reflect layout of colors in memory, from
50 // lowest byte to highest byte. The 32-bit value layout depends on machine
52 // in-memory 32-bit LE value 32-bit BE value
53 B8G8R8A8
, // [BB, GG, RR, AA] 0xAARRGGBB 0xBBGGRRAA
54 B8G8R8X8
, // [BB, GG, RR, 00] 0x00RRGGBB 0xBBGGRR00
55 R8G8B8A8
, // [RR, GG, BB, AA] 0xAABBGGRR 0xRRGGBBAA
56 R8G8B8X8
, // [RR, GG, BB, 00] 0x00BBGGRR 0xRRGGBB00
57 A8R8G8B8
, // [AA, RR, GG, BB] 0xBBGGRRAA 0xAARRGGBB
58 X8R8G8B8
, // [00, RR, GG, BB] 0xBBGGRR00 0x00RRGGBB
63 // The _UINT16 suffix here indicates that the name reflects the layout when
64 // viewed as a uint16_t value. In memory these values are stored using native
66 R5G6B5_UINT16
, // 0bRRRRRGGGGGGBBBBB
68 // This one is a single-byte, so endianness isn't an issue.
75 // These ones are their own special cases.
77 NV12
, // YUV 4:2:0 image with a plane of 8 bit Y samples followed by
78 // an interleaved U/V plane containing 8 bit 2x2 subsampled
79 // colour difference samples.
80 P016
, // Similar to NV12, but with 16 bits plane values
81 P010
, // Identical to P016 but the 6 least significant bits are 0.
82 // With DXGI in theory entirely compatible, however practice has
83 // shown that it's not the case.
84 YUV422
, // Single plane YUV 4:2:2 interleaved as Y`0 Cb Y`1 Cr.
89 // This represents the unknown format.
90 UNKNOWN
, // TODO: Replace uses with Maybe<SurfaceFormat>.
92 // The following values are endian-independent synonyms. The _UINT32 suffix
93 // indicates that the name reflects the layout when viewed as a uint32_t
95 #if MOZ_LITTLE_ENDIAN()
96 A8R8G8B8_UINT32
= B8G8R8A8
, // 0xAARRGGBB
97 X8R8G8B8_UINT32
= B8G8R8X8
, // 0x00RRGGBB
98 #elif MOZ_BIG_ENDIAN()
99 A8R8G8B8_UINT32
= A8R8G8B8
, // 0xAARRGGBB
100 X8R8G8B8_UINT32
= X8R8G8B8
, // 0x00RRGGBB
102 # error "bad endianness"
105 // The following values are OS and endian-independent synonyms.
107 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
108 // can make this use R8B8G8A8 and R8B8G8X8 for non-Windows platforms.
109 OS_RGBA
= A8R8G8B8_UINT32
,
110 OS_RGBX
= X8R8G8B8_UINT32
113 struct SurfaceFormatInfo
{
117 std::optional
<uint8_t> bytesPerPixel
;
119 inline std::optional
<SurfaceFormatInfo
> Info(const SurfaceFormat aFormat
) {
120 auto info
= SurfaceFormatInfo
{};
123 case SurfaceFormat::B8G8R8A8
:
124 case SurfaceFormat::R8G8B8A8
:
125 case SurfaceFormat::A8R8G8B8
:
126 info
.hasColor
= true;
127 info
.hasAlpha
= true;
130 case SurfaceFormat::B8G8R8X8
:
131 case SurfaceFormat::R8G8B8X8
:
132 case SurfaceFormat::X8R8G8B8
:
133 case SurfaceFormat::R8G8B8
:
134 case SurfaceFormat::B8G8R8
:
135 case SurfaceFormat::R5G6B5_UINT16
:
136 case SurfaceFormat::R8G8
:
137 case SurfaceFormat::R16G16
:
138 case SurfaceFormat::HSV
:
139 case SurfaceFormat::Lab
:
140 info
.hasColor
= true;
141 info
.hasAlpha
= false;
144 case SurfaceFormat::A8
:
145 case SurfaceFormat::A16
:
146 info
.hasColor
= false;
147 info
.hasAlpha
= true;
150 case SurfaceFormat::YUV
:
151 case SurfaceFormat::NV12
:
152 case SurfaceFormat::P016
:
153 case SurfaceFormat::P010
:
154 case SurfaceFormat::YUV422
:
155 info
.hasColor
= true;
156 info
.hasAlpha
= false;
160 case SurfaceFormat::Depth
:
161 info
.hasColor
= false;
162 info
.hasAlpha
= false;
166 case SurfaceFormat::UNKNOWN
:
174 case SurfaceFormat::B8G8R8A8
:
175 case SurfaceFormat::R8G8B8A8
:
176 case SurfaceFormat::A8R8G8B8
:
177 case SurfaceFormat::B8G8R8X8
:
178 case SurfaceFormat::R8G8B8X8
:
179 case SurfaceFormat::X8R8G8B8
:
180 case SurfaceFormat::R16G16
:
181 info
.bytesPerPixel
= 4;
184 case SurfaceFormat::R8G8B8
:
185 case SurfaceFormat::B8G8R8
:
186 info
.bytesPerPixel
= 3;
189 case SurfaceFormat::R5G6B5_UINT16
:
190 case SurfaceFormat::R8G8
:
191 case SurfaceFormat::A16
:
192 case SurfaceFormat::Depth
: // uint16_t
193 info
.bytesPerPixel
= 2;
196 case SurfaceFormat::A8
:
197 info
.bytesPerPixel
= 1;
200 case SurfaceFormat::HSV
:
201 case SurfaceFormat::Lab
:
202 info
.bytesPerPixel
= 3 * sizeof(float);
205 case SurfaceFormat::YUV
:
206 case SurfaceFormat::NV12
:
207 case SurfaceFormat::P016
:
208 case SurfaceFormat::P010
:
209 case SurfaceFormat::YUV422
:
210 case SurfaceFormat::UNKNOWN
:
211 break; // No bytesPerPixel per se.
216 if (aFormat
== SurfaceFormat::UNKNOWN
) {
222 std::ostream
& operator<<(std::ostream
& aOut
, const SurfaceFormat
& aFormat
);
224 // Represents the bit-shifts required to access color channels when the layout
225 // is viewed as a uint32_t value.
226 enum class SurfaceFormatBit
: uint32_t {
227 #if MOZ_LITTLE_ENDIAN()
232 #elif MOZ_BIG_ENDIAN()
238 # error "bad endianness"
241 // The following values are endian-independent for A8R8G8B8_UINT32.
242 A8R8G8B8_UINT32_B
= 0,
243 A8R8G8B8_UINT32_G
= 8,
244 A8R8G8B8_UINT32_R
= 16,
245 A8R8G8B8_UINT32_A
= 24,
247 // The following values are OS and endian-independent.
249 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
250 // can make this use R8G8B8A8_X for non-Windows platforms.
251 OS_R
= A8R8G8B8_UINT32_R
,
252 OS_G
= A8R8G8B8_UINT32_G
,
253 OS_B
= A8R8G8B8_UINT32_B
,
254 OS_A
= A8R8G8B8_UINT32_A
,
257 inline uint32_t operator<<(uint8_t a
, SurfaceFormatBit b
) {
258 return a
<< static_cast<uint32_t>(b
);
261 inline uint32_t operator>>(uint32_t a
, SurfaceFormatBit b
) {
262 return a
>> static_cast<uint32_t>(b
);
265 static inline int BytesPerPixel(SurfaceFormat aFormat
) {
266 // TODO: return Info(aFormat).value().bytesPerPixel.value();
268 case SurfaceFormat::A8
:
270 case SurfaceFormat::R5G6B5_UINT16
:
271 case SurfaceFormat::A16
:
273 case SurfaceFormat::R8G8B8
:
274 case SurfaceFormat::B8G8R8
:
276 case SurfaceFormat::HSV
:
277 case SurfaceFormat::Lab
:
278 return 3 * sizeof(float);
279 case SurfaceFormat::Depth
:
280 return sizeof(uint16_t);
286 inline bool IsOpaque(SurfaceFormat aFormat
) {
287 // TODO: return Info(aFormat).value().hasAlpha;
289 case SurfaceFormat::B8G8R8X8
:
290 case SurfaceFormat::R8G8B8X8
:
291 case SurfaceFormat::X8R8G8B8
:
292 case SurfaceFormat::R5G6B5_UINT16
:
293 case SurfaceFormat::R8G8B8
:
294 case SurfaceFormat::B8G8R8
:
295 case SurfaceFormat::R8G8
:
296 case SurfaceFormat::HSV
:
297 case SurfaceFormat::Lab
:
298 case SurfaceFormat::Depth
:
299 case SurfaceFormat::YUV
:
300 case SurfaceFormat::NV12
:
301 case SurfaceFormat::P010
:
302 case SurfaceFormat::P016
:
303 case SurfaceFormat::YUV422
:
310 // These are standardized Coding-independent Code Points
311 // See [Rec. ITU-T H.273
312 // (12/2016)](https://www.itu.int/rec/T-REC-H.273-201612-I/en)
314 // We deliberately use an unscoped enum with fixed uint8_t representation since
315 // all possible values [0, 255] are legal, but it's unwieldy to declare 200+
316 // "RESERVED" enumeration values. Having a fixed underlying type avoids any
317 // potential UB and avoids the need for a cast when passing these values across
318 // FFI to functions like qcms_profile_create_cicp.
320 enum ColourPrimaries
: uint8_t {
321 CP_RESERVED_MIN
= 0, // 0, 3, [13, 21], [23, 255] are all reserved
336 inline bool IsReserved(ColourPrimaries aIn
) {
344 case CP_GENERIC_FILM
:
356 enum TransferCharacteristics
: uint8_t {
357 TC_RESERVED_MIN
= 0, // 0, 3, [19, 255] are all reserved
366 TC_LOG_100_SQRT10
= 10,
370 TC_BT2020_10BIT
= 14,
371 TC_BT2020_12BIT
= 15,
377 inline bool IsReserved(TransferCharacteristics aIn
) {
387 case TC_LOG_100_SQRT10
:
391 case TC_BT2020_10BIT
:
392 case TC_BT2020_12BIT
:
402 enum MatrixCoefficients
: uint8_t {
406 MC_RESERVED_MIN
= 3, // 3, [15, 255] are all reserved
420 inline bool IsReserved(MatrixCoefficients aIn
) {
425 case MC_RESERVED_MIN
:
444 // The matrix coeffiecients used for YUV to RGB conversion.
445 enum class YUVColorSpace
: uint8_t {
449 Identity
, // Todo: s/YUVColorSpace/ColorSpace/, s/Identity/SRGB/
455 enum class ColorDepth
: uint8_t {
464 enum class TransferFunction
: uint8_t {
474 enum class ColorRange
: uint8_t {
481 // Really "YcbcrColorColorSpace"
482 enum class YUVRangedColorSpace
: uint8_t {
491 _First
= BT601_Narrow
,
493 Default
= BT709_Narrow
,
496 // I can either come up with a longer "very clever" name that doesn't conflict
497 // with FilterSupport.h, embrace and expand FilterSupport, or rename the old
499 // Some times Worse Is Better.
500 enum class ColorSpace2
: uint8_t {
502 UNKNOWN
= Display
, // We feel sufficiently bad about this TODO.
505 BT601_525
, // aka smpte170m NTSC
506 BT709
, // Same gamut as SRGB, but different gamma.
508 BT709
, // aka bt470bg PAL. Basically BT709, just Xg is 0.290 not 0.300.
514 inline ColorSpace2
ToColorSpace2(const YUVColorSpace in
) {
516 case YUVColorSpace::BT601
:
517 return ColorSpace2::BT601_525
;
518 case YUVColorSpace::BT709
:
519 return ColorSpace2::BT709
;
520 case YUVColorSpace::BT2020
:
521 return ColorSpace2::BT2020
;
522 case YUVColorSpace::Identity
:
523 return ColorSpace2::SRGB
;
525 MOZ_ASSERT_UNREACHABLE();
528 inline YUVColorSpace
ToYUVColorSpace(const ColorSpace2 in
) {
530 case ColorSpace2::BT601_525
:
531 return YUVColorSpace::BT601
;
532 case ColorSpace2::BT709
:
533 return YUVColorSpace::BT709
;
534 case ColorSpace2::BT2020
:
535 return YUVColorSpace::BT2020
;
536 case ColorSpace2::SRGB
:
537 return YUVColorSpace::Identity
;
539 case ColorSpace2::UNKNOWN
:
540 case ColorSpace2::DISPLAY_P3
:
541 MOZ_CRASH("Bad ColorSpace2 for ToYUVColorSpace");
543 MOZ_ASSERT_UNREACHABLE();
546 struct FromYUVRangedColorSpaceT final
{
547 const YUVColorSpace space
;
548 const ColorRange range
;
551 inline FromYUVRangedColorSpaceT
FromYUVRangedColorSpace(
552 const YUVRangedColorSpace s
) {
554 case YUVRangedColorSpace::BT601_Narrow
:
555 return {YUVColorSpace::BT601
, ColorRange::LIMITED
};
556 case YUVRangedColorSpace::BT601_Full
:
557 return {YUVColorSpace::BT601
, ColorRange::FULL
};
559 case YUVRangedColorSpace::BT709_Narrow
:
560 return {YUVColorSpace::BT709
, ColorRange::LIMITED
};
561 case YUVRangedColorSpace::BT709_Full
:
562 return {YUVColorSpace::BT709
, ColorRange::FULL
};
564 case YUVRangedColorSpace::BT2020_Narrow
:
565 return {YUVColorSpace::BT2020
, ColorRange::LIMITED
};
566 case YUVRangedColorSpace::BT2020_Full
:
567 return {YUVColorSpace::BT2020
, ColorRange::FULL
};
569 case YUVRangedColorSpace::GbrIdentity
:
570 return {YUVColorSpace::Identity
, ColorRange::FULL
};
572 MOZ_CRASH("bad YUVRangedColorSpace");
575 // Todo: This should go in the CPP.
576 inline YUVRangedColorSpace
ToYUVRangedColorSpace(const YUVColorSpace space
,
577 const ColorRange range
) {
580 case ColorRange::FULL
:
583 case ColorRange::LIMITED
:
589 case YUVColorSpace::Identity
:
590 MOZ_ASSERT(range
== ColorRange::FULL
);
591 return YUVRangedColorSpace::GbrIdentity
;
593 case YUVColorSpace::BT601
:
594 return narrow
? YUVRangedColorSpace::BT601_Narrow
595 : YUVRangedColorSpace::BT601_Full
;
597 case YUVColorSpace::BT709
:
598 return narrow
? YUVRangedColorSpace::BT709_Narrow
599 : YUVRangedColorSpace::BT709_Full
;
601 case YUVColorSpace::BT2020
:
602 return narrow
? YUVRangedColorSpace::BT2020_Narrow
603 : YUVRangedColorSpace::BT2020_Full
;
605 MOZ_CRASH("bad YUVColorSpace");
608 template <typename DescriptorT
>
609 inline YUVRangedColorSpace
GetYUVRangedColorSpace(const DescriptorT
& d
) {
610 return ToYUVRangedColorSpace(d
.yUVColorSpace(), d
.colorRange());
613 static inline SurfaceFormat
SurfaceFormatForColorDepth(ColorDepth aColorDepth
) {
614 SurfaceFormat format
= SurfaceFormat::A8
;
615 switch (aColorDepth
) {
616 case ColorDepth::COLOR_8
:
618 case ColorDepth::COLOR_10
:
619 case ColorDepth::COLOR_12
:
620 case ColorDepth::COLOR_16
:
621 format
= SurfaceFormat::A16
;
627 static inline uint8_t BitDepthForColorDepth(ColorDepth aColorDepth
) {
629 switch (aColorDepth
) {
630 case ColorDepth::COLOR_8
:
632 case ColorDepth::COLOR_10
:
635 case ColorDepth::COLOR_12
:
638 case ColorDepth::COLOR_16
:
645 static inline ColorDepth
ColorDepthForBitDepth(uint8_t aBitDepth
) {
646 ColorDepth depth
= ColorDepth::COLOR_8
;
651 depth
= ColorDepth::COLOR_10
;
654 depth
= ColorDepth::COLOR_12
;
657 depth
= ColorDepth::COLOR_16
;
663 // 10 and 12 bits color depth image are using 16 bits integers for storage
664 // As such we need to rescale the value from 10 or 12 bits to 16.
665 static inline uint32_t RescalingFactorForColorDepth(ColorDepth aColorDepth
) {
667 switch (aColorDepth
) {
668 case ColorDepth::COLOR_8
:
670 case ColorDepth::COLOR_10
:
673 case ColorDepth::COLOR_12
:
676 case ColorDepth::COLOR_16
:
682 enum class ChromaSubsampling
: uint8_t {
685 HALF_WIDTH_AND_HEIGHT
,
687 _Last
= HALF_WIDTH_AND_HEIGHT
,
690 template <typename T
>
691 static inline T
ChromaSize(const T
& aYSize
, ChromaSubsampling aSubsampling
) {
692 switch (aSubsampling
) {
693 case ChromaSubsampling::FULL
:
695 case ChromaSubsampling::HALF_WIDTH
:
696 return T((aYSize
.width
+ 1) / 2, aYSize
.height
);
697 case ChromaSubsampling::HALF_WIDTH_AND_HEIGHT
:
698 return T((aYSize
.width
+ 1) / 2, (aYSize
.height
+ 1) / 2);
700 MOZ_CRASH("bad ChromaSubsampling");
703 enum class FilterType
: int8_t {
733 enum class DrawTargetType
: int8_t {
739 enum class BackendType
: int8_t {
741 DIRECT2D
, // Used for version independent D2D objects.
749 // Add new entries above this line.
753 enum class RecorderType
: int8_t {
762 enum class FontType
: int8_t {
771 enum class NativeSurfaceType
: int8_t {
775 CGCONTEXT_ACCELERATED
,
780 enum class FontStyle
: int8_t { NORMAL
, ITALIC
, BOLD
, BOLD_ITALIC
};
782 enum class FontHinting
: int8_t { NONE
, LIGHT
, NORMAL
, FULL
};
784 enum class CompositionOp
: int8_t {
815 enum class Axis
: int8_t { X_AXIS
, Y_AXIS
, BOTH
};
817 enum class ExtendMode
: int8_t {
818 CLAMP
, // Do not repeat
819 REPEAT
, // Repeat in both axis
820 REPEAT_X
, // Only X axis
821 REPEAT_Y
, // Only Y axis
822 REFLECT
// Mirror the image
825 enum class FillRule
: int8_t { FILL_WINDING
, FILL_EVEN_ODD
};
827 enum class AntialiasMode
: int8_t { NONE
, GRAY
, SUBPIXEL
, DEFAULT
};
829 // See https://en.wikipedia.org/wiki/Texture_filtering
830 enum class SamplingFilter
: int8_t {
834 SENTINEL
// one past the last valid value
837 std::ostream
& operator<<(std::ostream
& aOut
, const SamplingFilter
& aFilter
);
840 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(PatternType
, int8_t, (
849 enum class JoinStyle
: int8_t {
852 MITER
, //!< Mitered if within the miter limit, else, if the backed supports
853 //!< it (D2D), the miter is clamped. If the backend does not support
854 //!< miter clamping the behavior is as for MITER_OR_BEVEL.
855 MITER_OR_BEVEL
//!< Mitered if within the miter limit, else beveled.
858 enum class CapStyle
: int8_t { BUTT
, ROUND
, SQUARE
};
860 enum class SamplingBounds
: int8_t { UNBOUNDED
, BOUNDED
};
862 // Moz2d version for SVG mask types
863 enum class LuminanceType
: int8_t {
868 /* Color is stored in non-premultiplied form in sRGB color space */
871 constexpr sRGBColor() : r(0.0f
), g(0.0f
), b(0.0f
), a(0.0f
) {}
872 constexpr sRGBColor(Float aR
, Float aG
, Float aB
, Float aA
)
873 : r(aR
), g(aG
), b(aB
), a(aA
) {}
874 constexpr sRGBColor(Float aR
, Float aG
, Float aB
)
875 : r(aR
), g(aG
), b(aB
), a(1.0f
) {}
877 static constexpr sRGBColor
White(float aA
) {
878 return sRGBColor(1.f
, 1.f
, 1.f
, aA
);
881 static constexpr sRGBColor
Black(float aA
) {
882 return sRGBColor(0.f
, 0.f
, 0.f
, aA
);
885 static constexpr sRGBColor
OpaqueWhite() { return White(1.f
); }
887 static constexpr sRGBColor
OpaqueBlack() { return Black(1.f
); }
889 static constexpr sRGBColor
FromU8(uint8_t aR
, uint8_t aG
, uint8_t aB
,
891 return sRGBColor(float(aR
) / 255.f
, float(aG
) / 255.f
, float(aB
) / 255.f
,
895 static constexpr sRGBColor
FromABGR(uint32_t aColor
) {
896 return sRGBColor(((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
897 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
898 ((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
899 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
902 // The "Unusual" prefix is to avoid unintentionally using this function when
903 // FromABGR(), which is much more common, is needed.
904 static constexpr sRGBColor
UnusualFromARGB(uint32_t aColor
) {
905 return sRGBColor(((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
906 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
907 ((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
908 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
911 constexpr uint32_t ToABGR() const {
912 return uint32_t(r
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
913 uint32_t(b
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
916 constexpr sRGBColor
Premultiplied() const {
917 return sRGBColor(r
* a
, g
* a
, b
* a
, a
);
920 constexpr sRGBColor
Unpremultiplied() const {
921 return a
> 0.f
? sRGBColor(r
/ a
, g
/ a
, b
/ a
, a
) : *this;
924 // The "Unusual" prefix is to avoid unintentionally using this function when
925 // ToABGR(), which is much more common, is needed.
926 uint32_t UnusualToARGB() const {
927 return uint32_t(b
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
928 uint32_t(r
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
931 bool operator==(const sRGBColor
& aColor
) const {
932 return r
== aColor
.r
&& g
== aColor
.g
&& b
== aColor
.b
&& a
== aColor
.a
;
935 bool operator!=(const sRGBColor
& aColor
) const { return !(*this == aColor
); }
940 /* Color is stored in non-premultiplied form in device color space */
943 DeviceColor() : r(0.0f
), g(0.0f
), b(0.0f
), a(0.0f
) {}
944 DeviceColor(Float aR
, Float aG
, Float aB
, Float aA
)
945 : r(aR
), g(aG
), b(aB
), a(aA
) {}
946 DeviceColor(Float aR
, Float aG
, Float aB
) : r(aR
), g(aG
), b(aB
), a(1.0f
) {}
948 /* The following Mask* variants are helpers used to make it clear when a
949 * particular color is being used for masking purposes. These masks should
950 * never be colored managed. */
951 static DeviceColor
Mask(float aC
, float aA
) {
952 return DeviceColor(aC
, aC
, aC
, aA
);
955 static DeviceColor
MaskWhite(float aA
) { return Mask(1.f
, aA
); }
957 static DeviceColor
MaskBlack(float aA
) { return Mask(0.f
, aA
); }
959 static DeviceColor
MaskOpaqueWhite() { return MaskWhite(1.f
); }
961 static DeviceColor
MaskOpaqueBlack() { return MaskBlack(1.f
); }
963 static DeviceColor
FromU8(uint8_t aR
, uint8_t aG
, uint8_t aB
, uint8_t aA
) {
964 return DeviceColor(float(aR
) / 255.f
, float(aG
) / 255.f
, float(aB
) / 255.f
,
968 static DeviceColor
FromABGR(uint32_t aColor
) {
969 DeviceColor
newColor(((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
970 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
971 ((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
972 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
977 // The "Unusual" prefix is to avoid unintentionally using this function when
978 // FromABGR(), which is much more common, is needed.
979 static DeviceColor
UnusualFromARGB(uint32_t aColor
) {
980 DeviceColor
newColor(((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
981 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
982 ((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
983 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
988 uint32_t ToABGR() const {
989 return uint32_t(r
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
990 uint32_t(b
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
993 // The "Unusual" prefix is to avoid unintentionally using this function when
994 // ToABGR(), which is much more common, is needed.
995 uint32_t UnusualToARGB() const {
996 return uint32_t(b
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
997 uint32_t(r
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
1000 bool operator==(const DeviceColor
& aColor
) const {
1001 return r
== aColor
.r
&& g
== aColor
.g
&& b
== aColor
.b
&& a
== aColor
.a
;
1004 bool operator!=(const DeviceColor
& aColor
) const {
1005 return !(*this == aColor
);
1008 friend std::ostream
& operator<<(std::ostream
& aOut
,
1009 const DeviceColor
& aColor
);
1014 struct GradientStop
{
1015 bool operator<(const GradientStop
& aOther
) const {
1016 return offset
< aOther
.offset
;
1023 enum class JobStatus
{ Complete
, Wait
, Yield
, Error
};
1026 } // namespace mozilla
1029 typedef mozilla::gfx::SurfaceFormat gfxImageFormat
;
1031 #if defined(XP_WIN) && defined(MOZ_GFX)
1032 # ifdef GFX2D_INTERNAL
1033 # define GFX2D_API __declspec(dllexport)
1035 # define GFX2D_API __declspec(dllimport)
1043 // Side constants for use in various places.
1044 enum Side
: uint8_t { eSideTop
, eSideRight
, eSideBottom
, eSideLeft
};
1046 std::ostream
& operator<<(std::ostream
&, const mozilla::Side
&);
1048 constexpr auto AllPhysicalSides() {
1049 return mozilla::MakeInclusiveEnumeratedRange(eSideTop
, eSideLeft
);
1052 enum class SideBits
{
1054 eTop
= 1 << eSideTop
,
1055 eRight
= 1 << eSideRight
,
1056 eBottom
= 1 << eSideBottom
,
1057 eLeft
= 1 << eSideLeft
,
1058 eTopBottom
= SideBits::eTop
| SideBits::eBottom
,
1059 eLeftRight
= SideBits::eLeft
| SideBits::eRight
,
1060 eAll
= SideBits::eTopBottom
| SideBits::eLeftRight
1063 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SideBits
)
1065 inline constexpr SideBits
SideToSideBit(mozilla::Side aSide
) {
1066 return SideBits(1 << aSide
);
1069 enum Corner
: uint8_t {
1070 // This order is important!
1072 eCornerTopRight
= 1,
1073 eCornerBottomRight
= 2,
1074 eCornerBottomLeft
= 3
1077 // RectCornerRadii::radii depends on this value. It is not being added to
1078 // Corner because we want to lift the responsibility to handle it in the
1080 constexpr int eCornerCount
= 4;
1082 constexpr auto AllPhysicalCorners() {
1083 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeft
,
1087 // Indices into "half corner" arrays (nsStyleCorners e.g.)
1088 enum HalfCorner
: uint8_t {
1089 // This order is important!
1090 eCornerTopLeftX
= 0,
1091 eCornerTopLeftY
= 1,
1092 eCornerTopRightX
= 2,
1093 eCornerTopRightY
= 3,
1094 eCornerBottomRightX
= 4,
1095 eCornerBottomRightY
= 5,
1096 eCornerBottomLeftX
= 6,
1097 eCornerBottomLeftY
= 7
1100 constexpr auto AllPhysicalHalfCorners() {
1101 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeftX
,
1102 eCornerBottomLeftY
);
1105 // The result of these conversion functions are exhaustively checked in
1106 // nsFrame.cpp, which also serves as usage examples.
1108 constexpr bool HalfCornerIsX(HalfCorner aHalfCorner
) {
1109 return !(aHalfCorner
% 2);
1112 constexpr Corner
HalfToFullCorner(HalfCorner aHalfCorner
) {
1113 return Corner(aHalfCorner
/ 2);
1116 constexpr HalfCorner
FullToHalfCorner(Corner aCorner
, bool aIsVertical
) {
1117 return HalfCorner(aCorner
* 2 + aIsVertical
);
1120 constexpr bool SideIsVertical(mozilla::Side aSide
) { return aSide
% 2; }
1122 // @param aIsSecond when true, return the clockwise second of the two
1123 // corners associated with aSide. For example, with aSide = eSideBottom the
1124 // result is eCornerBottomRight when aIsSecond is false, and
1125 // eCornerBottomLeft when aIsSecond is true.
1126 constexpr Corner
SideToFullCorner(mozilla::Side aSide
, bool aIsSecond
) {
1127 return Corner((aSide
+ aIsSecond
) % 4);
1130 // @param aIsSecond see SideToFullCorner.
1131 // @param aIsParallel return the half-corner that is parallel with aSide
1132 // when aIsParallel is true. For example with aSide=eSideTop, aIsSecond=true
1133 // the result is eCornerTopRightX when aIsParallel is true, and
1134 // eCornerTopRightY when aIsParallel is false (because "X" is parallel with
1135 // eSideTop/eSideBottom, similarly "Y" is parallel with
1136 // eSideLeft/eSideRight)
1137 constexpr HalfCorner
SideToHalfCorner(mozilla::Side aSide
, bool aIsSecond
,
1139 return HalfCorner(((aSide
+ aIsSecond
) * 2 + (aSide
+ !aIsParallel
) % 2) % 8);
1142 } // namespace mozilla
1144 #endif /* MOZILLA_GFX_TYPES_H_ */