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
24 typedef double Double
;
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 */
44 DATA_ALIGNED
, /* Data surface using aligned heap memory */
47 enum class SurfaceFormat
: int8_t {
48 // The following values are named to reflect layout of colors in memory, from
49 // lowest byte to highest byte. The 32-bit value layout depends on machine
51 // in-memory 32-bit LE value 32-bit BE value
52 B8G8R8A8
, // [BB, GG, RR, AA] 0xAARRGGBB 0xBBGGRRAA
53 B8G8R8X8
, // [BB, GG, RR, 00] 0x00RRGGBB 0xBBGGRR00
54 R8G8B8A8
, // [RR, GG, BB, AA] 0xAABBGGRR 0xRRGGBBAA
55 R8G8B8X8
, // [RR, GG, BB, 00] 0x00BBGGRR 0xRRGGBB00
56 A8R8G8B8
, // [AA, RR, GG, BB] 0xBBGGRRAA 0xAARRGGBB
57 X8R8G8B8
, // [00, RR, GG, BB] 0xBBGGRR00 0x00RRGGBB
62 // The _UINT16 suffix here indicates that the name reflects the layout when
63 // viewed as a uint16_t value. In memory these values are stored using native
65 R5G6B5_UINT16
, // 0bRRRRRGGGGGGBBBBB
67 // This one is a single-byte, so endianness isn't an issue.
74 // These ones are their own special cases.
76 NV12
, // YUV 4:2:0 image with a plane of 8 bit Y samples followed by
77 // an interleaved U/V plane containing 8 bit 2x2 subsampled
78 // colour difference samples.
79 P016
, // Similar to NV12, but with 16 bits plane values
80 P010
, // Identical to P016 but the 6 least significant bits are 0.
81 // With DXGI in theory entirely compatible, however practice has
82 // shown that it's not the case.
83 YUV422
, // Single plane YUV 4:2:2 interleaved as Y`0 Cb Y`1 Cr.
88 // This represents the unknown format.
91 // The following values are endian-independent synonyms. The _UINT32 suffix
92 // indicates that the name reflects the layout when viewed as a uint32_t
94 #if MOZ_LITTLE_ENDIAN()
95 A8R8G8B8_UINT32
= B8G8R8A8
, // 0xAARRGGBB
96 X8R8G8B8_UINT32
= B8G8R8X8
, // 0x00RRGGBB
97 #elif MOZ_BIG_ENDIAN()
98 A8R8G8B8_UINT32
= A8R8G8B8
, // 0xAARRGGBB
99 X8R8G8B8_UINT32
= X8R8G8B8
, // 0x00RRGGBB
101 # error "bad endianness"
104 // The following values are OS and endian-independent synonyms.
106 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
107 // can make this use R8B8G8A8 and R8B8G8X8 for non-Windows platforms.
108 OS_RGBA
= A8R8G8B8_UINT32
,
109 OS_RGBX
= X8R8G8B8_UINT32
112 std::ostream
& operator<<(std::ostream
& aOut
, const SurfaceFormat
& aFormat
);
114 // Represents the bit-shifts required to access color channels when the layout
115 // is viewed as a uint32_t value.
116 enum class SurfaceFormatBit
: uint32_t {
117 #if MOZ_LITTLE_ENDIAN()
122 #elif MOZ_BIG_ENDIAN()
128 # error "bad endianness"
131 // The following values are endian-independent for A8R8G8B8_UINT32.
132 A8R8G8B8_UINT32_B
= 0,
133 A8R8G8B8_UINT32_G
= 8,
134 A8R8G8B8_UINT32_R
= 16,
135 A8R8G8B8_UINT32_A
= 24,
137 // The following values are OS and endian-independent.
139 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
140 // can make this use R8G8B8A8_X for non-Windows platforms.
141 OS_R
= A8R8G8B8_UINT32_R
,
142 OS_G
= A8R8G8B8_UINT32_G
,
143 OS_B
= A8R8G8B8_UINT32_B
,
144 OS_A
= A8R8G8B8_UINT32_A
,
147 inline uint32_t operator<<(uint8_t a
, SurfaceFormatBit b
) {
148 return a
<< static_cast<uint32_t>(b
);
151 inline uint32_t operator>>(uint32_t a
, SurfaceFormatBit b
) {
152 return a
>> static_cast<uint32_t>(b
);
155 static inline int BytesPerPixel(SurfaceFormat aFormat
) {
157 case SurfaceFormat::A8
:
159 case SurfaceFormat::R5G6B5_UINT16
:
160 case SurfaceFormat::A16
:
162 case SurfaceFormat::R8G8B8
:
163 case SurfaceFormat::B8G8R8
:
165 case SurfaceFormat::HSV
:
166 case SurfaceFormat::Lab
:
167 return 3 * sizeof(float);
168 case SurfaceFormat::Depth
:
169 return sizeof(uint16_t);
175 inline bool IsOpaque(SurfaceFormat aFormat
) {
177 case SurfaceFormat::B8G8R8X8
:
178 case SurfaceFormat::R8G8B8X8
:
179 case SurfaceFormat::X8R8G8B8
:
180 case SurfaceFormat::R5G6B5_UINT16
:
181 case SurfaceFormat::R8G8B8
:
182 case SurfaceFormat::B8G8R8
:
183 case SurfaceFormat::R8G8
:
184 case SurfaceFormat::HSV
:
185 case SurfaceFormat::Lab
:
186 case SurfaceFormat::Depth
:
187 case SurfaceFormat::YUV
:
188 case SurfaceFormat::NV12
:
189 case SurfaceFormat::P010
:
190 case SurfaceFormat::P016
:
191 case SurfaceFormat::YUV422
:
198 // The matrix coeffiecients used for YUV to RGB conversion.
199 enum class YUVColorSpace
: uint8_t {
204 // This represents the unknown format and is a valid value.
209 enum class ColorDepth
: uint8_t {
217 enum class ColorRange
: uint8_t { LIMITED
, FULL
, UNKNOWN
};
219 static inline SurfaceFormat
SurfaceFormatForColorDepth(ColorDepth aColorDepth
) {
220 SurfaceFormat format
= SurfaceFormat::A8
;
221 switch (aColorDepth
) {
222 case ColorDepth::COLOR_8
:
224 case ColorDepth::COLOR_10
:
225 case ColorDepth::COLOR_12
:
226 case ColorDepth::COLOR_16
:
227 format
= SurfaceFormat::A16
;
229 case ColorDepth::UNKNOWN
:
230 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
235 static inline uint32_t BitDepthForColorDepth(ColorDepth aColorDepth
) {
237 switch (aColorDepth
) {
238 case ColorDepth::COLOR_8
:
240 case ColorDepth::COLOR_10
:
243 case ColorDepth::COLOR_12
:
246 case ColorDepth::COLOR_16
:
249 case ColorDepth::UNKNOWN
:
250 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
255 static inline ColorDepth
ColorDepthForBitDepth(uint8_t aBitDepth
) {
256 ColorDepth depth
= ColorDepth::COLOR_8
;
261 depth
= ColorDepth::COLOR_10
;
264 depth
= ColorDepth::COLOR_12
;
267 depth
= ColorDepth::COLOR_16
;
270 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
275 // 10 and 12 bits color depth image are using 16 bits integers for storage
276 // As such we need to rescale the value from 10 or 12 bits to 16.
277 static inline uint32_t RescalingFactorForColorDepth(ColorDepth aColorDepth
) {
279 switch (aColorDepth
) {
280 case ColorDepth::COLOR_8
:
282 case ColorDepth::COLOR_10
:
285 case ColorDepth::COLOR_12
:
288 case ColorDepth::COLOR_16
:
290 case ColorDepth::UNKNOWN
:
291 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
296 enum class FilterType
: int8_t {
326 enum class DrawTargetType
: int8_t {
332 enum class BackendType
: int8_t {
334 DIRECT2D
, // Used for version independent D2D objects.
340 CAPTURE
, // Used for paths
342 // Add new entries above this line.
346 enum class FontType
: int8_t {
355 enum class NativeSurfaceType
: int8_t {
359 CGCONTEXT_ACCELERATED
,
363 enum class FontStyle
: int8_t { NORMAL
, ITALIC
, BOLD
, BOLD_ITALIC
};
365 enum class FontHinting
: int8_t { NONE
, LIGHT
, NORMAL
, FULL
};
367 enum class CompositionOp
: int8_t {
397 enum class Axis
: int8_t { X_AXIS
, Y_AXIS
, BOTH
};
399 enum class ExtendMode
: int8_t {
400 CLAMP
, // Do not repeat
401 REPEAT
, // Repeat in both axis
402 REPEAT_X
, // Only X axis
403 REPEAT_Y
, // Only Y axis
404 REFLECT
// Mirror the image
407 enum class FillRule
: int8_t { FILL_WINDING
, FILL_EVEN_ODD
};
409 enum class AntialiasMode
: int8_t { NONE
, GRAY
, SUBPIXEL
, DEFAULT
};
411 // See https://en.wikipedia.org/wiki/Texture_filtering
412 enum class SamplingFilter
: int8_t {
416 SENTINEL
// one past the last valid value
419 std::ostream
& operator<<(std::ostream
& aOut
, const SamplingFilter
& aFilter
);
422 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(PatternType
, int8_t, (
431 enum class JoinStyle
: int8_t {
434 MITER
, //!< Mitered if within the miter limit, else, if the backed supports
435 //!< it (D2D), the miter is clamped. If the backend does not support
436 //!< miter clamping the behavior is as for MITER_OR_BEVEL.
437 MITER_OR_BEVEL
//!< Mitered if within the miter limit, else beveled.
440 enum class CapStyle
: int8_t { BUTT
, ROUND
, SQUARE
};
442 enum class SamplingBounds
: int8_t { UNBOUNDED
, BOUNDED
};
444 // Moz2d version for SVG mask types
445 enum class LuminanceType
: int8_t {
450 /* Color is stored in non-premultiplied form in sRGB color space */
453 constexpr sRGBColor() : r(0.0f
), g(0.0f
), b(0.0f
), a(0.0f
) {}
454 constexpr sRGBColor(Float aR
, Float aG
, Float aB
, Float aA
)
455 : r(aR
), g(aG
), b(aB
), a(aA
) {}
456 constexpr sRGBColor(Float aR
, Float aG
, Float aB
)
457 : r(aR
), g(aG
), b(aB
), a(1.0f
) {}
459 static sRGBColor
White(float aA
) { return sRGBColor(1.f
, 1.f
, 1.f
, aA
); }
461 static sRGBColor
Black(float aA
) { return sRGBColor(0.f
, 0.f
, 0.f
, aA
); }
463 static sRGBColor
OpaqueWhite() { return White(1.f
); }
465 static sRGBColor
OpaqueBlack() { return Black(1.f
); }
467 static sRGBColor
FromU8(uint8_t aR
, uint8_t aG
, uint8_t aB
, uint8_t aA
) {
468 return sRGBColor(float(aR
) / 255.f
, float(aG
) / 255.f
, float(aB
) / 255.f
,
472 static sRGBColor
FromABGR(uint32_t aColor
) {
473 sRGBColor
newColor(((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
474 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
475 ((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
476 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
481 // The "Unusual" prefix is to avoid unintentionally using this function when
482 // FromABGR(), which is much more common, is needed.
483 static sRGBColor
UnusualFromARGB(uint32_t aColor
) {
484 sRGBColor
newColor(((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
485 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
486 ((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
487 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
492 uint32_t ToABGR() const {
493 return uint32_t(r
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
494 uint32_t(b
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
497 // The "Unusual" prefix is to avoid unintentionally using this function when
498 // ToABGR(), which is much more common, is needed.
499 uint32_t UnusualToARGB() const {
500 return uint32_t(b
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
501 uint32_t(r
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
504 bool operator==(const sRGBColor
& aColor
) const {
505 return r
== aColor
.r
&& g
== aColor
.g
&& b
== aColor
.b
&& a
== aColor
.a
;
508 bool operator!=(const sRGBColor
& aColor
) const { return !(*this == aColor
); }
513 /* Color is stored in non-premultiplied form in device color space */
516 DeviceColor() : r(0.0f
), g(0.0f
), b(0.0f
), a(0.0f
) {}
517 DeviceColor(Float aR
, Float aG
, Float aB
, Float aA
)
518 : r(aR
), g(aG
), b(aB
), a(aA
) {}
519 DeviceColor(Float aR
, Float aG
, Float aB
) : r(aR
), g(aG
), b(aB
), a(1.0f
) {}
521 /* The following Mask* variants are helpers used to make it clear when a
522 * particular color is being used for masking purposes. These masks should
523 * never be colored managed. */
524 static DeviceColor
Mask(float aC
, float aA
) {
525 return DeviceColor(aC
, aC
, aC
, aA
);
528 static DeviceColor
MaskWhite(float aA
) { return Mask(1.f
, aA
); }
530 static DeviceColor
MaskBlack(float aA
) { return Mask(0.f
, aA
); }
532 static DeviceColor
MaskOpaqueWhite() { return MaskWhite(1.f
); }
534 static DeviceColor
MaskOpaqueBlack() { return MaskBlack(1.f
); }
536 static DeviceColor
FromU8(uint8_t aR
, uint8_t aG
, uint8_t aB
, uint8_t aA
) {
537 return DeviceColor(float(aR
) / 255.f
, float(aG
) / 255.f
, float(aB
) / 255.f
,
541 static DeviceColor
FromABGR(uint32_t aColor
) {
542 DeviceColor
newColor(((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
543 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
544 ((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
545 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
550 // The "Unusual" prefix is to avoid unintentionally using this function when
551 // FromABGR(), which is much more common, is needed.
552 static DeviceColor
UnusualFromARGB(uint32_t aColor
) {
553 DeviceColor
newColor(((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
554 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
555 ((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
556 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
561 uint32_t ToABGR() const {
562 return uint32_t(r
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
563 uint32_t(b
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
566 // The "Unusual" prefix is to avoid unintentionally using this function when
567 // ToABGR(), which is much more common, is needed.
568 uint32_t UnusualToARGB() const {
569 return uint32_t(b
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
570 uint32_t(r
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
573 bool operator==(const DeviceColor
& aColor
) const {
574 return r
== aColor
.r
&& g
== aColor
.g
&& b
== aColor
.b
&& a
== aColor
.a
;
577 bool operator!=(const DeviceColor
& aColor
) const {
578 return !(*this == aColor
);
581 friend std::ostream
& operator<<(std::ostream
& aOut
,
582 const DeviceColor
& aColor
);
587 struct GradientStop
{
588 bool operator<(const GradientStop
& aOther
) const {
589 return offset
< aOther
.offset
;
596 enum class JobStatus
{ Complete
, Wait
, Yield
, Error
};
599 } // namespace mozilla
602 typedef mozilla::gfx::SurfaceFormat gfxImageFormat
;
604 #if defined(XP_WIN) && defined(MOZ_GFX)
605 # ifdef GFX2D_INTERNAL
606 # define GFX2D_API __declspec(dllexport)
608 # define GFX2D_API __declspec(dllimport)
616 // Side constants for use in various places.
617 enum Side
: uint8_t { eSideTop
, eSideRight
, eSideBottom
, eSideLeft
};
619 constexpr auto AllPhysicalSides() {
620 return mozilla::MakeInclusiveEnumeratedRange(eSideTop
, eSideLeft
);
623 enum class SideBits
{
625 eTop
= 1 << eSideTop
,
626 eRight
= 1 << eSideRight
,
627 eBottom
= 1 << eSideBottom
,
628 eLeft
= 1 << eSideLeft
,
629 eTopBottom
= SideBits::eTop
| SideBits::eBottom
,
630 eLeftRight
= SideBits::eLeft
| SideBits::eRight
,
631 eAll
= SideBits::eTopBottom
| SideBits::eLeftRight
634 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SideBits
)
636 enum Corner
: uint8_t {
637 // This order is important!
640 eCornerBottomRight
= 2,
641 eCornerBottomLeft
= 3
644 // RectCornerRadii::radii depends on this value. It is not being added to
645 // Corner because we want to lift the responsibility to handle it in the
647 constexpr int eCornerCount
= 4;
649 constexpr auto AllPhysicalCorners() {
650 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeft
,
654 // Indices into "half corner" arrays (nsStyleCorners e.g.)
655 enum HalfCorner
: uint8_t {
656 // This order is important!
659 eCornerTopRightX
= 2,
660 eCornerTopRightY
= 3,
661 eCornerBottomRightX
= 4,
662 eCornerBottomRightY
= 5,
663 eCornerBottomLeftX
= 6,
664 eCornerBottomLeftY
= 7
667 constexpr auto AllPhysicalHalfCorners() {
668 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeftX
,
672 // The result of these conversion functions are exhaustively checked in
673 // nsFrame.cpp, which also serves as usage examples.
675 constexpr bool HalfCornerIsX(HalfCorner aHalfCorner
) {
676 return !(aHalfCorner
% 2);
679 constexpr Corner
HalfToFullCorner(HalfCorner aHalfCorner
) {
680 return Corner(aHalfCorner
/ 2);
683 constexpr HalfCorner
FullToHalfCorner(Corner aCorner
, bool aIsVertical
) {
684 return HalfCorner(aCorner
* 2 + aIsVertical
);
687 constexpr bool SideIsVertical(mozilla::Side aSide
) { return aSide
% 2; }
689 // @param aIsSecond when true, return the clockwise second of the two
690 // corners associated with aSide. For example, with aSide = eSideBottom the
691 // result is eCornerBottomRight when aIsSecond is false, and
692 // eCornerBottomLeft when aIsSecond is true.
693 constexpr Corner
SideToFullCorner(mozilla::Side aSide
, bool aIsSecond
) {
694 return Corner((aSide
+ aIsSecond
) % 4);
697 // @param aIsSecond see SideToFullCorner.
698 // @param aIsParallel return the half-corner that is parallel with aSide
699 // when aIsParallel is true. For example with aSide=eSideTop, aIsSecond=true
700 // the result is eCornerTopRightX when aIsParallel is true, and
701 // eCornerTopRightY when aIsParallel is false (because "X" is parallel with
702 // eSideTop/eSideBottom, similarly "Y" is parallel with
703 // eSideLeft/eSideRight)
704 constexpr HalfCorner
SideToHalfCorner(mozilla::Side aSide
, bool aIsSecond
,
706 return HalfCorner(((aSide
+ aIsSecond
) * 2 + (aSide
+ !aIsParallel
) % 2) % 8);
709 } // namespace mozilla
711 #endif /* MOZILLA_GFX_TYPES_H_ */