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"
23 typedef double Double
;
25 enum class SurfaceType
: int8_t {
26 DATA
, /* Data surface - bitmap in memory */
27 D2D1_BITMAP
, /* Surface wrapping a ID2D1Bitmap */
28 D2D1_DRAWTARGET
, /* Surface made from a D2D draw target */
29 CAIRO
, /* Surface wrapping a cairo surface */
30 CAIRO_IMAGE
, /* Data surface wrapping a cairo image surface */
31 COREGRAPHICS_IMAGE
, /* Surface wrapping a CoreGraphics Image */
32 COREGRAPHICS_CGCONTEXT
, /* Surface wrapping a CG context */
33 SKIA
, /* Surface wrapping a Skia bitmap */
34 DUAL_DT
, /* Snapshot of a dual drawtarget */
35 D2D1_1_IMAGE
, /* A D2D 1.1 ID2D1Image SourceSurface */
36 RECORDING
, /* Surface used for recording */
37 WRAP_AND_RECORD
, /* Surface used for wrap and record */
38 TILED
, /* Surface from a tiled DrawTarget */
39 DATA_SHARED
, /* Data surface using shared memory */
40 CAPTURE
, /* Data from a DrawTargetCapture */
41 DATA_RECYCLING_SHARED
, /* Data surface using shared memory */
43 DATA_ALIGNED
, /* Data surface using aligned heap memory */
46 enum class SurfaceFormat
: int8_t {
47 // The following values are named to reflect layout of colors in memory, from
48 // lowest byte to highest byte. The 32-bit value layout depends on machine
50 // in-memory 32-bit LE value 32-bit BE value
51 B8G8R8A8
, // [BB, GG, RR, AA] 0xAARRGGBB 0xBBGGRRAA
52 B8G8R8X8
, // [BB, GG, RR, 00] 0x00RRGGBB 0xBBGGRR00
53 R8G8B8A8
, // [RR, GG, BB, AA] 0xAABBGGRR 0xRRGGBBAA
54 R8G8B8X8
, // [RR, GG, BB, 00] 0x00BBGGRR 0xRRGGBB00
55 A8R8G8B8
, // [AA, RR, GG, BB] 0xBBGGRRAA 0xAARRGGBB
56 X8R8G8B8
, // [00, RR, GG, BB] 0xBBGGRR00 0x00RRGGBB
61 // The _UINT16 suffix here indicates that the name reflects the layout when
62 // viewed as a uint16_t value. In memory these values are stored using native
64 R5G6B5_UINT16
, // 0bRRRRRGGGGGGBBBBB
66 // This one is a single-byte, so endianness isn't an issue.
73 // These ones are their own special cases.
75 NV12
, // YUV 4:2:0 image with a plane of 8 bit Y samples followed by
76 // an interleaved U/V plane containing 8 bit 2x2 subsampled
77 // colour difference samples.
78 P016
, // Similar to NV12, but with 16 bits plane values
79 P010
, // Identical to P016 but the 6 least significant bits are 0.
80 // With DXGI in theory entirely compatible, however practice has
81 // shown that it's not the case.
87 // This represents the unknown format.
90 // The following values are endian-independent synonyms. The _UINT32 suffix
91 // indicates that the name reflects the layout when viewed as a uint32_t
93 #if MOZ_LITTLE_ENDIAN()
94 A8R8G8B8_UINT32
= B8G8R8A8
, // 0xAARRGGBB
95 X8R8G8B8_UINT32
= B8G8R8X8
, // 0x00RRGGBB
96 #elif MOZ_BIG_ENDIAN()
97 A8R8G8B8_UINT32
= A8R8G8B8
, // 0xAARRGGBB
98 X8R8G8B8_UINT32
= X8R8G8B8
, // 0x00RRGGBB
100 # error "bad endianness"
103 // The following values are OS and endian-independent synonyms.
105 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
106 // can make this use R8B8G8A8 and R8B8G8X8 for non-Windows platforms.
107 OS_RGBA
= A8R8G8B8_UINT32
,
108 OS_RGBX
= X8R8G8B8_UINT32
111 // Represents the bit-shifts required to access color channels when the layout
112 // is viewed as a uint32_t value.
113 enum class SurfaceFormatBit
: uint32_t {
114 #if MOZ_LITTLE_ENDIAN()
119 #elif MOZ_BIG_ENDIAN()
125 # error "bad endianness"
128 // The following values are endian-independent for A8R8G8B8_UINT32.
129 A8R8G8B8_UINT32_B
= 0,
130 A8R8G8B8_UINT32_G
= 8,
131 A8R8G8B8_UINT32_R
= 16,
132 A8R8G8B8_UINT32_A
= 24,
134 // The following values are OS and endian-independent.
136 // TODO(aosmond): When everything blocking bug 1581828 has been resolved, we
137 // can make this use R8G8B8A8_X for non-Windows platforms.
138 OS_R
= A8R8G8B8_UINT32_R
,
139 OS_G
= A8R8G8B8_UINT32_G
,
140 OS_B
= A8R8G8B8_UINT32_B
,
141 OS_A
= A8R8G8B8_UINT32_A
,
144 inline uint32_t operator<<(uint8_t a
, SurfaceFormatBit b
) {
145 return a
<< static_cast<uint32_t>(b
);
148 inline uint32_t operator>>(uint32_t a
, SurfaceFormatBit b
) {
149 return a
>> static_cast<uint32_t>(b
);
152 static inline int BytesPerPixel(SurfaceFormat aFormat
) {
154 case SurfaceFormat::A8
:
156 case SurfaceFormat::R5G6B5_UINT16
:
157 case SurfaceFormat::A16
:
159 case SurfaceFormat::R8G8B8
:
160 case SurfaceFormat::B8G8R8
:
162 case SurfaceFormat::HSV
:
163 case SurfaceFormat::Lab
:
164 return 3 * sizeof(float);
165 case SurfaceFormat::Depth
:
166 return sizeof(uint16_t);
172 inline bool IsOpaque(SurfaceFormat aFormat
) {
174 case SurfaceFormat::B8G8R8X8
:
175 case SurfaceFormat::R8G8B8X8
:
176 case SurfaceFormat::X8R8G8B8
:
177 case SurfaceFormat::R5G6B5_UINT16
:
178 case SurfaceFormat::R8G8B8
:
179 case SurfaceFormat::B8G8R8
:
180 case SurfaceFormat::R8G8
:
181 case SurfaceFormat::HSV
:
182 case SurfaceFormat::Lab
:
183 case SurfaceFormat::Depth
:
184 case SurfaceFormat::YUV
:
185 case SurfaceFormat::NV12
:
186 case SurfaceFormat::P010
:
187 case SurfaceFormat::P016
:
188 case SurfaceFormat::YUV422
:
195 enum class YUVColorSpace
: uint8_t {
199 // This represents the unknown format and is a valid value.
204 enum class ColorDepth
: uint8_t {
212 enum class ColorRange
: uint8_t { LIMITED
, FULL
, UNKNOWN
};
214 static inline SurfaceFormat
SurfaceFormatForColorDepth(ColorDepth aColorDepth
) {
215 SurfaceFormat format
= SurfaceFormat::A8
;
216 switch (aColorDepth
) {
217 case ColorDepth::COLOR_8
:
219 case ColorDepth::COLOR_10
:
220 case ColorDepth::COLOR_12
:
221 case ColorDepth::COLOR_16
:
222 format
= SurfaceFormat::A16
;
224 case ColorDepth::UNKNOWN
:
225 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
230 static inline uint32_t BitDepthForColorDepth(ColorDepth aColorDepth
) {
232 switch (aColorDepth
) {
233 case ColorDepth::COLOR_8
:
235 case ColorDepth::COLOR_10
:
238 case ColorDepth::COLOR_12
:
241 case ColorDepth::COLOR_16
:
244 case ColorDepth::UNKNOWN
:
245 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
250 static inline ColorDepth
ColorDepthForBitDepth(uint8_t aBitDepth
) {
251 ColorDepth depth
= ColorDepth::COLOR_8
;
256 depth
= ColorDepth::COLOR_10
;
259 depth
= ColorDepth::COLOR_12
;
262 depth
= ColorDepth::COLOR_16
;
265 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
270 // 10 and 12 bits color depth image are using 16 bits integers for storage
271 // As such we need to rescale the value from 10 or 12 bits to 16.
272 static inline uint32_t RescalingFactorForColorDepth(ColorDepth aColorDepth
) {
274 switch (aColorDepth
) {
275 case ColorDepth::COLOR_8
:
277 case ColorDepth::COLOR_10
:
280 case ColorDepth::COLOR_12
:
283 case ColorDepth::COLOR_16
:
285 case ColorDepth::UNKNOWN
:
286 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
291 enum class FilterType
: int8_t {
321 enum class DrawTargetType
: int8_t {
327 enum class BackendType
: int8_t {
329 DIRECT2D
, // Used for version independent D2D objects.
335 CAPTURE
, // Used for paths
337 // Add new entries above this line.
341 enum class FontType
: int8_t {
350 enum class NativeSurfaceType
: int8_t {
354 CGCONTEXT_ACCELERATED
,
358 enum class FontStyle
: int8_t { NORMAL
, ITALIC
, BOLD
, BOLD_ITALIC
};
360 enum class FontHinting
: int8_t { NONE
, LIGHT
, NORMAL
, FULL
};
362 enum class CompositionOp
: int8_t {
392 enum class Axis
: int8_t { X_AXIS
, Y_AXIS
, BOTH
};
394 enum class ExtendMode
: int8_t {
395 CLAMP
, // Do not repeat
396 REPEAT
, // Repeat in both axis
397 REPEAT_X
, // Only X axis
398 REPEAT_Y
, // Only Y axis
399 REFLECT
// Mirror the image
402 enum class FillRule
: int8_t { FILL_WINDING
, FILL_EVEN_ODD
};
404 enum class AntialiasMode
: int8_t { NONE
, GRAY
, SUBPIXEL
, DEFAULT
};
406 // See https://en.wikipedia.org/wiki/Texture_filtering
407 enum class SamplingFilter
: int8_t {
411 SENTINEL
// one past the last valid value
415 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(PatternType
, int8_t, (
424 enum class JoinStyle
: int8_t {
427 MITER
, //!< Mitered if within the miter limit, else, if the backed supports
428 //!< it (D2D), the miter is clamped. If the backend does not support
429 //!< miter clamping the behavior is as for MITER_OR_BEVEL.
430 MITER_OR_BEVEL
//!< Mitered if within the miter limit, else beveled.
433 enum class CapStyle
: int8_t { BUTT
, ROUND
, SQUARE
};
435 enum class SamplingBounds
: int8_t { UNBOUNDED
, BOUNDED
};
437 // Moz2d version for SVG mask types
438 enum class LuminanceType
: int8_t {
443 /* Color is stored in non-premultiplied form in sRGB color space */
446 sRGBColor() : r(0.0f
), g(0.0f
), b(0.0f
), a(0.0f
) {}
447 sRGBColor(Float aR
, Float aG
, Float aB
, Float aA
)
448 : r(aR
), g(aG
), b(aB
), a(aA
) {}
449 sRGBColor(Float aR
, Float aG
, Float aB
) : r(aR
), g(aG
), b(aB
), a(1.0f
) {}
451 static sRGBColor
White(float aA
) { return sRGBColor(1.f
, 1.f
, 1.f
, aA
); }
453 static sRGBColor
Black(float aA
) { return sRGBColor(0.f
, 0.f
, 0.f
, aA
); }
455 static sRGBColor
OpaqueWhite() { return White(1.f
); }
457 static sRGBColor
OpaqueBlack() { return Black(1.f
); }
459 static sRGBColor
FromU8(uint8_t aR
, uint8_t aG
, uint8_t aB
, uint8_t aA
) {
460 return sRGBColor(float(aR
) / 255.f
, float(aG
) / 255.f
, float(aB
) / 255.f
,
464 static sRGBColor
FromABGR(uint32_t aColor
) {
465 sRGBColor
newColor(((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
466 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
467 ((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
468 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
473 // The "Unusual" prefix is to avoid unintentionally using this function when
474 // FromABGR(), which is much more common, is needed.
475 static sRGBColor
UnusualFromARGB(uint32_t aColor
) {
476 sRGBColor
newColor(((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
477 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
478 ((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
479 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
484 uint32_t ToABGR() const {
485 return uint32_t(r
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
486 uint32_t(b
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
489 // The "Unusual" prefix is to avoid unintentionally using this function when
490 // ToABGR(), which is much more common, is needed.
491 uint32_t UnusualToARGB() const {
492 return uint32_t(b
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
493 uint32_t(r
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
496 bool operator==(const sRGBColor
& aColor
) const {
497 return r
== aColor
.r
&& g
== aColor
.g
&& b
== aColor
.b
&& a
== aColor
.a
;
500 bool operator!=(const sRGBColor
& aColor
) const { return !(*this == aColor
); }
505 /* Color is stored in non-premultiplied form in device color space */
508 DeviceColor() : r(0.0f
), g(0.0f
), b(0.0f
), a(0.0f
) {}
509 DeviceColor(Float aR
, Float aG
, Float aB
, Float aA
)
510 : r(aR
), g(aG
), b(aB
), a(aA
) {}
511 DeviceColor(Float aR
, Float aG
, Float aB
) : r(aR
), g(aG
), b(aB
), a(1.0f
) {}
513 /* The following Mask* variants are helpers used to make it clear when a
514 * particular color is being used for masking purposes. These masks should
515 * never be colored managed. */
516 static DeviceColor
Mask(float aC
, float aA
) {
517 return DeviceColor(aC
, aC
, aC
, aA
);
520 static DeviceColor
MaskWhite(float aA
) { return Mask(1.f
, aA
); }
522 static DeviceColor
MaskBlack(float aA
) { return Mask(0.f
, aA
); }
524 static DeviceColor
MaskOpaqueWhite() { return MaskWhite(1.f
); }
526 static DeviceColor
MaskOpaqueBlack() { return MaskBlack(1.f
); }
528 static DeviceColor
FromU8(uint8_t aR
, uint8_t aG
, uint8_t aB
, uint8_t aA
) {
529 return DeviceColor(float(aR
) / 255.f
, float(aG
) / 255.f
, float(aB
) / 255.f
,
533 static DeviceColor
FromABGR(uint32_t aColor
) {
534 DeviceColor
newColor(((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
535 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
536 ((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
537 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
542 // The "Unusual" prefix is to avoid unintentionally using this function when
543 // FromABGR(), which is much more common, is needed.
544 static DeviceColor
UnusualFromARGB(uint32_t aColor
) {
545 DeviceColor
newColor(((aColor
>> 16) & 0xff) * (1.0f
/ 255.0f
),
546 ((aColor
>> 8) & 0xff) * (1.0f
/ 255.0f
),
547 ((aColor
>> 0) & 0xff) * (1.0f
/ 255.0f
),
548 ((aColor
>> 24) & 0xff) * (1.0f
/ 255.0f
));
553 uint32_t ToABGR() const {
554 return uint32_t(r
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
555 uint32_t(b
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
558 // The "Unusual" prefix is to avoid unintentionally using this function when
559 // ToABGR(), which is much more common, is needed.
560 uint32_t UnusualToARGB() const {
561 return uint32_t(b
* 255.0f
) | uint32_t(g
* 255.0f
) << 8 |
562 uint32_t(r
* 255.0f
) << 16 | uint32_t(a
* 255.0f
) << 24;
565 bool operator==(const DeviceColor
& aColor
) const {
566 return r
== aColor
.r
&& g
== aColor
.g
&& b
== aColor
.b
&& a
== aColor
.a
;
569 bool operator!=(const DeviceColor
& aColor
) const {
570 return !(*this == aColor
);
576 struct GradientStop
{
577 bool operator<(const GradientStop
& aOther
) const {
578 return offset
< aOther
.offset
;
585 enum class JobStatus
{ Complete
, Wait
, Yield
, Error
};
588 } // namespace mozilla
591 typedef mozilla::gfx::SurfaceFormat gfxImageFormat
;
593 #if defined(XP_WIN) && defined(MOZ_GFX)
594 # ifdef GFX2D_INTERNAL
595 # define GFX2D_API __declspec(dllexport)
597 # define GFX2D_API __declspec(dllimport)
605 // Side constants for use in various places.
606 enum Side
: uint8_t { eSideTop
, eSideRight
, eSideBottom
, eSideLeft
};
608 constexpr auto AllPhysicalSides() {
609 return mozilla::MakeInclusiveEnumeratedRange(eSideTop
, eSideLeft
);
612 enum class SideBits
{
614 eTop
= 1 << eSideTop
,
615 eRight
= 1 << eSideRight
,
616 eBottom
= 1 << eSideBottom
,
617 eLeft
= 1 << eSideLeft
,
618 eTopBottom
= SideBits::eTop
| SideBits::eBottom
,
619 eLeftRight
= SideBits::eLeft
| SideBits::eRight
,
620 eAll
= SideBits::eTopBottom
| SideBits::eLeftRight
623 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SideBits
)
625 enum Corner
: uint8_t {
626 // This order is important!
629 eCornerBottomRight
= 2,
630 eCornerBottomLeft
= 3
633 // RectCornerRadii::radii depends on this value. It is not being added to
634 // Corner because we want to lift the responsibility to handle it in the
636 constexpr int eCornerCount
= 4;
638 constexpr auto AllPhysicalCorners() {
639 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeft
,
643 // Indices into "half corner" arrays (nsStyleCorners e.g.)
644 enum HalfCorner
: uint8_t {
645 // This order is important!
648 eCornerTopRightX
= 2,
649 eCornerTopRightY
= 3,
650 eCornerBottomRightX
= 4,
651 eCornerBottomRightY
= 5,
652 eCornerBottomLeftX
= 6,
653 eCornerBottomLeftY
= 7
656 constexpr auto AllPhysicalHalfCorners() {
657 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeftX
,
661 // The result of these conversion functions are exhaustively checked in
662 // nsFrame.cpp, which also serves as usage examples.
664 constexpr bool HalfCornerIsX(HalfCorner aHalfCorner
) {
665 return !(aHalfCorner
% 2);
668 constexpr Corner
HalfToFullCorner(HalfCorner aHalfCorner
) {
669 return Corner(aHalfCorner
/ 2);
672 constexpr HalfCorner
FullToHalfCorner(Corner aCorner
, bool aIsVertical
) {
673 return HalfCorner(aCorner
* 2 + aIsVertical
);
676 constexpr bool SideIsVertical(Side aSide
) { return aSide
% 2; }
678 // @param aIsSecond when true, return the clockwise second of the two
679 // corners associated with aSide. For example, with aSide = eSideBottom the
680 // result is eCornerBottomRight when aIsSecond is false, and
681 // eCornerBottomLeft when aIsSecond is true.
682 constexpr Corner
SideToFullCorner(Side aSide
, bool aIsSecond
) {
683 return Corner((aSide
+ aIsSecond
) % 4);
686 // @param aIsSecond see SideToFullCorner.
687 // @param aIsParallel return the half-corner that is parallel with aSide
688 // when aIsParallel is true. For example with aSide=eSideTop, aIsSecond=true
689 // the result is eCornerTopRightX when aIsParallel is true, and
690 // eCornerTopRightY when aIsParallel is false (because "X" is parallel with
691 // eSideTop/eSideBottom, similarly "Y" is parallel with
692 // eSideLeft/eSideRight)
693 constexpr HalfCorner
SideToHalfCorner(Side aSide
, bool aIsSecond
,
695 return HalfCorner(((aSide
+ aIsSecond
) * 2 + (aSide
+ !aIsParallel
) % 2) % 8);
698 } // namespace mozilla
700 #endif /* MOZILLA_GFX_TYPES_H_ */