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