Bug 1641886 [wpt PR 23851] - Support interpolating contain-intrinsic-size, a=testonly
[gecko.git] / gfx / 2d / Types.h
blob9514dde460649ace25a91e220d6e0c26e0f76c18
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 <stddef.h>
17 #include <stdint.h>
19 namespace mozilla {
20 namespace gfx {
22 typedef float Float;
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 */
42 OFFSET, /* Offset */
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
49 // endianness.
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
58 R8G8B8,
59 B8G8R8,
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
63 // endianness.
64 R5G6B5_UINT16, // 0bRRRRRGGGGGGBBBBB
66 // This one is a single-byte, so endianness isn't an issue.
67 A8,
68 A16,
70 R8G8,
71 R16G16,
73 // These ones are their own special cases.
74 YUV,
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.
82 YUV422,
83 HSV,
84 Lab,
85 Depth,
87 // This represents the unknown format.
88 UNKNOWN,
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
92 // value.
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
99 #else
100 # error "bad endianness"
101 #endif
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()
115 R8G8B8A8_R = 0,
116 R8G8B8A8_G = 8,
117 R8G8B8A8_B = 16,
118 R8G8B8A8_A = 24,
119 #elif MOZ_BIG_ENDIAN()
120 R8G8B8A8_A = 0,
121 R8G8B8A8_B = 8,
122 R8G8B8A8_G = 16,
123 R8G8B8A8_R = 24,
124 #else
125 # error "bad endianness"
126 #endif
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) {
153 switch (aFormat) {
154 case SurfaceFormat::A8:
155 return 1;
156 case SurfaceFormat::R5G6B5_UINT16:
157 case SurfaceFormat::A16:
158 return 2;
159 case SurfaceFormat::R8G8B8:
160 case SurfaceFormat::B8G8R8:
161 return 3;
162 case SurfaceFormat::HSV:
163 case SurfaceFormat::Lab:
164 return 3 * sizeof(float);
165 case SurfaceFormat::Depth:
166 return sizeof(uint16_t);
167 default:
168 return 4;
172 inline bool IsOpaque(SurfaceFormat aFormat) {
173 switch (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:
189 return true;
190 default:
191 return false;
195 enum class YUVColorSpace : uint8_t {
196 BT601,
197 BT709,
198 BT2020,
199 // This represents the unknown format and is a valid value.
200 UNKNOWN,
201 _NUM_COLORSPACE
204 enum class ColorDepth : uint8_t {
205 COLOR_8,
206 COLOR_10,
207 COLOR_12,
208 COLOR_16,
209 UNKNOWN
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:
218 break;
219 case ColorDepth::COLOR_10:
220 case ColorDepth::COLOR_12:
221 case ColorDepth::COLOR_16:
222 format = SurfaceFormat::A16;
223 break;
224 case ColorDepth::UNKNOWN:
225 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
227 return format;
230 static inline uint32_t BitDepthForColorDepth(ColorDepth aColorDepth) {
231 uint32_t depth = 8;
232 switch (aColorDepth) {
233 case ColorDepth::COLOR_8:
234 break;
235 case ColorDepth::COLOR_10:
236 depth = 10;
237 break;
238 case ColorDepth::COLOR_12:
239 depth = 12;
240 break;
241 case ColorDepth::COLOR_16:
242 depth = 16;
243 break;
244 case ColorDepth::UNKNOWN:
245 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
247 return depth;
250 static inline ColorDepth ColorDepthForBitDepth(uint8_t aBitDepth) {
251 ColorDepth depth = ColorDepth::COLOR_8;
252 switch (aBitDepth) {
253 case 8:
254 break;
255 case 10:
256 depth = ColorDepth::COLOR_10;
257 break;
258 case 12:
259 depth = ColorDepth::COLOR_12;
260 break;
261 case 16:
262 depth = ColorDepth::COLOR_16;
263 break;
264 default:
265 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
267 return depth;
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) {
273 uint32_t factor = 1;
274 switch (aColorDepth) {
275 case ColorDepth::COLOR_8:
276 break;
277 case ColorDepth::COLOR_10:
278 factor = 64;
279 break;
280 case ColorDepth::COLOR_12:
281 factor = 16;
282 break;
283 case ColorDepth::COLOR_16:
284 break;
285 case ColorDepth::UNKNOWN:
286 MOZ_ASSERT_UNREACHABLE("invalid color depth value");
288 return factor;
291 enum class FilterType : int8_t {
292 BLEND = 0,
293 TRANSFORM,
294 MORPHOLOGY,
295 COLOR_MATRIX,
296 FLOOD,
297 TILE,
298 TABLE_TRANSFER,
299 DISCRETE_TRANSFER,
300 LINEAR_TRANSFER,
301 GAMMA_TRANSFER,
302 CONVOLVE_MATRIX,
303 DISPLACEMENT_MAP,
304 TURBULENCE,
305 ARITHMETIC_COMBINE,
306 COMPOSITE,
307 DIRECTIONAL_BLUR,
308 GAUSSIAN_BLUR,
309 POINT_DIFFUSE,
310 POINT_SPECULAR,
311 SPOT_DIFFUSE,
312 SPOT_SPECULAR,
313 DISTANT_DIFFUSE,
314 DISTANT_SPECULAR,
315 CROP,
316 PREMULTIPLY,
317 UNPREMULTIPLY,
318 OPACITY
321 enum class DrawTargetType : int8_t {
322 SOFTWARE_RASTER = 0,
323 HARDWARE_RASTER,
324 VECTOR
327 enum class BackendType : int8_t {
328 NONE = 0,
329 DIRECT2D, // Used for version independent D2D objects.
330 CAIRO,
331 SKIA,
332 RECORDING,
333 DIRECT2D1_1,
334 WEBRENDER_TEXT,
335 CAPTURE, // Used for paths
337 // Add new entries above this line.
338 BACKEND_LAST
341 enum class FontType : int8_t {
342 DWRITE,
343 GDI,
344 MAC,
345 FONTCONFIG,
346 FREETYPE,
347 UNKNOWN
350 enum class NativeSurfaceType : int8_t {
351 D3D10_TEXTURE,
352 CAIRO_CONTEXT,
353 CGCONTEXT,
354 CGCONTEXT_ACCELERATED,
355 OPENGL_TEXTURE
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 {
363 OP_OVER,
364 OP_ADD,
365 OP_ATOP,
366 OP_OUT,
367 OP_IN,
368 OP_SOURCE,
369 OP_DEST_IN,
370 OP_DEST_OUT,
371 OP_DEST_OVER,
372 OP_DEST_ATOP,
373 OP_XOR,
374 OP_MULTIPLY,
375 OP_SCREEN,
376 OP_OVERLAY,
377 OP_DARKEN,
378 OP_LIGHTEN,
379 OP_COLOR_DODGE,
380 OP_COLOR_BURN,
381 OP_HARD_LIGHT,
382 OP_SOFT_LIGHT,
383 OP_DIFFERENCE,
384 OP_EXCLUSION,
385 OP_HUE,
386 OP_SATURATION,
387 OP_COLOR,
388 OP_LUMINOSITY,
389 OP_COUNT
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 {
408 GOOD,
409 LINEAR,
410 POINT,
411 SENTINEL // one past the last valid value
414 // clang-format off
415 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(PatternType, int8_t, (
416 COLOR,
417 SURFACE,
418 LINEAR_GRADIENT,
419 RADIAL_GRADIENT,
420 CONIC_GRADIENT
422 // clang-format on
424 enum class JoinStyle : int8_t {
425 BEVEL,
426 ROUND,
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 {
439 LUMINANCE,
440 LINEARRGB,
443 /* Color is stored in non-premultiplied form in sRGB color space */
444 struct sRGBColor {
445 public:
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,
461 float(aA) / 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));
470 return newColor;
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));
481 return newColor;
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); }
502 Float r, g, b, a;
505 /* Color is stored in non-premultiplied form in device color space */
506 struct DeviceColor {
507 public:
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,
530 float(aA) / 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));
539 return newColor;
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));
550 return newColor;
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);
573 Float r, g, b, a;
576 struct GradientStop {
577 bool operator<(const GradientStop& aOther) const {
578 return offset < aOther.offset;
581 Float offset;
582 DeviceColor color;
585 enum class JobStatus { Complete, Wait, Yield, Error };
587 } // namespace gfx
588 } // namespace mozilla
590 // XXX: temporary
591 typedef mozilla::gfx::SurfaceFormat gfxImageFormat;
593 #if defined(XP_WIN) && defined(MOZ_GFX)
594 # ifdef GFX2D_INTERNAL
595 # define GFX2D_API __declspec(dllexport)
596 # else
597 # define GFX2D_API __declspec(dllimport)
598 # endif
599 #else
600 # define GFX2D_API
601 #endif
603 namespace mozilla {
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 {
613 eNone = 0,
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!
627 eCornerTopLeft = 0,
628 eCornerTopRight = 1,
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
635 // switch-case.
636 constexpr int eCornerCount = 4;
638 constexpr auto AllPhysicalCorners() {
639 return mozilla::MakeInclusiveEnumeratedRange(eCornerTopLeft,
640 eCornerBottomLeft);
643 // Indices into "half corner" arrays (nsStyleCorners e.g.)
644 enum HalfCorner : uint8_t {
645 // This order is important!
646 eCornerTopLeftX = 0,
647 eCornerTopLeftY = 1,
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,
658 eCornerBottomLeftY);
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,
694 bool aIsParallel) {
695 return HalfCorner(((aSide + aIsSecond) * 2 + (aSide + !aIsParallel) % 2) % 8);
698 } // namespace mozilla
700 #endif /* MOZILLA_GFX_TYPES_H_ */