Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
// See the comment in ServoBindings.h about the same.
#pragma GCC diagnostic push
#ifdef __clang__
# pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
#endif
#ifndef mozilla_ServoStyleConsts_h
#define mozilla_ServoStyleConsts_h
/* Generated with cbindgen:0.28.0 */
/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen. See RunCbindgen.py
* To modify this file, edit servo/ports/geckolib/cbindgen.toml and build Firefox.
*/
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
#include "mozilla/ServoStyleConstsForwards.h"
#include "mozilla/ServoStyleSet.h"
// Work-around silly windows.h define.
#pragma push_macro("STRICT")
#undef STRICT
#pragma push_macro("TRANSPARENT")
#undef TRANSPARENT
namespace mozilla {
#if defined(CBINDGEN_IS_GECKO)
/// The minimum stack size for a thread in the styling pool, in kilobytes.
constexpr static const uintptr_t StyleSTYLE_THREAD_STACK_SIZE_KB = 256;
#endif
#if defined(CBINDGEN_IS_SERVO)
/// The minimum stack size for a thread in the styling pool, in kilobytes.
/// Servo requires a bigger stack in debug builds.
constexpr static const uintptr_t StyleSTYLE_THREAD_STACK_SIZE_KB = 512;
#endif
/// The stack margin. If we get this deep in the stack, we will skip recursive
/// optimizations to ensure that there is sufficient room for non-recursive work.
///
/// We allocate large safety margins because certain OS calls can use very large
/// amounts of stack space [1]. Reserving a larger-than-necessary stack costs us
/// address space, but if we keep our safety margin big, we will generally avoid
/// committing those extra pages, and only use them in edge cases that would
/// otherwise cause crashes.
///
/// When measured with 128KB stacks and 40KB margin, we could support 53
/// levels of recursion before the limiter kicks in, on x86_64-Linux [2]. When
/// we doubled the stack size, we added it all to the safety margin, so we should
/// be able to get the same amount of recursion.
///
constexpr static const uintptr_t StyleSTACK_SAFETY_MARGIN_KB = 168;
/// The amount of nodes that the style sharing candidate cache should hold at
/// most.
///
/// The cache size was chosen by measuring style sharing and resulting
/// performance on a few pages; sizes up to about 32 were giving good sharing
/// improvements (e.g. 3x fewer styles having to be resolved than at size 8) and
/// slight performance improvements. Sizes larger than 32 haven't really been
/// tested.
constexpr static const uintptr_t StyleSHARING_CACHE_SIZE = 32;
/// We use an unsigned 10.6 fixed-point value (range 0.0 - 1023.984375).
constexpr static const uint16_t StyleZOOM_FRACTION_BITS = 6;
/// font-weight: range 1..1000, fractional values permitted; keywords
/// 'normal', 'bold' aliased to 400, 700 respectively.
///
/// We use an unsigned 10.6 fixed-point value (range 0.0 - 1023.984375)
constexpr static const uint16_t StyleFONT_WEIGHT_FRACTION_BITS = 6;
/// - Use a signed 8.8 fixed-point value (representable range -128.0..128)
///
/// Values of <angle> below -90 or above 90 are not permitted, so we use an out
/// of range value to represent `italic`.
constexpr static const uint16_t StyleFONT_STYLE_FRACTION_BITS = 8;
/// font-stretch is a percentage relative to normal.
///
/// We use an unsigned 10.6 fixed-point value (range 0.0 - 1023.984375)
///
/// We arbitrarily limit here to 1000%. (If that becomes a problem, we could
/// reduce the number of fractional bits and increase the limit.)
constexpr static const uint16_t StyleFONT_STRETCH_FRACTION_BITS = 6;
constexpr static const uint8_t StyleLengthPercentageUnion_TAG_CALC = 0;
constexpr static const uint8_t StyleLengthPercentageUnion_TAG_LENGTH = 1;
constexpr static const uint8_t StyleLengthPercentageUnion_TAG_PERCENTAGE = 2;
constexpr static const uint8_t StyleLengthPercentageUnion_TAG_MASK = 3;
/// These are the limits that we choose to clamp grid line numbers to.
/// line_num is clamped to this range at parse time.
constexpr static const int32_t StyleMIN_GRID_LINE = -10000;
/// See above.
constexpr static const int32_t StyleMAX_GRID_LINE = 10000;
/// The minimum font-weight value per:
///
constexpr static const float StyleMIN_FONT_WEIGHT = 1.;
/// The maximum font-weight value per:
///
constexpr static const float StyleMAX_FONT_WEIGHT = 1000.;
///
/// Values less than -90deg or values greater than 90deg are
/// invalid and are treated as parse errors.
///
/// The maximum angle value that `font-style: oblique` should compute to.
constexpr static const float StyleFONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES = 90.;
/// The minimum angle value that `font-style: oblique` should compute to.
constexpr static const float StyleFONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES = -90.;
/// The default font size.
constexpr static const float StyleFONT_MEDIUM_PX = 16.0;
/// The default line height.
constexpr static const float StyleFONT_MEDIUM_LINE_HEIGHT_PX = (StyleFONT_MEDIUM_PX * 1.2);
/// Number of non-normal components
constexpr static const uint8_t StylePAINT_ORDER_COUNT = 3;
/// Number of bits for each component
constexpr static const uint8_t StylePAINT_ORDER_SHIFT = 2;
/// Mask with above bits set
constexpr static const uint8_t StylePAINT_ORDER_MASK = 3;
#if defined(CBINDGEN_IS_SERVO)
/// The number of eager pseudo-elements. Keep this in sync with cascade_type.
constexpr static const uintptr_t StyleEAGER_PSEUDO_COUNT = 3;
#endif
/// Whether @import rules are allowed.
enum class StyleAllowImportRules : uint8_t {
/// @import rules will be parsed.
Yes,
/// @import rules will not be parsed.
No,
};
/// Whether to allow negative lengths or not.
enum class StyleAllowedNumericType : uint8_t {
/// Allow all kind of numeric values.
All,
/// Allow only non-negative numeric values.
NonNegative,
/// Allow only numeric values greater or equal to 1.0.
AtLeastOne,
/// Allow only numeric values from 0 to 1.0.
ZeroToOne,
};
/// Keyword values for the anchor positioning function.
enum class StyleAnchorSideKeyword : uint8_t {
/// Inside relative (i.e. Same side) to the inset property it's used in.
Inside,
/// Same as above, but outside (i.e. Opposite side).
Outside,
/// Top of the anchor element.
Top,
/// Left of the anchor element.
Left,
/// Right of the anchor element.
Right,
/// Bottom of the anchor element.
Bottom,
/// Refers to the start side of the anchor element for the same axis of the inset
/// property it's used in, resolved against the positioned element's containing
/// block's writing mode.
Start,
/// Same as above, but for the end side.
End,
/// Same as `start`, resolved against the positioned element's writing mode.
SelfStart,
/// Same as above, but for the end side.
SelfEnd,
/// Halfway between `start` and `end` sides.
Center,
};
/// Keyword values for the anchor size function.
enum class StyleAnchorSizeKeyword : uint8_t {
/// Magic value for nothing.
None,
/// Width of the anchor element.
Width,
/// Height of the anchor element.
Height,
/// Block size of the anchor element.
Block,
/// Inline size of the anchor element.
Inline,
/// Same as `Block`, resolved against the positioned element's writing mode.
SelfBlock,
/// Same as `Inline`, resolved against the positioned element's writing mode.
SelfInline,
};
enum class StyleAnimationComposition : uint8_t {
Replace,
Add,
Accumulate,
};
enum class StyleAnimationDirection : uint8_t {
Normal,
Reverse,
Alternate,
AlternateReverse,
};
enum class StyleAnimationFillMode : uint8_t {
None,
Forwards,
Backwards,
Both,
};
enum class StyleAnimationPlayState : uint8_t {
Running,
Paused,
};
/// The value for the `appearance` property.
///
enum class StyleAppearance : uint8_t {
/// No appearance at all.
None,
/// Default appearance for the element.
///
/// This value doesn't make sense for -moz-default-appearance, but we don't bother to guard
/// against parsing it.
Auto,
/// A searchfield.
Searchfield,
/// A multi-line text field, e.g. HTML <textarea>.
Textarea,
/// A checkbox element.
Checkbox,
/// A radio element within a radio group.
Radio,
/// A dropdown list.
Menulist,
/// List boxes.
Listbox,
/// A horizontal meter bar.
Meter,
/// A horizontal progress bar.
ProgressBar,
/// A typical dialog button.
Button,
/// A single-line text field, e.g. HTML <input type=text>.
Textfield,
/// The dropdown button(s) that open up a dropdown list.
MenulistButton,
/// Various arrows that go in buttons
ButtonArrowDown,
ButtonArrowNext,
ButtonArrowPrevious,
ButtonArrowUp,
/// A dual toolbar button (e.g., a Back button with a dropdown)
Dualbutton,
/// Menu Popup background.
Menupopup,
/// The meter bar's meter indicator.
Meterchunk,
/// The "arrowed" part of the dropdown button that open up a dropdown list.
MozMenulistArrowButton,
/// For HTML's <input type=number>
NumberInput,
/// For HTML's <input type=password>
PasswordInput,
/// The progress bar's progress indicator
Progresschunk,
/// nsRangeFrame and its subparts
Range,
RangeThumb,
/// The scrollbar slider
ScrollbarHorizontal,
ScrollbarVertical,
/// A scrollbar button (up/down/left/right).
/// Keep these in order (some code casts these values to `int` in order to
/// compare them against each other).
ScrollbarbuttonUp,
ScrollbarbuttonDown,
ScrollbarbuttonLeft,
ScrollbarbuttonRight,
/// The scrollbar thumb.
ScrollbarthumbHorizontal,
ScrollbarthumbVertical,
/// The scroll corner
Scrollcorner,
/// A separator. Can be horizontal or vertical.
Separator,
/// The up button of a spin control.
SpinnerUpbutton,
/// The down button of a spin control.
SpinnerDownbutton,
/// A splitter. Can be horizontal or vertical.
Splitter,
/// A status bar in a main application window.
Statusbar,
/// A single tab in a tab widget.
Tab,
/// A single pane (inside the tabpanels container).
Tabpanel,
/// The tab panels container.
Tabpanels,
/// A single toolbar button (with no associated dropdown).
Toolbarbutton,
/// The dropdown portion of a toolbar button
ToolbarbuttonDropdown,
/// A tooltip.
Tooltip,
/// Sidebar appearance.
MozSidebar,
/// Mac help button.
MozMacHelpButton,
/// An appearance value for the root, so that we can get tinting and unified toolbar looks
/// (which require a transparent gecko background) without really using the whole transparency
MozMacWindow,
/// Windows themed window frame elements.
MozWindowButtonBox,
MozWindowButtonClose,
MozWindowButtonMaximize,
MozWindowButtonMinimize,
MozWindowButtonRestore,
MozWindowTitlebar,
MozWindowTitlebarMaximized,
MozWindowDecorations,
MozMacDisclosureButtonClosed,
MozMacDisclosureButtonOpen,
/// A themed focus outline (for outline:auto).
///
/// This isn't exposed to CSS at all, just here for convenience.
FocusOutline,
/// A dummy variant that should be last to let the GTK widget do hackery.
Count,
};
/// This indicates that the larger or smaller, respectively, of the two possible arcs must be
/// chosen.
enum class StyleArcSize : uint8_t {
/// Choose the small one. The default value. (This also represents 0 in the svg path.)
Small = 0,
/// Choose the large one. (This also represents 1 in the svg path.)
Large = 1,
};
/// This indicates that the arc that is traced around the ellipse clockwise or counter-clockwise
/// from the center.
enum class StyleArcSweep : uint8_t {
/// Counter-clockwise. The default value. (This also represents 0 in the svg path.)
Ccw = 0,
/// Clockwise. (This also represents 1 in the svg path.)
Cw = 1,
};
/// A specified value for the `baseline-source` property.
enum class StyleBaselineSource : uint8_t {
/// `Last` for `inline-block`, `First` otherwise.
Auto,
/// Use first baseline for alignment.
First,
/// Use last baseline for alignment.
Last,
};
/// This flag is never user-specified.
enum class StyleEasingBeforeFlag : uint8_t {
Unset,
Set,
};
/// A boolean value for a pref query.
enum class StyleBoolValue : uint8_t {
False,
True,
};
/// A single border-image-repeat keyword.
enum class StyleBorderImageRepeatKeyword : uint8_t {
Stretch,
Repeat,
Round,
Space,
};
/// A specified value for a single side of a `border-style` property.
///
/// The order here corresponds to the integer values from the border conflict
/// resolution rules in CSS 2.1 § 17.6.2.1. Higher values override lower values.
enum class StyleBorderStyle : uint8_t {
Hidden,
None,
Inset,
Groove,
Outset,
Ridge,
Dotted,
Dashed,
Solid,
Double,
};
/// A kind of break between two boxes.
///
enum class StyleBreakBetween : uint8_t {
Always,
Auto,
Page,
Avoid,
Left,
Right,
};
/// A kind of break within a box.
///
enum class StyleBreakWithin : uint8_t {
Auto,
Avoid,
AvoidPage,
AvoidColumn,
};
/// This indicates the command is absolute or relative.
enum class StyleByTo : uint8_t {
/// This indicates that the <coordinate-pair>s are relative to the command’s starting point.
By,
/// This relative to the top-left corner of the reference box.
To,
};
/// Specified values for the `caption-side` property.
///
/// Note that despite having "physical" names, these are actually interpreted
/// according to the table's writing-mode: Top and Bottom are treated as
/// block-start and -end respectively.
///
enum class StyleCaptionSide : uint8_t {
Top,
Bottom,
};
/// Represents a channel keyword inside a color.
enum class StyleChannelKeyword : uint8_t {
/// alpha
Alpha,
/// a
A,
/// b, blackness, blue
B,
/// chroma
C,
/// green
G,
/// hue
H,
/// lightness
L,
/// red
R,
/// saturation
S,
/// whiteness
W,
/// x
X,
/// y
Y,
/// z
Z,
};
enum class StyleClear : uint8_t {
None,
Left,
Right,
Both,
InlineStart,
InlineEnd,
};
#if defined(CBINDGEN_IS_GECKO)
/// Values for the color-gamut media feature.
/// This implements PartialOrd so that lower values will correctly match
/// higher capabilities.
enum class StyleColorGamut : uint8_t {
#if defined(CBINDGEN_IS_GECKO)
/// The sRGB gamut.
Srgb,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// The gamut specified by the Display P3 Color Space.
P3,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// The gamut specified by the ITU-R Recommendation BT.2020 Color Space.
Rec2020,
#endif
};
#endif
/// A color space representation in the CSS specification.
///
enum class StyleColorSpace : uint8_t {
/// A color specified in the sRGB color space with either the rgb/rgba(..)
/// functions or the newer color(srgb ..) function. If the color(..)
/// function is used, the AS_COLOR_FUNCTION flag will be set. Examples:
/// "color(srgb 0.691 0.139 0.259)", "rgb(176, 35, 66)"
Srgb = 0,
/// A color specified in the Hsl notation in the sRGB color space, e.g.
/// "hsl(289.18 93.136% 65.531%)"
Hsl,
/// A color specified in the Hwb notation in the sRGB color space, e.g.
/// "hwb(740deg 20% 30%)"
Hwb,
/// A color specified in the Lab color format, e.g.
/// "lab(29.2345% 39.3825 20.0664)".
Lab,
/// A color specified in the Lch color format, e.g.
/// "lch(29.2345% 44.2 27)".
Lch,
/// A color specified in the Oklab color format, e.g.
/// "oklab(40.101% 0.1147 0.0453)".
Oklab,
/// A color specified in the Oklch color format, e.g.
/// "oklch(40.101% 0.12332 21.555)".
Oklch,
/// A color specified with the color(..) function and the "srgb-linear"
/// color space, e.g. "color(srgb-linear 0.435 0.017 0.055)".
SrgbLinear,
/// A color specified with the color(..) function and the "display-p3"
/// color space, e.g. "color(display-p3 0.84 0.19 0.72)".
DisplayP3,
/// A color specified with the color(..) function and the "a98-rgb" color
/// space, e.g. "color(a98-rgb 0.44091 0.49971 0.37408)".
A98Rgb,
/// A color specified with the color(..) function and the "prophoto-rgb"
/// color space, e.g. "color(prophoto-rgb 0.36589 0.41717 0.31333)".
ProphotoRgb,
/// A color specified with the color(..) function and the "rec2020" color
/// space, e.g. "color(rec2020 0.42210 0.47580 0.35605)".
Rec2020,
/// A color specified with the color(..) function and the "xyz-d50" color
/// space, e.g. "color(xyz-d50 0.2005 0.14089 0.4472)".
XyzD50,
/// A color specified with the color(..) function and the "xyz-d65" or "xyz"
/// color space, e.g. "color(xyz-d65 0.21661 0.14602 0.59452)".
/// specifies that `xyz` is an alias for the `xyz-d65` color space.
XyzD65,
};
enum class StyleContainerType : uint8_t {
/// The `normal` variant.
Normal,
/// The `inline-size` variant.
InlineSize,
/// The `size` variant.
Size,
};
enum class StyleContentVisibility : uint8_t {
/// `auto` variant, the element turns on layout containment, style containment, and paint
/// containment. In addition, if the element is not relevant to the user (such as by being
/// offscreen) it also skips its content
Auto,
/// `hidden` variant, the element skips its content
Hidden,
/// 'visible' variant, no effect
Visible,
};
/// The <coord-box> value, which defines the box that the <offset-path> sizes into.
///
/// <coord-box> = content-box | padding-box | border-box | fill-box | stroke-box | view-box
enum class StyleCoordBox : uint8_t {
ContentBox,
PaddingBox,
BorderBox,
FillBox,
StrokeBox,
ViewBox,
};
/// The CORS mode used for a CSS load.
enum class StyleCorsMode : uint8_t {
/// No CORS mode, so cross-origin loads can be done.
None,
/// Anonymous CORS request.
Anonymous,
};
enum class StyleCounterSystem : uint8_t {
Cyclic = 0,
Numeric,
Alphabetic,
Symbolic,
Additive,
Fixed,
Extends,
};
enum class StyleCssRuleType : uint8_t {
Style = 1,
Import = 3,
Media = 4,
FontFace = 5,
Page = 6,
Keyframes = 7,
Keyframe = 8,
Margin = 9,
Namespace = 10,
CounterStyle = 11,
Supports = 12,
Document = 13,
FontFeatureValues = 14,
LayerBlock = 16,
LayerStatement = 17,
Container = 18,
FontPaletteValues = 19,
Property = 20,
Scope = 21,
StartingStyle = 22,
PositionTry = 23,
NestedDeclarations = 24,
};
/// The keywords allowed in the Cursor property.
///
enum class StyleCursorKind : uint8_t {
None,
Default,
Pointer,
ContextMenu,
Help,
Progress,
Wait,
Cell,
Crosshair,
Text,
VerticalText,
Alias,
Copy,
Move,
NoDrop,
NotAllowed,
Grab,
Grabbing,
EResize,
NResize,
NeResize,
NwResize,
SResize,
SeResize,
SwResize,
WResize,
EwResize,
NsResize,
NeswResize,
NwseResize,
ColResize,
RowResize,
AllScroll,
ZoomIn,
ZoomOut,
Auto,
};
enum class StyleDisplayInside : uint8_t {
None = 0,
Contents,
Flow,
FlowRoot,
Flex,
Grid,
Table,
TableRowGroup,
TableColumn,
TableColumnGroup,
TableHeaderGroup,
TableFooterGroup,
TableRow,
TableCell,
#if defined(CBINDGEN_IS_GECKO)
Ruby,
#endif
#if defined(CBINDGEN_IS_GECKO)
RubyBase,
#endif
#if defined(CBINDGEN_IS_GECKO)
RubyBaseContainer,
#endif
#if defined(CBINDGEN_IS_GECKO)
RubyText,
#endif
#if defined(CBINDGEN_IS_GECKO)
RubyTextContainer,
#endif
#if defined(CBINDGEN_IS_GECKO)
WebkitBox,
#endif
};
#if defined(CBINDGEN_IS_GECKO)
/// Values for the display-mode media feature.
enum class StyleDisplayMode : uint8_t {
#if defined(CBINDGEN_IS_GECKO)
Browser = 0,
#endif
#if defined(CBINDGEN_IS_GECKO)
MinimalUi,
#endif
#if defined(CBINDGEN_IS_GECKO)
Standalone,
#endif
#if defined(CBINDGEN_IS_GECKO)
Fullscreen,
#endif
};
#endif
/// Defines an element’s display type, which consists of
/// the two basic qualities of how an element generates boxes
enum class StyleDisplayOutside : uint8_t {
None = 0,
Inline,
Block,
TableCaption,
InternalTable,
#if defined(CBINDGEN_IS_GECKO)
InternalRuby,
#endif
};
#if defined(CBINDGEN_IS_GECKO)
/// Values for the dynamic-range and video-dynamic-range media features.
/// This implements PartialOrd so that lower values will correctly match
/// higher capabilities.
enum class StyleDynamicRange : uint8_t {
#if defined(CBINDGEN_IS_GECKO)
Standard,
#endif
#if defined(CBINDGEN_IS_GECKO)
High,
#endif
};
#endif
enum class StyleFillRule : uint8_t {
Nonzero,
Evenodd,
};
enum class StyleFloat : uint8_t {
Left,
Right,
None,
InlineStart,
InlineEnd,
};
/// A font-display value for a @font-face rule.
/// The font-display descriptor determines how a font face is displayed based
/// on whether and when it is downloaded and ready to use.
enum class StyleFontDisplay : uint8_t {
Auto,
Block,
Swap,
Fallback,
Optional,
};
/// Keywords for the font-face src descriptor's format() function.
/// ('None' and 'Unknown' are for internal use in gfx, not exposed to CSS.)
enum class StyleFontFaceSourceFormatKeyword : uint8_t {
None,
Collection,
EmbeddedOpentype,
Opentype,
Svg,
Truetype,
Woff,
Woff2,
Unknown,
};
/// Font family names must either be given quoted as strings,
/// or unquoted as a sequence of one or more identifiers.
enum class StyleFontFamilyNameSyntax : uint8_t {
/// The family name was specified in a quoted form, e.g. "Font Name"
/// or 'Font Name'.
Quoted,
/// The family name was specified in an unquoted form as a sequence of
/// identifiers.
Identifiers,
};
/// CSS font keywords
enum class StyleFontSizeKeyword : uint8_t {
XXSmall,
XSmall,
Small,
Medium,
Large,
XLarge,
XXLarge,
XXXLarge,
#if defined(CBINDGEN_IS_GECKO)
/// Indicate whether to apply font-size: math is specified so that extra
/// scaling due to math-depth changes is applied during the cascade.
Math,
#endif
None,
};
/// A value for any of the font-synthesis-{weight,small-caps,position} properties.
enum class StyleFontSynthesis : uint8_t {
/// This attribute may be synthesized if not supported by a face.
Auto,
/// Do not attempt to synthesis this style attribute.
None,
};
/// A value for the font-synthesis-style property.
enum class StyleFontSynthesisStyle : uint8_t {
/// This attribute may be synthesized if not supported by a face.
Auto,
/// Do not attempt to synthesis this style attribute.
None,
/// Allow synthesis for oblique, but not for italic.
ObliqueOnly,
};
enum class StyleForcedColorAdjust : uint8_t {
/// Adjust colors if needed.
Auto,
/// Respect specified colors.
None,
};
/// Possible values for the forced-colors media query.
enum class StyleForcedColors : uint8_t {
/// Page colors are not being forced.
None,
/// Page colors would be forced in content.
Requested,
/// Page colors are being forced.
Active,
};
/// A generic font-family name.
///
/// The order here is important, if you change it make sure that
/// `gfxPlatformFontList.h`s ranged array and `gfxFontFamilyList`'s
/// sSingleGenerics are updated as well.
///
/// NOTE(emilio): Should be u8, but it's a u32 because of ABI issues between GCC
enum class StyleGenericFontFamily : uint32_t {
/// No generic family specified, only for internal usage.
///
/// NOTE(emilio): Gecko code relies on this variant being zero.
None = 0,
Serif,
SansSerif,
Monospace,
Cursive,
Fantasy,
SystemUi,
#if defined(CBINDGEN_IS_GECKO)
/// An internal value for emoji font selection.
MozEmoji,
#endif
};
/// Whether we used the modern notation or the compatibility `-webkit`, `-moz` prefixes.
enum class StyleGradientCompatMode : uint8_t {
/// Modern syntax.
Modern,
/// `-webkit` prefix.
WebKit,
/// `-moz` prefix
Moz,
};
#if defined(CBINDGEN_IS_GECKO)
/// Allows front-end CSS to discern gtk theme via media queries.
enum class StyleGtkThemeFamily : uint8_t {
#if defined(CBINDGEN_IS_GECKO)
/// Unknown theme family.
Unknown = 0,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Adwaita, the default GTK theme.
Adwaita,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Breeze, the default KDE theme.
Breeze,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Yaru, the default Ubuntu theme.
Yaru,
#endif
};
#endif
/// A keyword for the X direction.
enum class StyleHorizontalPositionKeyword : uint8_t {
Left,
Right,
};
/// A hue-interpolation-method as defined in [1].
///
enum class StyleHueInterpolationMethod : uint8_t {
Shorter,
Longer,
Increasing,
Decreasing,
Specified,
};
enum class StyleImageRendering : uint8_t {
Auto,
#if defined(CBINDGEN_IS_GECKO)
Smooth,
#endif
CrispEdges,
Pixelated,
#if defined(CBINDGEN_IS_GECKO)
Optimizespeed,
#endif
#if defined(CBINDGEN_IS_GECKO)
Optimizequality,
#endif
};
/// Internal property to represent the inert attribute state:
enum class StyleInert : uint8_t {
None,
Inert,
};
enum class StyleIsOrdinalInRange : uint8_t {
Auto,
InRange,
NotInRange,
NoOrdinalSpecified,
};
/// Values for the `line-break` property.
enum class StyleLineBreak : uint8_t {
Auto,
Loose,
Normal,
Strict,
Anywhere,
};
/// Masonry auto-placement algorithm item sorting option.
enum class StyleMasonryItemOrder : uint8_t {
/// Place all items with a definite placement before auto-placed items.
DefiniteFirst,
/// Place items in `order-modified document order`.
Ordered,
};
/// Masonry auto-placement algorithm packing.
enum class StyleMasonryPlacement : uint8_t {
/// Place the item in the track(s) with the smallest extent so far.
Pack,
/// Place the item after the last item, from start to end.
Next,
};
/// Whether we're a `min` or `max` function.
enum class StyleMinMaxOp : uint8_t {
/// `min()`
Min,
/// `max()`
Max,
};
/// Whether we're a `mod` or `rem` function.
enum class StyleModRemOp : uint8_t {
/// `mod()`
Mod,
/// `rem()`
Rem,
};
/// Values for the `-moz-control-character-visibility` CSS property.
enum class StyleMozControlCharacterVisibility : uint8_t {
Hidden,
Visible,
};
/// The keywords allowed in the -moz-theme property.
enum class StyleMozTheme : uint8_t {
/// Choose the default (maybe native) rendering.
Auto,
/// Choose the non-native rendering.
NonNative,
};
/// Each style rule has an origin, which determines where it enters the cascade.
///
enum class StyleOrigin : uint8_t {
UserAgent = 1,
User = 2,
Author = 4,
};
/// The value for the `overflow-x` / `overflow-y` properties.
enum class StyleOverflow : uint8_t {
Visible,
Hidden,
Scroll,
Auto,
Clip,
};
enum class StyleOverflowAnchor : uint8_t {
Auto,
None,
};
enum class StyleOverflowClipBox : uint8_t {
PaddingBox,
ContentBox,
};
/// Values for the `overflow-wrap` property.
enum class StyleOverflowWrap : uint8_t {
Normal,
BreakWord,
Anywhere,
};
enum class StyleOverscrollBehavior : uint8_t {
Auto,
Contain,
None,
};
/// Page orientation names.
///
enum class StylePageOrientation : uint8_t {
/// upright
Upright,
/// rotate-left (counter-clockwise)
RotateLeft,
/// rotate-right (clockwise)
RotateRight,
};
/// Paper orientation
///
enum class StylePageSizeOrientation : uint8_t {
/// Portrait orientation
Portrait,
/// Landscape orientation
Landscape,
};
/// The specified value for a single CSS paint-order property.
enum class StylePaintOrder : uint8_t {
/// `normal` variant
Normal = 0,
/// `fill` variant
Fill = 1,
/// `stroke` variant
Stroke = 2,
/// `markers` variant
Markers = 3,
};
enum class StylePhysicalAxis : uint8_t {
Vertical = 0,
Horizontal,
};
#if defined(CBINDGEN_IS_GECKO)
/// Allows front-end CSS to discern platform via media queries.
enum class StylePlatform : uint8_t {
#if defined(CBINDGEN_IS_GECKO)
/// Matches any Android version.
Android,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// For our purposes here, "linux" is just "gtk" (so unix-but-not-mac).
/// There's no need for our front-end code to differentiate between those
/// platforms and they already use the "linux" string elsewhere (e.g.,
/// toolkit/themes/linux).
Linux,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Matches any iOS version.
Ios,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Matches any macOS version.
Macos,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Matches any Windows version.
Windows,
#endif
};
#endif
/// The pointer-events property
enum class StylePointerEvents : uint8_t {
Auto,
None,
#if defined(CBINDGEN_IS_GECKO)
Visiblepainted,
#endif
#if defined(CBINDGEN_IS_GECKO)
Visiblefill,
#endif
#if defined(CBINDGEN_IS_GECKO)
Visiblestroke,
#endif
#if defined(CBINDGEN_IS_GECKO)
Visible,
#endif
#if defined(CBINDGEN_IS_GECKO)
Painted,
#endif
#if defined(CBINDGEN_IS_GECKO)
Fill,
#endif
#if defined(CBINDGEN_IS_GECKO)
Stroke,
#endif
#if defined(CBINDGEN_IS_GECKO)
All,
#endif
};
/// Possible values for the `position-area` preperty's keywords.
enum class StylePositionAreaKeyword : uint8_t {
None,
Center,
SpanAll,
Left,
Right,
SpanLeft,
SpanRight,
XStart,
XEnd,
SpanXStart,
SpanXEnd,
XSelfStart,
XSelfEnd,
SpanXSelfStart,
SpanXSelfEnd,
Top,
Bottom,
SpanTop,
SpanBottom,
YStart,
YEnd,
SpanYStart,
SpanYEnd,
YSelfStart,
YSelfEnd,
SpanYSelfStart,
SpanYSelfEnd,
BlockStart,
BlockEnd,
SpanBlockStart,
SpanBlockEnd,
InlineStart,
InlineEnd,
SpanInlineStart,
SpanInlineEnd,
SelfBlockStart,
SelfBlockEnd,
SpanSelfBlockStart,
SpanSelfBlockEnd,
SelfInlineStart,
SelfInlineEnd,
SpanSelfInlineStart,
SpanSelfInlineEnd,
Start,
End,
SpanStart,
SpanEnd,
SelfStart,
SelfEnd,
SpanSelfStart,
SpanSelfEnd,
};
enum class StylePositionProperty : uint8_t {
Static = 0,
Relative,
Absolute,
Fixed,
Sticky,
};
/// How to swap values for the automatically-generated position tactic.
enum class StylePositionTryFallbacksTryTacticKeyword : uint8_t {
/// Magic value for no change.
None,
/// Swap the values in the block axis.
FlipBlock,
/// Swap the values in the inline axis.
FlipInline,
/// Swap the values in the start properties.
FlipStart,
};
enum class StylePositionTryOrder : uint8_t {
/// `normal`
Normal,
/// `most-width`
MostWidth,
/// `most-height`
MostHeight,
/// `most-block-size`
MostBlockSize,
/// `most-inline-size`
MostInlineSize,
};
/// Values for the prefers-color-scheme media feature.
enum class StylePrefersColorScheme : uint8_t {
Light,
Dark,
};
#if defined(CBINDGEN_IS_GECKO)
/// Possible values for prefers-contrast media query.
enum class StylePrefersContrast : uint8_t {
#if defined(CBINDGEN_IS_GECKO)
/// More contrast is preferred.
More,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Low contrast is preferred.
Less,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Custom (not more, not less).
Custom,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// The default value if neither high or low contrast is enabled.
NoPreference,
#endif
};
#endif
enum class StylePrintColorAdjust : uint8_t {
/// Ignore backgrounds and darken text.
Economy,
/// Respect specified colors.
Exact,
};
/// The <size> in ray() function.
///
enum class StyleRaySize : uint8_t {
ClosestSide,
ClosestCorner,
FarthestSide,
FarthestCorner,
Sides,
};
enum class StyleRegisterCustomPropertyResult : uint8_t {
SuccessfullyRegistered,
InvalidName,
AlreadyRegistered,
InvalidSyntax,
NoInitialValue,
InvalidInitialValue,
InitialValueNotComputationallyIndependent,
};
/// Which edge side should the invalidation run for?
enum class StyleRelativeSelectorNthEdgeInvalidateFor : uint8_t {
First,
Last,
};
/// A computed value for the `resize` property.
enum class StyleResize : uint8_t {
None,
Both,
Horizontal,
Vertical,
};
/// The strategy used in `round()`
enum class StyleRoundingStrategy : uint8_t {
/// `round(nearest, a, b)`
/// round a to the nearest multiple of b
Nearest,
/// `round(up, a, b)`
/// round a up to the nearest multiple of b
Up,
/// `round(down, a, b)`
/// round a down to the nearest multiple of b
Down,
/// `round(to-zero, a, b)`
/// round a to the nearest multiple of b that is towards zero
ToZero,
};
/// Values for `ruby-position` property
enum class StyleRubyPosition : uint8_t {
AlternateOver,
AlternateUnder,
Over,
Under,
};
/// The kind of change that happened for a given rule.
enum class StyleRuleChangeKind : uint32_t {
/// Some change in the rule which we don't know about, and could have made
/// the rule change in any way.
Generic = 0,
/// The rule was inserted.
Insertion,
/// The rule was removed.
Removal,
/// A change in the declarations of a style rule.
StyleRuleDeclarations,
};
/// The kind of sanitization to use when parsing a stylesheet.
enum class StyleSanitizationKind : uint8_t {
/// Perform no sanitization.
None,
/// Allow only @font-face, style rules, and @namespace.
Standard,
/// Allow everything but conditional rules.
NoConditionalRules,
};
#if defined(CBINDGEN_IS_GECKO)
/// Values for the scripting media feature.
enum class StyleScripting : uint8_t {
#if defined(CBINDGEN_IS_GECKO)
/// Scripting is not supported or not enabled
None,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Scripting is supported and enabled, but only for initial page load
/// We will never match this value as it is intended for non-browser user agents,
/// but it is part of the spec so we should still parse it.
InitialOnly,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Scripting is supported and enabled
Enabled,
#endif
};
#endif
/// A value for the <Axis> used in scroll(), or a value for {scroll|view}-timeline-axis.
///
enum class StyleScrollAxis : uint8_t {
/// The block axis of the scroll container. (Default.)
Block = 0,
/// The inline axis of the scroll container.
Inline = 1,
/// The horizontal axis of the scroll container.
X = 2,
/// The vertical axis of the scroll container.
Y = 3,
};
/// Specified value of scroll-snap-align keyword value.
enum class StyleScrollSnapAlignKeyword : uint8_t {
None,
Start,
End,
Center,
};
enum class StyleScrollSnapAxis : uint8_t {
X,
Y,
Block,
Inline,
Both,
};
enum class StyleScrollSnapStop : uint8_t {
Normal,
Always,
};
enum class StyleScrollSnapStrictness : uint8_t {
None,
Mandatory,
Proximity,
};
/// A value for the <Scroller> used in scroll().
///
enum class StyleScroller : uint8_t {
/// The nearest ancestor scroll container. (Default.)
Nearest,
/// The document viewport as the scroll container.
Root,
/// Specifies to use the element’s own principal box as the scroll container.
SelfElement,
};
/// Any warning a selector may generate.
/// TODO(dshin): Bug 1860634 - Merge with never matching host selector warning, which is part of the rule parser.
enum class StyleSelectorWarningKind : uint8_t {
/// Relative Selector with not enough constraint, either outside or inside the selector. e.g. `*:has(.a)`, `.a:has(*)`.
/// May cause expensive invalidations for every element inserted and/or removed.
UnconstraintedRelativeSelector,
};
enum class StyleShapeBox : uint8_t {
MarginBox,
BorderBox,
PaddingBox,
ContentBox,
};
enum class StyleShapeExtent : uint8_t {
ClosestSide,
FarthestSide,
ClosestCorner,
FarthestCorner,
Contain,
Cover,
};
enum class StyleStepPosition : uint8_t {
JumpStart,
JumpEnd,
JumpNone,
JumpBoth,
Start,
End,
};
enum class StyleSymbolsType : uint8_t {
Cyclic,
Numeric,
Alphabetic,
Symbolic,
Fixed,
};
#if defined(CBINDGEN_IS_GECKO)
/// System colors. A bunch of these are ad-hoc, others come from Windows:
///
///
/// Others are HTML/CSS specific. Spec is:
///
enum class StyleSystemColor : uint8_t {
Activeborder,
/// Background in the (active) titlebar.
Activecaption,
Appworkspace,
Background,
Buttonface,
Buttonhighlight,
Buttonshadow,
Buttontext,
Buttonborder,
/// Text color in the (active) titlebar.
Captiontext,
Field,
/// Used for disabled field backgrounds.
MozDisabledfield,
Fieldtext,
Mark,
Marktext,
/// Combobox widgets
MozComboboxtext,
MozCombobox,
Graytext,
Highlight,
Highlighttext,
Inactiveborder,
/// Background in the (inactive) titlebar.
Inactivecaption,
/// Text color in the (inactive) titlebar.
Inactivecaptiontext,
Infobackground,
Infotext,
Menu,
Menutext,
Scrollbar,
Threeddarkshadow,
Threedface,
Threedhighlight,
Threedlightshadow,
Threedshadow,
Window,
Windowframe,
Windowtext,
Canvastext,
Canvas,
MozDialog,
MozDialogtext,
/// Used for selected but not focused cell backgrounds.
MozCellhighlight,
/// Used for selected but not focused cell text.
MozCellhighlighttext,
/// Used for selected and focused html cell backgrounds.
Selecteditem,
/// Used for selected and focused html cell text.
Selecteditemtext,
/// Used to button text background when hovered.
MozButtonhoverface,
/// Used to button text color when hovered.
MozButtonhovertext,
/// Used for menu item backgrounds when hovered.
MozMenuhover,
/// Used for menu item backgrounds when hovered and disabled.
MozMenuhoverdisabled,
/// Used for menu item text when hovered.
MozMenuhovertext,
/// Used for menubar item text when hovered.
MozMenubarhovertext,
/// On platforms where these colors are the same as -moz-field, use
/// -moz-fieldtext as foreground color
MozEventreerow,
MozOddtreerow,
/// Used for button text when pressed.
MozButtonactivetext,
/// Used for button background when pressed.
MozButtonactiveface,
/// Used for button background when disabled.
MozButtondisabledface,
/// Colors used for the header bar (sorta like the tab bar / menubar).
MozHeaderbar,
MozHeaderbartext,
MozHeaderbarinactive,
MozHeaderbarinactivetext,
/// Foreground color of default buttons.
MozMacDefaultbuttontext,
/// Ring color around text fields and lists.
MozMacFocusring,
/// Text color of disabled text on toolbars.
MozMacDisabledtoolbartext,
/// The background of a sidebar.
MozSidebar,
/// The foreground color of a sidebar.
MozSidebartext,
/// The border color of a sidebar.
MozSidebarborder,
/// Theme accent color.
Accentcolor,
/// Foreground for the accent color.
Accentcolortext,
/// The background-color for :autofill-ed inputs.
MozAutofillBackground,
Linktext,
Activetext,
Visitedtext,
/// Color of tree column headers
MozColheader,
MozColheadertext,
MozColheaderhover,
MozColheaderhovertext,
MozColheaderactive,
MozColheaderactivetext,
TextSelectDisabledBackground,
TextSelectAttentionBackground,
TextSelectAttentionForeground,
TextHighlightBackground,
TextHighlightForeground,
TargetTextBackground,
TargetTextForeground,
IMERawInputBackground,
IMERawInputForeground,
IMERawInputUnderline,
IMESelectedRawTextBackground,
IMESelectedRawTextForeground,
IMESelectedRawTextUnderline,
IMEConvertedTextBackground,
IMEConvertedTextForeground,
IMEConvertedTextUnderline,
IMESelectedConvertedTextBackground,
IMESelectedConvertedTextForeground,
IMESelectedConvertedTextUnderline,
SpellCheckerUnderline,
ThemedScrollbar,
ThemedScrollbarInactive,
ThemedScrollbarThumb,
ThemedScrollbarThumbHover,
ThemedScrollbarThumbActive,
ThemedScrollbarThumbInactive,
End,
};
#endif
#if defined(CBINDGEN_IS_GECKO)
/// System fonts.
enum class StyleSystemFont : uint8_t {
Caption,
Icon,
Menu,
MessageBox,
SmallCaption,
StatusBar,
/// Internal system font, used by the `<menupopup>`s on macOS.
MozPullDownMenu,
/// Internal system font, used for `<button>` elements.
MozButton,
/// Internal font, used by `<select>` elements.
MozList,
/// Internal font, used by `<input>` elements.
MozField,
End,
};
#endif
/// Specified value of text-align keyword value.
enum class StyleTextAlignKeyword : uint8_t {
Start,
Left,
Right,
Center,
Justify,
End,
MozCenter,
MozLeft,
MozRight,
};
/// Specified and computed value of text-align-last.
enum class StyleTextAlignLast : uint8_t {
Auto,
Start,
End,
Left,
Right,
Center,
Justify,
};
/// Implements text-decoration-skip-ink which takes the keywords auto | none | all
///
enum class StyleTextDecorationSkipInk : uint8_t {
Auto,
None,
All,
};
/// Fill mode for the text-emphasis-style property
enum class StyleTextEmphasisFillMode : uint8_t {
/// `filled`
Filled,
/// `open`
Open,
};
/// Shape keyword for the text-emphasis-style property
enum class StyleTextEmphasisShapeKeyword : uint8_t {
/// `dot`
Dot,
/// `circle`
Circle,
/// `double-circle`
DoubleCircle,
/// `triangle`
Triangle,
/// `sesame`
Sesame,
};
/// Values for the `text-justify` CSS property.
enum class StyleTextJustify : uint8_t {
Auto,
None,
InterWord,
InterCharacter,
};
enum class StyleTimingKeyword : uint8_t {
Linear,
Ease,
EaseIn,
EaseOut,
EaseInOut,
};
/// The specified value of `transform-box`.
enum class StyleTransformBox : uint8_t {
ContentBox,
BorderBox,
FillBox,
StrokeBox,
ViewBox,
};
enum class StyleTransformStyle : uint8_t {
Flat,
Preserve3d,
};
/// A specified value for <transition-behavior-value>.
///
enum class StyleTransitionBehavior : uint8_t {
/// Transitions will not be started for discrete properties, only for interpolable properties.
Normal,
/// Transitions will be started for discrete properties as well as interpolable properties.
AllowDiscrete,
};
/// Internal -moz-user-focus property.
enum class StyleUserFocus : uint8_t {
Normal,
None,
Ignore,
};
/// Non-standard user-input property.
enum class StyleUserInput : uint8_t {
Auto,
None,
};
/// The specified value for the `user-select` property.
///
enum class StyleUserSelect : uint8_t {
Auto,
Text,
None,
/// Force selection of all children.
All,
};
enum class StyleVerticalAlignKeyword : uint8_t {
Baseline,
Sub,
Super,
Top,
TextTop,
Middle,
Bottom,
TextBottom,
#if defined(CBINDGEN_IS_GECKO)
MozMiddleWithBaseline,
#endif
};
/// A keyword for the Y direction.
enum class StyleVerticalPositionKeyword : uint8_t {
Top,
Bottom,
};
/// Values for the `word-break` property.
enum class StyleWordBreak : uint8_t {
Normal,
BreakAll,
KeepAll,
#if defined(CBINDGEN_IS_GECKO)
/// The break-word value, needed for compat.
///
/// Specifying `word-break: break-word` makes `overflow-wrap` behave as
/// `anywhere`, and `word-break` behave like `normal`.
BreakWord,
#endif
};
/// How to do font-size scaling.
enum class StyleXTextScale : uint8_t {
/// Both min-font-size and text zoom are enabled.
All,
/// Text-only zoom is enabled, but min-font-size is not honored.
ZoomOnly,
/// Neither of them is enabled.
None,
};
#if defined(CBINDGEN_IS_GECKO)
/// Gecko-FFI-safe Arc (T is an ArcInner).
///
/// This can be null.
///
/// Leaks on drop. Please don't drop this.
template<typename GeckoType>
struct StyleStrong {
const GeckoType *ptr;
bool operator==(const StyleStrong& other) const {
return ptr == other.ptr;
}
bool operator!=(const StyleStrong& other) const {
return ptr != other.ptr;
}
already_AddRefed<GeckoType> Consume() {
already_AddRefed<GeckoType> ret(const_cast<GeckoType*>(ptr));
ptr = nullptr;
return ret;
}
};
#endif
/// A CSS float value.
using StyleCSSFloat = float;
/// A `<number>` value.
using StyleNumber = StyleCSSFloat;
/// A value of the `Scale` property
///
template<typename Number>
struct StyleGenericScale {
enum class Tag : uint8_t {
/// 'none'
None,
/// '<number>{1,3}'
Scale,
};
struct StyleScale_Body {
Number _0;
Number _1;
Number _2;
bool operator==(const StyleScale_Body& other) const {
return _0 == other._0 &&
_1 == other._1 &&
_2 == other._2;
}
bool operator!=(const StyleScale_Body& other) const {
return _0 != other._0 ||
_1 != other._1 ||
_2 != other._2;
}
};
Tag tag;
union {
StyleScale_Body scale;
};
static StyleGenericScale None() {
StyleGenericScale result;
result.tag = Tag::None;
return result;
}
bool IsNone() const {
return tag == Tag::None;
}
static StyleGenericScale Scale(const Number &_0,
const Number &_1,
const Number &_2) {
StyleGenericScale result;
::new (&result.scale._0) (Number)(_0);
::new (&result.scale._1) (Number)(_1);
::new (&result.scale._2) (Number)(_2);
result.tag = Tag::Scale;
return result;
}
bool IsScale() const {
return tag == Tag::Scale;
}
const StyleScale_Body& AsScale() const {
MOZ_DIAGNOSTIC_ASSERT(IsScale());
return scale;
}
bool operator==(const StyleGenericScale& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Scale: return scale == other.scale;
default: break;
}
return true;
}
bool operator!=(const StyleGenericScale& other) const {
return !(*this == other);
}
private:
StyleGenericScale() {
}
public:
~StyleGenericScale() {
switch (tag) {
case Tag::Scale: scale.~StyleScale_Body(); break;
default: break;
}
}
StyleGenericScale(const StyleGenericScale& other)
: tag(other.tag) {
switch (tag) {
case Tag::Scale: ::new (&scale) (StyleScale_Body)(other.scale); break;
default: break;
}
}
StyleGenericScale& operator=(const StyleGenericScale& other) {
if (this != &other) {
this->~StyleGenericScale();
new (this) StyleGenericScale(other);
}
return *this;
}
};
/// A computed CSS `scale`
using StyleScale = StyleGenericScale<StyleNumber>;
/// The computed `<length>` value.
struct StyleCSSPixelLength {
StyleCSSFloat _0;
bool operator==(const StyleCSSPixelLength& other) const {
return _0 == other._0;
}
bool operator!=(const StyleCSSPixelLength& other) const {
return _0 != other._0;
}
static StyleCSSPixelLength FromPixels(CSSCoord aCoord) { return {aCoord}; }
static StyleCSSPixelLength Zero() { return FromPixels(0.0f); }
inline nscoord ToAppUnits() const;
inline bool IsZero() const;
CSSCoord ToCSSPixels() const { return _0; }
inline void ScaleBy(float);
inline StyleCSSPixelLength ScaledBy(float) const;
};
/// An alias of computed `<length>` value.
using StyleLength = StyleCSSPixelLength;
struct StyleLengthVariant {
uint8_t tag;
StyleLength length;
bool operator==(const StyleLengthVariant& other) const {
return tag == other.tag &&
length == other.length;
}
bool operator!=(const StyleLengthVariant& other) const {
return tag != other.tag ||
length != other.length;
}
};
/// A computed percentage.
struct StylePercentage {
StyleCSSFloat _0;
bool operator==(const StylePercentage& other) const {
return _0 == other._0;
}
bool operator!=(const StylePercentage& other) const {
return _0 != other._0;
}
};
struct StylePercentageVariant {
uint8_t tag;
StylePercentage percentage;
bool operator==(const StylePercentageVariant& other) const {
return tag == other.tag &&
percentage == other.percentage;
}
bool operator!=(const StylePercentageVariant& other) const {
return tag != other.tag ||
percentage != other.percentage;
}
};
#if defined(SERVO_32_BITS)
struct StyleCalcVariant {
uint8_t tag;
void *ptr;
bool operator==(const StyleCalcVariant& other) const {
return tag == other.tag &&
ptr == other.ptr;
}
bool operator!=(const StyleCalcVariant& other) const {
return tag != other.tag ||
ptr != other.ptr;
}
};
#endif
#if defined(HAVE_64BIT_BUILD)
struct StyleCalcVariant {
uintptr_t ptr;
bool operator==(const StyleCalcVariant& other) const {
return ptr == other.ptr;
}
bool operator!=(const StyleCalcVariant& other) const {
return ptr != other.ptr;
}
};
#endif
struct StyleTagVariant {
uint8_t tag;
bool operator==(const StyleTagVariant& other) const {
return tag == other.tag;
}
bool operator!=(const StyleTagVariant& other) const {
return tag != other.tag;
}
};
union StyleLengthPercentageUnion {
StyleLengthVariant length;
StylePercentageVariant percentage;
StyleCalcVariant calc;
StyleTagVariant tag;
using Self = StyleLengthPercentageUnion;
// TODO(emilio): cbindgen should be able to generate these in the body of the
// union, but it seems it's only implemented for structs, not unions.
static const uint8_t TAG_CALC = StyleLengthPercentageUnion_TAG_CALC;
static const uint8_t TAG_LENGTH = StyleLengthPercentageUnion_TAG_LENGTH;
static const uint8_t TAG_PERCENTAGE = StyleLengthPercentageUnion_TAG_PERCENTAGE;
static const uint8_t TAG_MASK = StyleLengthPercentageUnion_TAG_MASK;
private:
uint8_t Tag() const {
return tag.tag & TAG_MASK;
}
public:
// We need to do all this manually because cbingen can't reason about unions.
inline StyleLengthPercentageUnion();
inline StyleLengthPercentageUnion(const Self&);
inline ~StyleLengthPercentageUnion();
inline Self& operator=(const Self&);
inline bool operator==(const Self& aOther) const;
inline bool operator!=(const Self& aOther) const;
inline bool IsLength() const;
inline bool IsPercentage() const;
inline bool IsCalc() const;
inline const StyleLength& AsLength() const;
inline StyleLength& AsLength();
inline const StylePercentage& AsPercentage() const;
inline StylePercentage& AsPercentage();
inline const StyleCalcLengthPercentage& AsCalc() const;
inline StyleCalcLengthPercentage& AsCalc();
static inline Self Zero();
static inline Self FromAppUnits(nscoord);
static inline Self FromPixels(CSSCoord);
static inline Self FromPercentage(float);
inline void ScaleLengthsBy(float);
inline bool HasPercent() const;
inline bool ConvertsToLength() const;
inline nscoord ToLength() const;
inline CSSCoord ToLengthInCSSPixels() const;
inline bool ConvertsToPercentage() const;
inline bool HasLengthAndPercentage() const;
inline float ToPercentage() const;
inline bool IsDefinitelyZero() const;
inline CSSCoord ResolveToCSSPixels(CSSCoord aPercentageBasisInCSSPixels) const;
template<typename T> inline CSSCoord ResolveToCSSPixelsWith(T aPercentageGetter) const;
template<typename T, typename Rounder>
inline nscoord Resolve(T aPercentageGetter, Rounder) const;
template<typename Rounder>
inline nscoord Resolve(nscoord aPercentageBasis, Rounder) const;
template<typename T> inline nscoord Resolve(T aPercentageGetter) const;
inline nscoord Resolve(nscoord aPercentageBasis) const;
};
/// A `<length-percentage>` value. This can be either a `<length>`, a
/// `<percentage>`, or a combination of both via `calc()`.
///
///
///
/// The tag is stored in the lower two bits.
///
/// We need to use a struct instead of the union directly because unions with
/// Drop implementations are unstable, looks like.
///
/// Also we need the union and the variants to be `pub` (even though the member
/// is private) so that cbindgen generates it. They're not part of the public
/// API otherwise.
using StyleLengthPercentage = StyleLengthPercentageUnion;
/// A value of the `translate` property
///
///
/// If a 2d translation is specified, the property must serialize with only one
/// or two values (per usual, if the second value is 0px, the default, it must
/// be omitted when serializing; however if 0% is the second value, it is included).
///
/// If a 3d translation is specified and the value can be expressed as 2d, we treat as 2d and
/// serialize accoringly. Otherwise, we serialize all three values.
///
template<typename LengthPercentage, typename Length>
struct StyleGenericTranslate {
enum class Tag : uint8_t {
/// 'none'
None,
/// <length-percentage> [ <length-percentage> <length>? ]?
Translate,
};
struct StyleTranslate_Body {
LengthPercentage _0;
LengthPercentage _1;
Length _2;
bool operator==(const StyleTranslate_Body& other) const {
return _0 == other._0 &&
_1 == other._1 &&
_2 == other._2;
}
bool operator!=(const StyleTranslate_Body& other) const {
return _0 != other._0 ||
_1 != other._1 ||
_2 != other._2;
}
};
Tag tag;
union {
StyleTranslate_Body translate;
};
static StyleGenericTranslate None() {
StyleGenericTranslate result;
result.tag = Tag::None;
return result;
}
bool IsNone() const {
return tag == Tag::None;
}
static StyleGenericTranslate Translate(const LengthPercentage &_0,
const LengthPercentage &_1,
const Length &_2) {
StyleGenericTranslate result;
::new (&result.translate._0) (LengthPercentage)(_0);
::new (&result.translate._1) (LengthPercentage)(_1);
::new (&result.translate._2) (Length)(_2);
result.tag = Tag::Translate;
return result;
}
bool IsTranslate() const {
return tag == Tag::Translate;
}
const StyleTranslate_Body& AsTranslate() const {
MOZ_DIAGNOSTIC_ASSERT(IsTranslate());
return translate;
}
bool operator==(const StyleGenericTranslate& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Translate: return translate == other.translate;
default: break;
}
return true;
}
bool operator!=(const StyleGenericTranslate& other) const {
return !(*this == other);
}
private:
StyleGenericTranslate() {
}
public:
~StyleGenericTranslate() {
switch (tag) {
case Tag::Translate: translate.~StyleTranslate_Body(); break;
default: break;
}
}
StyleGenericTranslate(const StyleGenericTranslate& other)
: tag(other.tag) {
switch (tag) {
case Tag::Translate: ::new (&translate) (StyleTranslate_Body)(other.translate); break;
default: break;
}
}
StyleGenericTranslate& operator=(const StyleGenericTranslate& other) {
if (this != &other) {
this->~StyleGenericTranslate();
new (this) StyleGenericTranslate(other);
}
return *this;
}
};
/// A computed CSS `translate`
using StyleTranslate = StyleGenericTranslate<StyleLengthPercentage, StyleLength>;
/// A computed angle in degrees.
struct StyleAngle {
StyleCSSFloat _0;
bool operator==(const StyleAngle& other) const {
return _0 == other._0;
}
bool operator!=(const StyleAngle& other) const {
return _0 != other._0;
}
inline static StyleAngle Zero();
inline float ToDegrees() const;
inline double ToRadians() const;
StyleAngle operator+(const StyleAngle& aAngle) const {
return StyleAngle{_0 + aAngle._0};
}
StyleAngle operator-(const StyleAngle& aAngle) const {
return StyleAngle{_0 - aAngle._0};
}
};
/// A value of the `Rotate` property
///
template<typename Number, typename Angle>
struct StyleGenericRotate {
enum class Tag : uint8_t {
/// 'none'
None,
/// '<angle>'
Rotate,
/// '<number>{3} <angle>'
Rotate3D,
};
struct StyleRotate_Body {
Angle _0;
bool operator==(const StyleRotate_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleRotate_Body& other) const {
return _0 != other._0;
}
};
struct StyleRotate3D_Body {
Number _0;
Number _1;
Number _2;
Angle _3;
bool operator==(const StyleRotate3D_Body& other) const {
return _0 == other._0 &&
_1 == other._1 &&
_2 == other._2 &&
_3 == other._3;
}
bool operator!=(const StyleRotate3D_Body& other) const {
return _0 != other._0 ||
_1 != other._1 ||
_2 != other._2 ||
_3 != other._3;
}
};
Tag tag;
union {
StyleRotate_Body rotate;
StyleRotate3D_Body rotate3_d;
};
static StyleGenericRotate None() {
StyleGenericRotate result;
result.tag = Tag::None;
return result;
}
bool IsNone() const {
return tag == Tag::None;
}
static StyleGenericRotate Rotate(const Angle &_0) {
StyleGenericRotate result;
::new (&result.rotate._0) (Angle)(_0);
result.tag = Tag::Rotate;
return result;
}
bool IsRotate() const {
return tag == Tag::Rotate;
}
const Angle& AsRotate() const {
MOZ_DIAGNOSTIC_ASSERT(IsRotate());
return rotate._0;
}
static StyleGenericRotate Rotate3D(const Number &_0,
const Number &_1,
const Number &_2,
const Angle &_3) {
StyleGenericRotate result;
::new (&result.rotate3_d._0) (Number)(_0);
::new (&result.rotate3_d._1) (Number)(_1);
::new (&result.rotate3_d._2) (Number)(_2);
::new (&result.rotate3_d._3) (Angle)(_3);
result.tag = Tag::Rotate3D;
return result;
}
bool IsRotate3D() const {
return tag == Tag::Rotate3D;
}
const StyleRotate3D_Body& AsRotate3D() const {
MOZ_DIAGNOSTIC_ASSERT(IsRotate3D());
return rotate3_d;
}
bool operator==(const StyleGenericRotate& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Rotate: return rotate == other.rotate;
case Tag::Rotate3D: return rotate3_d == other.rotate3_d;
default: break;
}
return true;
}
bool operator!=(const StyleGenericRotate& other) const {
return !(*this == other);
}
private:
StyleGenericRotate() {
}
public:
~StyleGenericRotate() {
switch (tag) {
case Tag::Rotate: rotate.~StyleRotate_Body(); break;
case Tag::Rotate3D: rotate3_d.~StyleRotate3D_Body(); break;
default: break;
}
}
StyleGenericRotate(const StyleGenericRotate& other)
: tag(other.tag) {
switch (tag) {
case Tag::Rotate: ::new (&rotate) (StyleRotate_Body)(other.rotate); break;
case Tag::Rotate3D: ::new (&rotate3_d) (StyleRotate3D_Body)(other.rotate3_d); break;
default: break;
}
}
StyleGenericRotate& operator=(const StyleGenericRotate& other) {
if (this != &other) {
this->~StyleGenericRotate();
new (this) StyleGenericRotate(other);
}
return *this;
}
};
/// A computed CSS `rotate`
using StyleRotate = StyleGenericRotate<StyleNumber, StyleAngle>;
/// A CSS integer value.
using StyleCSSInteger = int32_t;
/// A `<integer>` value.
using StyleInteger = StyleCSSInteger;
/// A generic 2D transformation matrix.
template<typename T>
struct StyleGenericMatrix {
T a;
T b;
T c;
T d;
T e;
T f;
bool operator==(const StyleGenericMatrix& other) const {
return a == other.a &&
b == other.b &&
c == other.c &&
d == other.d &&
e == other.e &&
f == other.f;
}
bool operator!=(const StyleGenericMatrix& other) const {
return a != other.a ||
b != other.b ||
c != other.c ||
d != other.d ||
e != other.e ||
f != other.f;
}
};
template<typename T>
struct StyleGenericMatrix3D {
T m11;
T m12;
T m13;
T m14;
T m21;
T m22;
T m23;
T m24;
T m31;
T m32;
T m33;
T m34;
T m41;
T m42;
T m43;
T m44;
bool operator==(const StyleGenericMatrix3D& other) const {
return m11 == other.m11 &&
m12 == other.m12 &&
m13 == other.m13 &&
m14 == other.m14 &&
m21 == other.m21 &&
m22 == other.m22 &&
m23 == other.m23 &&
m24 == other.m24 &&
m31 == other.m31 &&
m32 == other.m32 &&
m33 == other.m33 &&
m34 == other.m34 &&
m41 == other.m41 &&
m42 == other.m42 &&
m43 == other.m43 &&
m44 == other.m44;
}
bool operator!=(const StyleGenericMatrix3D& other) const {
return m11 != other.m11 ||
m12 != other.m12 ||
m13 != other.m13 ||
m14 != other.m14 ||
m21 != other.m21 ||
m22 != other.m22 ||
m23 != other.m23 ||
m24 != other.m24 ||
m31 != other.m31 ||
m32 != other.m32 ||
m33 != other.m33 ||
m34 != other.m34 ||
m41 != other.m41 ||
m42 != other.m42 ||
m43 != other.m43 ||
m44 != other.m44;
}
};
/// A value for the `perspective()` transform function, which is either a
/// non-negative `<length>` or `none`.
template<typename L>
struct StyleGenericPerspectiveFunction {
enum class Tag : uint8_t {
/// `none`
None,
/// A `<length>`.
Length,
};
struct StyleLength_Body {
L _0;
bool operator==(const StyleLength_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleLength_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StyleLength_Body length;
};
static StyleGenericPerspectiveFunction None() {
StyleGenericPerspectiveFunction result;
result.tag = Tag::None;
return result;
}
bool IsNone() const {
return tag == Tag::None;
}
static StyleGenericPerspectiveFunction Length(const L &_0) {
StyleGenericPerspectiveFunction result;
::new (&result.length._0) (L)(_0);
result.tag = Tag::Length;
return result;
}
bool IsLength() const {
return tag == Tag::Length;
}
const L& AsLength() const {
MOZ_DIAGNOSTIC_ASSERT(IsLength());
return length._0;
}
bool operator==(const StyleGenericPerspectiveFunction& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Length: return length == other.length;
default: break;
}
return true;
}
bool operator!=(const StyleGenericPerspectiveFunction& other) const {
return !(*this == other);
}
private:
StyleGenericPerspectiveFunction() {
}
public:
~StyleGenericPerspectiveFunction() {
switch (tag) {
case Tag::Length: length.~StyleLength_Body(); break;
default: break;
}
}
StyleGenericPerspectiveFunction(const StyleGenericPerspectiveFunction& other)
: tag(other.tag) {
switch (tag) {
case Tag::Length: ::new (&length) (StyleLength_Body)(other.length); break;
default: break;
}
}
StyleGenericPerspectiveFunction& operator=(const StyleGenericPerspectiveFunction& other) {
if (this != &other) {
this->~StyleGenericPerspectiveFunction();
new (this) StyleGenericPerspectiveFunction(other);
}
return *this;
}
};
/// A struct that basically replaces a `Box<[T]>`, but which cbindgen can
/// understand.
///
/// We could rely on the struct layout of `Box<[T]>` per:
///
/// https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md
///
/// But handling fat pointers with cbindgen both in structs and argument
/// positions more generally is a bit tricky.
///
template<typename T>
struct StyleOwnedSlice {
T *ptr;
uintptr_t len;
constexpr StyleOwnedSlice() :
ptr((T*)alignof(T)),
len(0) {}
inline void Clear();
inline void CopyFrom(const StyleOwnedSlice&);
inline void SwapElements(StyleOwnedSlice&);
StyleOwnedSlice& operator=(const StyleOwnedSlice&);
StyleOwnedSlice& operator=(StyleOwnedSlice&&);
inline StyleOwnedSlice(const StyleOwnedSlice&);
inline StyleOwnedSlice(StyleOwnedSlice&&);
inline explicit StyleOwnedSlice(Vector<T>&&);
inline ~StyleOwnedSlice();
Span<const T> AsSpan() const {
return {ptr, len};
}
size_t Length() const {
return len;
}
bool IsEmpty() const { return Length() == 0; }
bool operator==(const StyleOwnedSlice& other) const {
return AsSpan() == other.AsSpan();
}
bool operator!=(const StyleOwnedSlice& other) const {
return !(*this == other);
}
};
/// A value of the `transform` property
template<typename T>
struct StyleGenericTransform {
StyleOwnedSlice<T> _0;
bool operator==(const StyleGenericTransform& other) const {
return _0 == other._0;
}
bool operator!=(const StyleGenericTransform& other) const {
return _0 != other._0;
}
inline Span<const T> Operations() const;
inline bool IsNone() const;
bool HasPercent() const;
};
/// A single operation in the list of a `transform` value
template<typename Angle, typename Number, typename Length, typename Integer, typename LengthPercentage>
struct StyleGenericTransformOperation {
enum class Tag : uint8_t {
/// Represents a 2D 2x3 matrix.
Matrix,
/// Represents a 3D 4x4 matrix.
Matrix3D,
/// A 2D skew.
///
/// If the second angle is not provided it is assumed zero.
///
/// Syntax can be skew(angle) or skew(angle, angle)
Skew,
/// skewX(angle)
SkewX,
/// skewY(angle)
SkewY,
/// translate(x, y) or translate(x)
Translate,
/// translateX(x)
TranslateX,
/// translateY(y)
TranslateY,
/// translateZ(z)
TranslateZ,
/// translate3d(x, y, z)
Translate3D,
/// A 2D scaling factor.
///
/// Syntax can be scale(factor) or scale(factor, factor)
Scale,
/// scaleX(factor)
ScaleX,
/// scaleY(factor)
ScaleY,
/// scaleZ(factor)
ScaleZ,
/// scale3D(factorX, factorY, factorZ)
Scale3D,
/// Describes a 2D Rotation.
///
/// In a 3D scene `rotate(angle)` is equivalent to `rotateZ(angle)`.
Rotate,
/// Rotation in 3D space around the x-axis.
RotateX,
/// Rotation in 3D space around the y-axis.
RotateY,
/// Rotation in 3D space around the z-axis.
RotateZ,
/// Rotation in 3D space.
///
/// Generalization of rotateX, rotateY and rotateZ.
Rotate3D,
/// Specifies a perspective projection matrix.
///
/// Part of CSS Transform Module Level 2 and defined at
/// [§ 13.1. 3D Transform Function](https://drafts.csswg.org/css-transforms-2/#funcdef-perspective).
///
/// The value must be greater than or equal to zero.
Perspective,
/// A intermediate type for interpolation of mismatched transform lists.
InterpolateMatrix,
/// A intermediate type for accumulation of mismatched transform lists.
AccumulateMatrix,
};
struct StyleMatrix_Body {
StyleGenericMatrix<Number> _0;
bool operator==(const StyleMatrix_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleMatrix_Body& other) const {
return _0 != other._0;
}
};
struct StyleMatrix3D_Body {
StyleGenericMatrix3D<Number> _0;
bool operator==(const StyleMatrix3D_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleMatrix3D_Body& other) const {
return _0 != other._0;
}
};
struct StyleSkew_Body {
Angle _0;
Angle _1;
bool operator==(const StyleSkew_Body& other) const {
return _0 == other._0 &&
_1 == other._1;
}
bool operator!=(const StyleSkew_Body& other) const {
return _0 != other._0 ||
_1 != other._1;
}
};
struct StyleSkewX_Body {
Angle _0;
bool operator==(const StyleSkewX_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleSkewX_Body& other) const {
return _0 != other._0;
}
};
struct StyleSkewY_Body {
Angle _0;
bool operator==(const StyleSkewY_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleSkewY_Body& other) const {
return _0 != other._0;
}
};
struct StyleTranslate_Body {
LengthPercentage _0;
LengthPercentage _1;
bool operator==(const StyleTranslate_Body& other) const {
return _0 == other._0 &&
_1 == other._1;
}
bool operator!=(const StyleTranslate_Body& other) const {
return _0 != other._0 ||
_1 != other._1;
}
};
struct StyleTranslateX_Body {
LengthPercentage _0;
bool operator==(const StyleTranslateX_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleTranslateX_Body& other) const {
return _0 != other._0;
}
};
struct StyleTranslateY_Body {
LengthPercentage _0;
bool operator==(const StyleTranslateY_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleTranslateY_Body& other) const {
return _0 != other._0;
}
};
struct StyleTranslateZ_Body {
Length _0;
bool operator==(const StyleTranslateZ_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleTranslateZ_Body& other) const {
return _0 != other._0;
}
};
struct StyleTranslate3D_Body {
LengthPercentage _0;
LengthPercentage _1;
Length _2;
bool operator==(const StyleTranslate3D_Body& other) const {
return _0 == other._0 &&
_1 == other._1 &&
_2 == other._2;
}
bool operator!=(const StyleTranslate3D_Body& other) const {
return _0 != other._0 ||
_1 != other._1 ||
_2 != other._2;
}
};
struct StyleScale_Body {
Number _0;
Number _1;
bool operator==(const StyleScale_Body& other) const {
return _0 == other._0 &&
_1 == other._1;
}
bool operator!=(const StyleScale_Body& other) const {
return _0 != other._0 ||
_1 != other._1;
}
};
struct StyleScaleX_Body {
Number _0;
bool operator==(const StyleScaleX_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleScaleX_Body& other) const {
return _0 != other._0;
}
};
struct StyleScaleY_Body {
Number _0;
bool operator==(const StyleScaleY_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleScaleY_Body& other) const {
return _0 != other._0;
}
};
struct StyleScaleZ_Body {
Number _0;
bool operator==(const StyleScaleZ_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleScaleZ_Body& other) const {
return _0 != other._0;
}
};
struct StyleScale3D_Body {
Number _0;
Number _1;
Number _2;
bool operator==(const StyleScale3D_Body& other) const {
return _0 == other._0 &&
_1 == other._1 &&
_2 == other._2;
}
bool operator!=(const StyleScale3D_Body& other) const {
return _0 != other._0 ||
_1 != other._1 ||
_2 != other._2;
}
};
struct StyleRotate_Body {
Angle _0;
bool operator==(const StyleRotate_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleRotate_Body& other) const {
return _0 != other._0;
}
};
struct StyleRotateX_Body {
Angle _0;
bool operator==(const StyleRotateX_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleRotateX_Body& other) const {
return _0 != other._0;
}
};
struct StyleRotateY_Body {
Angle _0;
bool operator==(const StyleRotateY_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleRotateY_Body& other) const {
return _0 != other._0;
}
};
struct StyleRotateZ_Body {
Angle _0;
bool operator==(const StyleRotateZ_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleRotateZ_Body& other) const {
return _0 != other._0;
}
};
struct StyleRotate3D_Body {
Number _0;
Number _1;
Number _2;
Angle _3;
bool operator==(const StyleRotate3D_Body& other) const {
return _0 == other._0 &&
_1 == other._1 &&
_2 == other._2 &&
_3 == other._3;
}
bool operator!=(const StyleRotate3D_Body& other) const {
return _0 != other._0 ||
_1 != other._1 ||
_2 != other._2 ||
_3 != other._3;
}
};
struct StylePerspective_Body {
StyleGenericPerspectiveFunction<Length> _0;
bool operator==(const StylePerspective_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StylePerspective_Body& other) const {
return _0 != other._0;
}
};
struct StyleInterpolateMatrix_Body {
StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>> from_list;
StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>> to_list;
StylePercentage progress;
bool operator==(const StyleInterpolateMatrix_Body& other) const {
return from_list == other.from_list &&
to_list == other.to_list &&
progress == other.progress;
}
bool operator!=(const StyleInterpolateMatrix_Body& other) const {
return from_list != other.from_list ||
to_list != other.to_list ||
progress != other.progress;
}
};
struct StyleAccumulateMatrix_Body {
StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>> from_list;
StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>> to_list;
Integer count;
bool operator==(const StyleAccumulateMatrix_Body& other) const {
return from_list == other.from_list &&
to_list == other.to_list &&
count == other.count;
}
bool operator!=(const StyleAccumulateMatrix_Body& other) const {
return from_list != other.from_list ||
to_list != other.to_list ||
count != other.count;
}
};
Tag tag;
union {
StyleMatrix_Body matrix;
StyleMatrix3D_Body matrix3_d;
StyleSkew_Body skew;
StyleSkewX_Body skew_x;
StyleSkewY_Body skew_y;
StyleTranslate_Body translate;
StyleTranslateX_Body translate_x;
StyleTranslateY_Body translate_y;
StyleTranslateZ_Body translate_z;
StyleTranslate3D_Body translate3_d;
StyleScale_Body scale;
StyleScaleX_Body scale_x;
StyleScaleY_Body scale_y;
StyleScaleZ_Body scale_z;
StyleScale3D_Body scale3_d;
StyleRotate_Body rotate;
StyleRotateX_Body rotate_x;
StyleRotateY_Body rotate_y;
StyleRotateZ_Body rotate_z;
StyleRotate3D_Body rotate3_d;
StylePerspective_Body perspective;
StyleInterpolateMatrix_Body interpolate_matrix;
StyleAccumulateMatrix_Body accumulate_matrix;
};
static StyleGenericTransformOperation Matrix(const StyleGenericMatrix<Number> &_0) {
StyleGenericTransformOperation result;
::new (&result.matrix._0) (StyleGenericMatrix<Number>)(_0);
result.tag = Tag::Matrix;
return result;
}
bool IsMatrix() const {
return tag == Tag::Matrix;
}
const StyleGenericMatrix<Number>& AsMatrix() const {
MOZ_DIAGNOSTIC_ASSERT(IsMatrix());
return matrix._0;
}
static StyleGenericTransformOperation Matrix3D(const StyleGenericMatrix3D<Number> &_0) {
StyleGenericTransformOperation result;
::new (&result.matrix3_d._0) (StyleGenericMatrix3D<Number>)(_0);
result.tag = Tag::Matrix3D;
return result;
}
bool IsMatrix3D() const {
return tag == Tag::Matrix3D;
}
const StyleGenericMatrix3D<Number>& AsMatrix3D() const {
MOZ_DIAGNOSTIC_ASSERT(IsMatrix3D());
return matrix3_d._0;
}
static StyleGenericTransformOperation Skew(const Angle &_0,
const Angle &_1) {
StyleGenericTransformOperation result;
::new (&result.skew._0) (Angle)(_0);
::new (&result.skew._1) (Angle)(_1);
result.tag = Tag::Skew;
return result;
}
bool IsSkew() const {
return tag == Tag::Skew;
}
const StyleSkew_Body& AsSkew() const {
MOZ_DIAGNOSTIC_ASSERT(IsSkew());
return skew;
}
static StyleGenericTransformOperation SkewX(const Angle &_0) {
StyleGenericTransformOperation result;
::new (&result.skew_x._0) (Angle)(_0);
result.tag = Tag::SkewX;
return result;
}
bool IsSkewX() const {
return tag == Tag::SkewX;
}
const Angle& AsSkewX() const {
MOZ_DIAGNOSTIC_ASSERT(IsSkewX());
return skew_x._0;
}
static StyleGenericTransformOperation SkewY(const Angle &_0) {
StyleGenericTransformOperation result;
::new (&result.skew_y._0) (Angle)(_0);
result.tag = Tag::SkewY;
return result;
}
bool IsSkewY() const {
return tag == Tag::SkewY;
}
const Angle& AsSkewY() const {
MOZ_DIAGNOSTIC_ASSERT(IsSkewY());
return skew_y._0;
}
static StyleGenericTransformOperation Translate(const LengthPercentage &_0,
const LengthPercentage &_1) {
StyleGenericTransformOperation result;
::new (&result.translate._0) (LengthPercentage)(_0);
::new (&result.translate._1) (LengthPercentage)(_1);
result.tag = Tag::Translate;
return result;
}
bool IsTranslate() const {
return tag == Tag::Translate;
}
const StyleTranslate_Body& AsTranslate() const {
MOZ_DIAGNOSTIC_ASSERT(IsTranslate());
return translate;
}
static StyleGenericTransformOperation TranslateX(const LengthPercentage &_0) {
StyleGenericTransformOperation result;
::new (&result.translate_x._0) (LengthPercentage)(_0);
result.tag = Tag::TranslateX;
return result;
}
bool IsTranslateX() const {
return tag == Tag::TranslateX;
}
const LengthPercentage& AsTranslateX() const {
MOZ_DIAGNOSTIC_ASSERT(IsTranslateX());
return translate_x._0;
}
static StyleGenericTransformOperation TranslateY(const LengthPercentage &_0) {
StyleGenericTransformOperation result;
::new (&result.translate_y._0) (LengthPercentage)(_0);
result.tag = Tag::TranslateY;
return result;
}
bool IsTranslateY() const {
return tag == Tag::TranslateY;
}
const LengthPercentage& AsTranslateY() const {
MOZ_DIAGNOSTIC_ASSERT(IsTranslateY());
return translate_y._0;
}
static StyleGenericTransformOperation TranslateZ(const Length &_0) {
StyleGenericTransformOperation result;
::new (&result.translate_z._0) (Length)(_0);
result.tag = Tag::TranslateZ;
return result;
}
bool IsTranslateZ() const {
return tag == Tag::TranslateZ;
}
const Length& AsTranslateZ() const {
MOZ_DIAGNOSTIC_ASSERT(IsTranslateZ());
return translate_z._0;
}
static StyleGenericTransformOperation Translate3D(const LengthPercentage &_0,
const LengthPercentage &_1,
const Length &_2) {
StyleGenericTransformOperation result;
::new (&result.translate3_d._0) (LengthPercentage)(_0);
::new (&result.translate3_d._1) (LengthPercentage)(_1);
::new (&result.translate3_d._2) (Length)(_2);
result.tag = Tag::Translate3D;
return result;
}
bool IsTranslate3D() const {
return tag == Tag::Translate3D;
}
const StyleTranslate3D_Body& AsTranslate3D() const {
MOZ_DIAGNOSTIC_ASSERT(IsTranslate3D());
return translate3_d;
}
static StyleGenericTransformOperation Scale(const Number &_0,
const Number &_1) {
StyleGenericTransformOperation result;
::new (&result.scale._0) (Number)(_0);
::new (&result.scale._1) (Number)(_1);
result.tag = Tag::Scale;
return result;
}
bool IsScale() const {
return tag == Tag::Scale;
}
const StyleScale_Body& AsScale() const {
MOZ_DIAGNOSTIC_ASSERT(IsScale());
return scale;
}
static StyleGenericTransformOperation ScaleX(const Number &_0) {
StyleGenericTransformOperation result;
::new (&result.scale_x._0) (Number)(_0);
result.tag = Tag::ScaleX;
return result;
}
bool IsScaleX() const {
return tag == Tag::ScaleX;
}
const Number& AsScaleX() const {
MOZ_DIAGNOSTIC_ASSERT(IsScaleX());
return scale_x._0;
}
static StyleGenericTransformOperation ScaleY(const Number &_0) {
StyleGenericTransformOperation result;
::new (&result.scale_y._0) (Number)(_0);
result.tag = Tag::ScaleY;
return result;
}
bool IsScaleY() const {
return tag == Tag::ScaleY;
}
const Number& AsScaleY() const {
MOZ_DIAGNOSTIC_ASSERT(IsScaleY());
return scale_y._0;
}
static StyleGenericTransformOperation ScaleZ(const Number &_0) {
StyleGenericTransformOperation result;
::new (&result.scale_z._0) (Number)(_0);
result.tag = Tag::ScaleZ;
return result;
}
bool IsScaleZ() const {
return tag == Tag::ScaleZ;
}
const Number& AsScaleZ() const {
MOZ_DIAGNOSTIC_ASSERT(IsScaleZ());
return scale_z._0;
}
static StyleGenericTransformOperation Scale3D(const Number &_0,
const Number &_1,
const Number &_2) {
StyleGenericTransformOperation result;
::new (&result.scale3_d._0) (Number)(_0);
::new (&result.scale3_d._1) (Number)(_1);
::new (&result.scale3_d._2) (Number)(_2);
result.tag = Tag::Scale3D;
return result;
}
bool IsScale3D() const {
return tag == Tag::Scale3D;
}
const StyleScale3D_Body& AsScale3D() const {
MOZ_DIAGNOSTIC_ASSERT(IsScale3D());
return scale3_d;
}
static StyleGenericTransformOperation Rotate(const Angle &_0) {
StyleGenericTransformOperation result;
::new (&result.rotate._0) (Angle)(_0);
result.tag = Tag::Rotate;
return result;
}
bool IsRotate() const {
return tag == Tag::Rotate;
}
const Angle& AsRotate() const {
MOZ_DIAGNOSTIC_ASSERT(IsRotate());
return rotate._0;
}
static StyleGenericTransformOperation RotateX(const Angle &_0) {
StyleGenericTransformOperation result;
::new (&result.rotate_x._0) (Angle)(_0);
result.tag = Tag::RotateX;
return result;
}
bool IsRotateX() const {
return tag == Tag::RotateX;
}
const Angle& AsRotateX() const {
MOZ_DIAGNOSTIC_ASSERT(IsRotateX());
return rotate_x._0;
}
static StyleGenericTransformOperation RotateY(const Angle &_0) {
StyleGenericTransformOperation result;
::new (&result.rotate_y._0) (Angle)(_0);
result.tag = Tag::RotateY;
return result;
}
bool IsRotateY() const {
return tag == Tag::RotateY;
}
const Angle& AsRotateY() const {
MOZ_DIAGNOSTIC_ASSERT(IsRotateY());
return rotate_y._0;
}
static StyleGenericTransformOperation RotateZ(const Angle &_0) {
StyleGenericTransformOperation result;
::new (&result.rotate_z._0) (Angle)(_0);
result.tag = Tag::RotateZ;
return result;
}
bool IsRotateZ() const {
return tag == Tag::RotateZ;
}
const Angle& AsRotateZ() const {
MOZ_DIAGNOSTIC_ASSERT(IsRotateZ());
return rotate_z._0;
}
static StyleGenericTransformOperation Rotate3D(const Number &_0,
const Number &_1,
const Number &_2,
const Angle &_3) {
StyleGenericTransformOperation result;
::new (&result.rotate3_d._0) (Number)(_0);
::new (&result.rotate3_d._1) (Number)(_1);
::new (&result.rotate3_d._2) (Number)(_2);
::new (&result.rotate3_d._3) (Angle)(_3);
result.tag = Tag::Rotate3D;
return result;
}
bool IsRotate3D() const {
return tag == Tag::Rotate3D;
}
const StyleRotate3D_Body& AsRotate3D() const {
MOZ_DIAGNOSTIC_ASSERT(IsRotate3D());
return rotate3_d;
}
static StyleGenericTransformOperation Perspective(const StyleGenericPerspectiveFunction<Length> &_0) {
StyleGenericTransformOperation result;
::new (&result.perspective._0) (StyleGenericPerspectiveFunction<Length>)(_0);
result.tag = Tag::Perspective;
return result;
}
bool IsPerspective() const {
return tag == Tag::Perspective;
}
const StyleGenericPerspectiveFunction<Length>& AsPerspective() const {
MOZ_DIAGNOSTIC_ASSERT(IsPerspective());
return perspective._0;
}
static StyleGenericTransformOperation InterpolateMatrix(const StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>> &from_list,
const StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>> &to_list,
const StylePercentage &progress) {
StyleGenericTransformOperation result;
::new (&result.interpolate_matrix.from_list) (StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>>)(from_list);
::new (&result.interpolate_matrix.to_list) (StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>>)(to_list);
::new (&result.interpolate_matrix.progress) (StylePercentage)(progress);
result.tag = Tag::InterpolateMatrix;
return result;
}
bool IsInterpolateMatrix() const {
return tag == Tag::InterpolateMatrix;
}
const StyleInterpolateMatrix_Body& AsInterpolateMatrix() const {
MOZ_DIAGNOSTIC_ASSERT(IsInterpolateMatrix());
return interpolate_matrix;
}
static StyleGenericTransformOperation AccumulateMatrix(const StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>> &from_list,
const StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>> &to_list,
const Integer &count) {
StyleGenericTransformOperation result;
::new (&result.accumulate_matrix.from_list) (StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>>)(from_list);
::new (&result.accumulate_matrix.to_list) (StyleGenericTransform<StyleGenericTransformOperation<Angle, Number, Length, Integer, LengthPercentage>>)(to_list);
::new (&result.accumulate_matrix.count) (Integer)(count);
result.tag = Tag::AccumulateMatrix;
return result;
}
bool IsAccumulateMatrix() const {
return tag == Tag::AccumulateMatrix;
}
const StyleAccumulateMatrix_Body& AsAccumulateMatrix() const {
MOZ_DIAGNOSTIC_ASSERT(IsAccumulateMatrix());
return accumulate_matrix;
}
bool operator==(const StyleGenericTransformOperation& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Matrix: return matrix == other.matrix;
case Tag::Matrix3D: return matrix3_d == other.matrix3_d;
case Tag::Skew: return skew == other.skew;
case Tag::SkewX: return skew_x == other.skew_x;
case Tag::SkewY: return skew_y == other.skew_y;
case Tag::Translate: return translate == other.translate;
case Tag::TranslateX: return translate_x == other.translate_x;
case Tag::TranslateY: return translate_y == other.translate_y;
case Tag::TranslateZ: return translate_z == other.translate_z;
case Tag::Translate3D: return translate3_d == other.translate3_d;
case Tag::Scale: return scale == other.scale;
case Tag::ScaleX: return scale_x == other.scale_x;
case Tag::ScaleY: return scale_y == other.scale_y;
case Tag::ScaleZ: return scale_z == other.scale_z;
case Tag::Scale3D: return scale3_d == other.scale3_d;
case Tag::Rotate: return rotate == other.rotate;
case Tag::RotateX: return rotate_x == other.rotate_x;
case Tag::RotateY: return rotate_y == other.rotate_y;
case Tag::RotateZ: return rotate_z == other.rotate_z;
case Tag::Rotate3D: return rotate3_d == other.rotate3_d;
case Tag::Perspective: return perspective == other.perspective;
case Tag::InterpolateMatrix: return interpolate_matrix == other.interpolate_matrix;
case Tag::AccumulateMatrix: return accumulate_matrix == other.accumulate_matrix;
}
return true;
}
bool operator!=(const StyleGenericTransformOperation& other) const {
return !(*this == other);
}
private:
StyleGenericTransformOperation() {
}
public:
~StyleGenericTransformOperation() {
switch (tag) {
case Tag::Matrix: matrix.~StyleMatrix_Body(); break;
case Tag::Matrix3D: matrix3_d.~StyleMatrix3D_Body(); break;
case Tag::Skew: skew.~StyleSkew_Body(); break;
case Tag::SkewX: skew_x.~StyleSkewX_Body(); break;
case Tag::SkewY: skew_y.~StyleSkewY_Body(); break;
case Tag::Translate: translate.~StyleTranslate_Body(); break;
case Tag::TranslateX: translate_x.~StyleTranslateX_Body(); break;
case Tag::TranslateY: translate_y.~StyleTranslateY_Body(); break;
case Tag::TranslateZ: translate_z.~StyleTranslateZ_Body(); break;
case Tag::Translate3D: translate3_d.~StyleTranslate3D_Body(); break;
case Tag::Scale: scale.~StyleScale_Body(); break;
case Tag::ScaleX: scale_x.~StyleScaleX_Body(); break;
case Tag::ScaleY: scale_y.~StyleScaleY_Body(); break;
case Tag::ScaleZ: scale_z.~StyleScaleZ_Body(); break;
case Tag::Scale3D: scale3_d.~StyleScale3D_Body(); break;
case Tag::Rotate: rotate.~StyleRotate_Body(); break;
case Tag::RotateX: rotate_x.~StyleRotateX_Body(); break;
case Tag::RotateY: rotate_y.~StyleRotateY_Body(); break;
case Tag::RotateZ: rotate_z.~StyleRotateZ_Body(); break;
case Tag::Rotate3D: rotate3_d.~StyleRotate3D_Body(); break;
case Tag::Perspective: perspective.~StylePerspective_Body(); break;
case Tag::InterpolateMatrix: interpolate_matrix.~StyleInterpolateMatrix_Body(); break;
case Tag::AccumulateMatrix: accumulate_matrix.~StyleAccumulateMatrix_Body(); break;
}
}
StyleGenericTransformOperation(const StyleGenericTransformOperation& other)
: tag(other.tag) {
switch (tag) {
case Tag::Matrix: ::new (&matrix) (StyleMatrix_Body)(other.matrix); break;
case Tag::Matrix3D: ::new (&matrix3_d) (StyleMatrix3D_Body)(other.matrix3_d); break;
case Tag::Skew: ::new (&skew) (StyleSkew_Body)(other.skew); break;
case Tag::SkewX: ::new (&skew_x) (StyleSkewX_Body)(other.skew_x); break;
case Tag::SkewY: ::new (&skew_y) (StyleSkewY_Body)(other.skew_y); break;
case Tag::Translate: ::new (&translate) (StyleTranslate_Body)(other.translate); break;
case Tag::TranslateX: ::new (&translate_x) (StyleTranslateX_Body)(other.translate_x); break;
case Tag::TranslateY: ::new (&translate_y) (StyleTranslateY_Body)(other.translate_y); break;
case Tag::TranslateZ: ::new (&translate_z) (StyleTranslateZ_Body)(other.translate_z); break;
case Tag::Translate3D: ::new (&translate3_d) (StyleTranslate3D_Body)(other.translate3_d); break;
case Tag::Scale: ::new (&scale) (StyleScale_Body)(other.scale); break;
case Tag::ScaleX: ::new (&scale_x) (StyleScaleX_Body)(other.scale_x); break;
case Tag::ScaleY: ::new (&scale_y) (StyleScaleY_Body)(other.scale_y); break;
case Tag::ScaleZ: ::new (&scale_z) (StyleScaleZ_Body)(other.scale_z); break;
case Tag::Scale3D: ::new (&scale3_d) (StyleScale3D_Body)(other.scale3_d); break;
case Tag::Rotate: ::new (&rotate) (StyleRotate_Body)(other.rotate); break;
case Tag::RotateX: ::new (&rotate_x) (StyleRotateX_Body)(other.rotate_x); break;
case Tag::RotateY: ::new (&rotate_y) (StyleRotateY_Body)(other.rotate_y); break;
case Tag::RotateZ: ::new (&rotate_z) (StyleRotateZ_Body)(other.rotate_z); break;
case Tag::Rotate3D: ::new (&rotate3_d) (StyleRotate3D_Body)(other.rotate3_d); break;
case Tag::Perspective: ::new (&perspective) (StylePerspective_Body)(other.perspective); break;
case Tag::InterpolateMatrix: ::new (&interpolate_matrix) (StyleInterpolateMatrix_Body)(other.interpolate_matrix); break;
case Tag::AccumulateMatrix: ::new (&accumulate_matrix) (StyleAccumulateMatrix_Body)(other.accumulate_matrix); break;
}
}
StyleGenericTransformOperation& operator=(const StyleGenericTransformOperation& other) {
if (this != &other) {
this->~StyleGenericTransformOperation();
new (this) StyleGenericTransformOperation(other);
}
return *this;
}
};
/// A single operation in a computed CSS `transform`
using StyleTransformOperation = StyleGenericTransformOperation<StyleAngle, StyleNumber, StyleLength, StyleInteger, StyleLengthPercentage>;
/// A computed CSS `transform`
using StyleTransform = StyleGenericTransform<StyleTransformOperation>;
/// The computed value of a CSS horizontal position.
using StyleHorizontalPosition = StyleLengthPercentage;
/// The computed value of a CSS vertical position.
using StyleVerticalPosition = StyleLengthPercentage;
/// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position).
template<typename H, typename V>
struct StyleGenericPosition {
/// The horizontal component of position.
H horizontal;
/// The vertical component of position.
V vertical;
bool operator==(const StyleGenericPosition& other) const {
return horizontal == other.horizontal &&
vertical == other.vertical;
}
bool operator!=(const StyleGenericPosition& other) const {
return horizontal != other.horizontal ||
vertical != other.vertical;
}
inline bool HasPercent() const;
inline bool DependsOnPositioningAreaSize() const;
static inline StyleGenericPosition FromPercentage(float);
};
/// The computed value of a CSS `<position>`
using StylePosition = StyleGenericPosition<StyleHorizontalPosition, StyleVerticalPosition>;
/// A wrapper of Non-negative values.
template<typename T>
using StyleNonNegative = T;
/// A wrapper of LengthPercentage, whose value must be >= 0.
using StyleNonNegativeLengthPercentage = StyleNonNegative<StyleLengthPercentage>;
/// A CSS value made of four components, where its `ToCss` impl will try to
/// serialize as few components as possible, like for example in `border-width`.
template<typename T>
struct StyleRect {
T _0;
T _1;
T _2;
T _3;
bool operator==(const StyleRect& other) const {
return _0 == other._0 &&
_1 == other._1 &&
_2 == other._2 &&
_3 == other._3;
}
bool operator!=(const StyleRect& other) const {
return _0 != other._0 ||
_1 != other._1 ||
_2 != other._2 ||
_3 != other._3;
}
template<typename Predicate> inline bool All(Predicate) const;
template<typename Predicate> inline bool Any(Predicate) const;
// Defined in WritingModes.h
inline const T& Get(mozilla::Side) const;
inline const T& Get(LogicalSide, WritingMode) const;
inline const T& GetIStart(WritingMode) const;
inline const T& GetBStart(WritingMode) const;
inline const T& Start(LogicalAxis, WritingMode) const;
inline const T& GetIEnd(WritingMode) const;
inline const T& GetBEnd(WritingMode) const;
inline const T& End(LogicalAxis, WritingMode) const;
inline T& Get(mozilla::Side);
inline T& Get(LogicalSide, WritingMode);
inline T& GetIStart(WritingMode);
inline T& GetBStart(WritingMode);
inline T& GetIEnd(WritingMode);
inline T& GetBEnd(WritingMode);
static StyleRect WithAllSides(const T& aSide) {
return {aSide, aSide, aSide, aSide};
}
};
/// A generic size, for `border-*-radius` longhand properties, or
/// `border-spacing`.
template<typename L>
struct StyleSize2D {
L width;
L height;
bool operator==(const StyleSize2D& other) const {
return width == other.width &&
height == other.height;
}
bool operator!=(const StyleSize2D& other) const {
return width != other.width ||
height != other.height;
}
};
/// A generic value for the `border-*-radius` longhand properties.
template<typename L>
struct StyleGenericBorderCornerRadius {
StyleSize2D<L> _0;
bool operator==(const StyleGenericBorderCornerRadius& other) const {
return _0 == other._0;
}
bool operator!=(const StyleGenericBorderCornerRadius& other) const {
return _0 != other._0;
}
};
/// A generic value for `border-radius` and `inset()`.
///
template<typename LengthPercentage>
struct StyleGenericBorderRadius {
/// The top left radius.
StyleGenericBorderCornerRadius<LengthPercentage> top_left;
/// The top right radius.
StyleGenericBorderCornerRadius<LengthPercentage> top_right;
/// The bottom right radius.
StyleGenericBorderCornerRadius<LengthPercentage> bottom_right;
/// The bottom left radius.
StyleGenericBorderCornerRadius<LengthPercentage> bottom_left;
bool operator==(const StyleGenericBorderRadius& other) const {
return top_left == other.top_left &&
top_right == other.top_right &&
bottom_right == other.bottom_right &&
bottom_left == other.bottom_left;
}
bool operator!=(const StyleGenericBorderRadius& other) const {
return top_left != other.top_left ||
top_right != other.top_right ||
bottom_right != other.bottom_right ||
bottom_left != other.bottom_left;
}
inline const StyleLengthPercentage& Get(HalfCorner) const;
};
template<typename LengthPercentage, typename NonNegativeLengthPercentage>
struct StyleGenericInsetRect {
StyleRect<LengthPercentage> rect;
StyleGenericBorderRadius<NonNegativeLengthPercentage> round;
bool operator==(const StyleGenericInsetRect& other) const {
return rect == other.rect &&
round == other.round;
}
bool operator!=(const StyleGenericInsetRect& other) const {
return rect != other.rect ||
round != other.round;
}
};
/// The computed value of `inset()`.
using StyleInsetRect = StyleGenericInsetRect<StyleLengthPercentage, StyleNonNegativeLengthPercentage>;
/// A generic type for representing an `Auto | <position>`.
/// This is used by <offset-anchor> for now.
template<typename Pos>
struct StyleGenericPositionOrAuto {
enum class Tag : uint8_t {
/// The <position> value.
Position,
/// The keyword `auto`.
Auto,
};
struct StylePosition_Body {
Pos _0;
bool operator==(const StylePosition_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StylePosition_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StylePosition_Body position;
};
static StyleGenericPositionOrAuto Position(const Pos &_0) {
StyleGenericPositionOrAuto result;
::new (&result.position._0) (Pos)(_0);
result.tag = Tag::Position;
return result;
}
bool IsPosition() const {
return tag == Tag::Position;
}
const Pos& AsPosition() const {
MOZ_DIAGNOSTIC_ASSERT(IsPosition());
return position._0;
}
static StyleGenericPositionOrAuto Auto() {
StyleGenericPositionOrAuto result;
result.tag = Tag::Auto;
return result;
}
bool IsAuto() const {
return tag == Tag::Auto;
}
bool operator==(const StyleGenericPositionOrAuto& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Position: return position == other.position;
default: break;
}
return true;
}
bool operator!=(const StyleGenericPositionOrAuto& other) const {
return !(*this == other);
}
private:
StyleGenericPositionOrAuto() {
}
public:
~StyleGenericPositionOrAuto() {
switch (tag) {
case Tag::Position: position.~StylePosition_Body(); break;
default: break;
}
}
StyleGenericPositionOrAuto(const StyleGenericPositionOrAuto& other)
: tag(other.tag) {
switch (tag) {
case Tag::Position: ::new (&position) (StylePosition_Body)(other.position); break;
default: break;
}
}
StyleGenericPositionOrAuto& operator=(const StyleGenericPositionOrAuto& other) {
if (this != &other) {
this->~StyleGenericPositionOrAuto();
new (this) StyleGenericPositionOrAuto(other);
}
return *this;
}
};
template<typename NonNegativeLengthPercentage>
struct StyleGenericShapeRadius {
enum class Tag : uint8_t {
Length,
ClosestSide,
FarthestSide,
};
struct StyleLength_Body {
NonNegativeLengthPercentage _0;
bool operator==(const StyleLength_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleLength_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StyleLength_Body length;
};
static StyleGenericShapeRadius Length(const NonNegativeLengthPercentage &_0) {
StyleGenericShapeRadius result;
::new (&result.length._0) (NonNegativeLengthPercentage)(_0);
result.tag = Tag::Length;
return result;
}
bool IsLength() const {
return tag == Tag::Length;
}
const NonNegativeLengthPercentage& AsLength() const {
MOZ_DIAGNOSTIC_ASSERT(IsLength());
return length._0;
}
static StyleGenericShapeRadius ClosestSide() {
StyleGenericShapeRadius result;
result.tag = Tag::ClosestSide;
return result;
}
bool IsClosestSide() const {
return tag == Tag::ClosestSide;
}
static StyleGenericShapeRadius FarthestSide() {
StyleGenericShapeRadius result;
result.tag = Tag::FarthestSide;
return result;
}
bool IsFarthestSide() const {
return tag == Tag::FarthestSide;
}
bool operator==(const StyleGenericShapeRadius& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Length: return length == other.length;
default: break;
}
return true;
}
bool operator!=(const StyleGenericShapeRadius& other) const {
return !(*this == other);
}
private:
StyleGenericShapeRadius() {
}
public:
~StyleGenericShapeRadius() {
switch (tag) {
case Tag::Length: length.~StyleLength_Body(); break;
default: break;
}
}
StyleGenericShapeRadius(const StyleGenericShapeRadius& other)
: tag(other.tag) {
switch (tag) {
case Tag::Length: ::new (&length) (StyleLength_Body)(other.length); break;
default: break;
}
}
StyleGenericShapeRadius& operator=(const StyleGenericShapeRadius& other) {
if (this != &other) {
this->~StyleGenericShapeRadius();
new (this) StyleGenericShapeRadius(other);
}
return *this;
}
};
template<typename Position, typename NonNegativeLengthPercentage>
struct StyleCircle {
StyleGenericPositionOrAuto<Position> position;
StyleGenericShapeRadius<NonNegativeLengthPercentage> radius;
bool operator==(const StyleCircle& other) const {
return position == other.position &&
radius == other.radius;
}
bool operator!=(const StyleCircle& other) const {
return position != other.position ||
radius != other.radius;
}
};
template<typename Position, typename NonNegativeLengthPercentage>
struct StyleEllipse {
StyleGenericPositionOrAuto<Position> position;
StyleGenericShapeRadius<NonNegativeLengthPercentage> semiaxis_x;
StyleGenericShapeRadius<NonNegativeLengthPercentage> semiaxis_y;
bool operator==(const StyleEllipse& other) const {
return position == other.position &&
semiaxis_x == other.semiaxis_x &&
semiaxis_y == other.semiaxis_y;
}
bool operator!=(const StyleEllipse& other) const {
return position != other.position ||
semiaxis_x != other.semiaxis_x ||
semiaxis_y != other.semiaxis_y;
}
};
/// Coordinates for Polygon.
template<typename LengthPercentage>
struct StylePolygonCoord {
LengthPercentage _0;
LengthPercentage _1;
bool operator==(const StylePolygonCoord& other) const {
return _0 == other._0 &&
_1 == other._1;
}
bool operator!=(const StylePolygonCoord& other) const {
return _0 != other._0 ||
_1 != other._1;
}
};
/// A generic type for representing the `polygon()` function
///
template<typename LengthPercentage>
struct StyleGenericPolygon {
/// The filling rule for a polygon.
StyleFillRule fill;
/// A collection of (x, y) coordinates to draw the polygon.
StyleOwnedSlice<StylePolygonCoord<LengthPercentage>> coordinates;
bool operator==(const StyleGenericPolygon& other) const {
return fill == other.fill &&
coordinates == other.coordinates;
}
bool operator!=(const StyleGenericPolygon& other) const {
return fill != other.fill ||
coordinates != other.coordinates;
}
};
/// Defines a pair of coordinates, representing a rightward and downward offset, respectively, from
/// a specified reference point. Percentages are resolved against the width or height,
/// respectively, of the reference box.
template<typename LengthPercentage>
struct StyleCoordinatePair {
LengthPercentage x;
LengthPercentage y;
bool operator==(const StyleCoordinatePair& other) const {
return x == other.x &&
y == other.y;
}
bool operator!=(const StyleCoordinatePair& other) const {
return x != other.x ||
y != other.y;
}
inline gfx::Point ToGfxPoint(const CSSSize* aBasis = nullptr) const;
gfx::Point ToGfxPoint(const CSSSize& aBasis) const {
return ToGfxPoint(&aBasis);
};
};
/// This is a more general shape(path) command type, for both shape() and path().
///
template<typename Angle, typename LengthPercentage>
struct StyleGenericShapeCommand {
enum class Tag : uint8_t {
/// The move command.
Move,
/// The line command.
Line,
/// The hline command.
HLine,
/// The vline command.
VLine,
/// The cubic Bézier curve command.
CubicCurve,
/// The quadratic Bézier curve command.
QuadCurve,
/// The smooth command.
SmoothCubic,
/// The smooth quadratic Bézier curve command.
SmoothQuad,
/// The arc command.
Arc,
/// The closepath command.
Close,
};
struct StyleMove_Body {
StyleByTo by_to;
StyleCoordinatePair<LengthPercentage> point;
bool operator==(const StyleMove_Body& other) const {
return by_to == other.by_to &&
point == other.point;
}
bool operator!=(const StyleMove_Body& other) const {
return by_to != other.by_to ||
point != other.point;
}
};
struct StyleLine_Body {
StyleByTo by_to;
StyleCoordinatePair<LengthPercentage> point;
bool operator==(const StyleLine_Body& other) const {
return by_to == other.by_to &&
point == other.point;
}
bool operator!=(const StyleLine_Body& other) const {
return by_to != other.by_to ||
point != other.point;
}
};
struct StyleHLine_Body {
StyleByTo by_to;
LengthPercentage x;
bool operator==(const StyleHLine_Body& other) const {
return by_to == other.by_to &&
x == other.x;
}
bool operator!=(const StyleHLine_Body& other) const {
return by_to != other.by_to ||
x != other.x;
}
};
struct StyleVLine_Body {
StyleByTo by_to;
LengthPercentage y;
bool operator==(const StyleVLine_Body& other) const {
return by_to == other.by_to &&
y == other.y;
}
bool operator!=(const StyleVLine_Body& other) const {
return by_to != other.by_to ||
y != other.y;
}
};
struct StyleCubicCurve_Body {
StyleByTo by_to;
StyleCoordinatePair<LengthPercentage> point;
StyleCoordinatePair<LengthPercentage> control1;
StyleCoordinatePair<LengthPercentage> control2;
bool operator==(const StyleCubicCurve_Body& other) const {
return by_to == other.by_to &&
point == other.point &&
control1 == other.control1 &&
control2 == other.control2;
}
bool operator!=(const StyleCubicCurve_Body& other) const {
return by_to != other.by_to ||
point != other.point ||
control1 != other.control1 ||
control2 != other.control2;
}
};
struct StyleQuadCurve_Body {
StyleByTo by_to;
StyleCoordinatePair<LengthPercentage> point;
StyleCoordinatePair<LengthPercentage> control1;
bool operator==(const StyleQuadCurve_Body& other) const {
return by_to == other.by_to &&
point == other.point &&
control1 == other.control1;
}
bool operator!=(const StyleQuadCurve_Body& other) const {
return by_to != other.by_to ||
point != other.point ||
control1 != other.control1;
}
};
struct StyleSmoothCubic_Body {
StyleByTo by_to;
StyleCoordinatePair<LengthPercentage> point;
StyleCoordinatePair<LengthPercentage> control2;
bool operator==(const StyleSmoothCubic_Body& other) const {
return by_to == other.by_to &&
point == other.point &&
control2 == other.control2;
}
bool operator!=(const StyleSmoothCubic_Body& other) const {
return by_to != other.by_to ||
point != other.point ||
control2 != other.control2;
}
};
struct StyleSmoothQuad_Body {
StyleByTo by_to;
StyleCoordinatePair<LengthPercentage> point;
bool operator==(const StyleSmoothQuad_Body& other) const {
return by_to == other.by_to &&
point == other.point;
}
bool operator!=(const StyleSmoothQuad_Body& other) const {
return by_to != other.by_to ||
point != other.point;
}
};
struct StyleArc_Body {
StyleByTo by_to;
StyleCoordinatePair<LengthPercentage> point;
StyleCoordinatePair<LengthPercentage> radii;
StyleArcSweep arc_sweep;
StyleArcSize arc_size;
Angle rotate;
bool operator==(const StyleArc_Body& other) const {
return by_to == other.by_to &&
point == other.point &&
radii == other.radii &&
arc_sweep == other.arc_sweep &&
arc_size == other.arc_size &&
rotate == other.rotate;
}
bool operator!=(const StyleArc_Body& other) const {
return by_to != other.by_to ||
point != other.point ||
radii != other.radii ||
arc_sweep != other.arc_sweep ||
arc_size != other.arc_size ||
rotate != other.rotate;
}
};
Tag tag;
union {
StyleMove_Body move;
StyleLine_Body line;
StyleHLine_Body h_line;
StyleVLine_Body v_line;
StyleCubicCurve_Body cubic_curve;
StyleQuadCurve_Body quad_curve;
StyleSmoothCubic_Body smooth_cubic;
StyleSmoothQuad_Body smooth_quad;
StyleArc_Body arc;
};
static StyleGenericShapeCommand Move(const StyleByTo &by_to,
const StyleCoordinatePair<LengthPercentage> &point) {
StyleGenericShapeCommand result;
::new (&result.move.by_to) (StyleByTo)(by_to);
::new (&result.move.point) (StyleCoordinatePair<LengthPercentage>)(point);
result.tag = Tag::Move;
return result;
}
bool IsMove() const {
return tag == Tag::Move;
}
const StyleMove_Body& AsMove() const {
MOZ_DIAGNOSTIC_ASSERT(IsMove());
return move;
}
static StyleGenericShapeCommand Line(const StyleByTo &by_to,
const StyleCoordinatePair<LengthPercentage> &point) {
StyleGenericShapeCommand result;
::new (&result.line.by_to) (StyleByTo)(by_to);
::new (&result.line.point) (StyleCoordinatePair<LengthPercentage>)(point);
result.tag = Tag::Line;
return result;
}
bool IsLine() const {
return tag == Tag::Line;
}
const StyleLine_Body& AsLine() const {
MOZ_DIAGNOSTIC_ASSERT(IsLine());
return line;
}
static StyleGenericShapeCommand HLine(const StyleByTo &by_to,
const LengthPercentage &x) {
StyleGenericShapeCommand result;
::new (&result.h_line.by_to) (StyleByTo)(by_to);
::new (&result.h_line.x) (LengthPercentage)(x);
result.tag = Tag::HLine;
return result;
}
bool IsHLine() const {
return tag == Tag::HLine;
}
const StyleHLine_Body& AsHLine() const {
MOZ_DIAGNOSTIC_ASSERT(IsHLine());
return h_line;
}
static StyleGenericShapeCommand VLine(const StyleByTo &by_to,
const LengthPercentage &y) {
StyleGenericShapeCommand result;
::new (&result.v_line.by_to) (StyleByTo)(by_to);
::new (&result.v_line.y) (LengthPercentage)(y);
result.tag = Tag::VLine;
return result;
}
bool IsVLine() const {
return tag == Tag::VLine;
}
const StyleVLine_Body& AsVLine() const {
MOZ_DIAGNOSTIC_ASSERT(IsVLine());
return v_line;
}
static StyleGenericShapeCommand CubicCurve(const StyleByTo &by_to,
const StyleCoordinatePair<LengthPercentage> &point,
const StyleCoordinatePair<LengthPercentage> &control1,
const StyleCoordinatePair<LengthPercentage> &control2) {
StyleGenericShapeCommand result;
::new (&result.cubic_curve.by_to) (StyleByTo)(by_to);
::new (&result.cubic_curve.point) (StyleCoordinatePair<LengthPercentage>)(point);
::new (&result.cubic_curve.control1) (StyleCoordinatePair<LengthPercentage>)(control1);
::new (&result.cubic_curve.control2) (StyleCoordinatePair<LengthPercentage>)(control2);
result.tag = Tag::CubicCurve;
return result;
}
bool IsCubicCurve() const {
return tag == Tag::CubicCurve;
}
const StyleCubicCurve_Body& AsCubicCurve() const {
MOZ_DIAGNOSTIC_ASSERT(IsCubicCurve());
return cubic_curve;
}
static StyleGenericShapeCommand QuadCurve(const StyleByTo &by_to,
const StyleCoordinatePair<LengthPercentage> &point,
const StyleCoordinatePair<LengthPercentage> &control1) {
StyleGenericShapeCommand result;
::new (&result.quad_curve.by_to) (StyleByTo)(by_to);
::new (&result.quad_curve.point) (StyleCoordinatePair<LengthPercentage>)(point);
::new (&result.quad_curve.control1) (StyleCoordinatePair<LengthPercentage>)(control1);
result.tag = Tag::QuadCurve;
return result;
}
bool IsQuadCurve() const {
return tag == Tag::QuadCurve;
}
const StyleQuadCurve_Body& AsQuadCurve() const {
MOZ_DIAGNOSTIC_ASSERT(IsQuadCurve());
return quad_curve;
}
static StyleGenericShapeCommand SmoothCubic(const StyleByTo &by_to,
const StyleCoordinatePair<LengthPercentage> &point,
const StyleCoordinatePair<LengthPercentage> &control2) {
StyleGenericShapeCommand result;
::new (&result.smooth_cubic.by_to) (StyleByTo)(by_to);
::new (&result.smooth_cubic.point) (StyleCoordinatePair<LengthPercentage>)(point);
::new (&result.smooth_cubic.control2) (StyleCoordinatePair<LengthPercentage>)(control2);
result.tag = Tag::SmoothCubic;
return result;
}
bool IsSmoothCubic() const {
return tag == Tag::SmoothCubic;
}
const StyleSmoothCubic_Body& AsSmoothCubic() const {
MOZ_DIAGNOSTIC_ASSERT(IsSmoothCubic());
return smooth_cubic;
}
static StyleGenericShapeCommand SmoothQuad(const StyleByTo &by_to,
const StyleCoordinatePair<LengthPercentage> &point) {
StyleGenericShapeCommand result;
::new (&result.smooth_quad.by_to) (StyleByTo)(by_to);
::new (&result.smooth_quad.point) (StyleCoordinatePair<LengthPercentage>)(point);
result.tag = Tag::SmoothQuad;
return result;
}
bool IsSmoothQuad() const {
return tag == Tag::SmoothQuad;
}
const StyleSmoothQuad_Body& AsSmoothQuad() const {
MOZ_DIAGNOSTIC_ASSERT(IsSmoothQuad());
return smooth_quad;
}
static StyleGenericShapeCommand Arc(const StyleByTo &by_to,
const StyleCoordinatePair<LengthPercentage> &point,
const StyleCoordinatePair<LengthPercentage> &radii,
const StyleArcSweep &arc_sweep,
const StyleArcSize &arc_size,
const Angle &rotate) {
StyleGenericShapeCommand result;
::new (&result.arc.by_to) (StyleByTo)(by_to);
::new (&result.arc.point) (StyleCoordinatePair<LengthPercentage>)(point);
::new (&result.arc.radii) (StyleCoordinatePair<LengthPercentage>)(radii);
::new (&result.arc.arc_sweep) (StyleArcSweep)(arc_sweep);
::new (&result.arc.arc_size) (StyleArcSize)(arc_size);
::new (&result.arc.rotate) (Angle)(rotate);
result.tag = Tag::Arc;
return result;
}
bool IsArc() const {
return tag == Tag::Arc;
}
const StyleArc_Body& AsArc() const {
MOZ_DIAGNOSTIC_ASSERT(IsArc());
return arc;
}
static StyleGenericShapeCommand Close() {
StyleGenericShapeCommand result;
result.tag = Tag::Close;
return result;
}
bool IsClose() const {
return tag == Tag::Close;
}
bool operator==(const StyleGenericShapeCommand& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Move: return move == other.move;
case Tag::Line: return line == other.line;
case Tag::HLine: return h_line == other.h_line;
case Tag::VLine: return v_line == other.v_line;
case Tag::CubicCurve: return cubic_curve == other.cubic_curve;
case Tag::QuadCurve: return quad_curve == other.quad_curve;
case Tag::SmoothCubic: return smooth_cubic == other.smooth_cubic;
case Tag::SmoothQuad: return smooth_quad == other.smooth_quad;
case Tag::Arc: return arc == other.arc;
default: break;
}
return true;
}
bool operator!=(const StyleGenericShapeCommand& other) const {
return !(*this == other);
}
private:
StyleGenericShapeCommand() {
}
public:
~StyleGenericShapeCommand() {
switch (tag) {
case Tag::Move: move.~StyleMove_Body(); break;
case Tag::Line: line.~StyleLine_Body(); break;
case Tag::HLine: h_line.~StyleHLine_Body(); break;
case Tag::VLine: v_line.~StyleVLine_Body(); break;
case Tag::CubicCurve: cubic_curve.~StyleCubicCurve_Body(); break;
case Tag::QuadCurve: quad_curve.~StyleQuadCurve_Body(); break;
case Tag::SmoothCubic: smooth_cubic.~StyleSmoothCubic_Body(); break;
case Tag::SmoothQuad: smooth_quad.~StyleSmoothQuad_Body(); break;
case Tag::Arc: arc.~StyleArc_Body(); break;
default: break;
}
}
StyleGenericShapeCommand(const StyleGenericShapeCommand& other)
: tag(other.tag) {
switch (tag) {
case Tag::Move: ::new (&move) (StyleMove_Body)(other.move); break;
case Tag::Line: ::new (&line) (StyleLine_Body)(other.line); break;
case Tag::HLine: ::new (&h_line) (StyleHLine_Body)(other.h_line); break;
case Tag::VLine: ::new (&v_line) (StyleVLine_Body)(other.v_line); break;
case Tag::CubicCurve: ::new (&cubic_curve) (StyleCubicCurve_Body)(other.cubic_curve); break;
case Tag::QuadCurve: ::new (&quad_curve) (StyleQuadCurve_Body)(other.quad_curve); break;
case Tag::SmoothCubic: ::new (&smooth_cubic) (StyleSmoothCubic_Body)(other.smooth_cubic); break;
case Tag::SmoothQuad: ::new (&smooth_quad) (StyleSmoothQuad_Body)(other.smooth_quad); break;
case Tag::Arc: ::new (&arc) (StyleArc_Body)(other.arc); break;
default: break;
}
}
StyleGenericShapeCommand& operator=(const StyleGenericShapeCommand& other) {
if (this != &other) {
this->~StyleGenericShapeCommand();
new (this) StyleGenericShapeCommand(other);
}
return *this;
}
bool IsCubicType() const { return IsCubicCurve() || IsSmoothCubic(); }
bool IsQuadraticType() const { return IsQuadCurve() || IsSmoothQuad(); }
};
/// The SVG path command.
/// The fields of these commands are self-explanatory, so we skip the documents.
/// Note: the index of the control points, e.g. control1, control2, are mapping to the control
/// points of the Bézier curve in the spec.
///
using StylePathCommand = StyleGenericShapeCommand<StyleCSSFloat, StyleCSSFloat>;
/// Structure to allow Arc-managing some fixed-sized data and a variably-sized
/// slice in a single allocation.
///
template<typename H, typename T>
struct StyleHeaderSlice {
/// The fixed-sized data.
H header;
/// The length of the slice at our end.
uintptr_t len;
/// The dynamically-sized data.
T data[0];
StyleHeaderSlice() = delete;
StyleHeaderSlice(const StyleHeaderSlice&) = delete;
inline ~StyleHeaderSlice();
inline bool operator==(const StyleHeaderSlice& other) const;
inline bool operator!=(const StyleHeaderSlice& other) const;
inline Span<const T> AsSpan() const;
inline size_t Length() const { return len; }
inline bool IsEmpty() const { return len == 0; }
};
/// The object allocated by an Arc<T>
///
/// use those anyways so we can just disable them.
template<typename T>
struct StyleArcInner {
StyleAtomicUsize count;
#if defined(CBINDGEN_IS_SERVO)
uintptr_t alloc_size
#endif
;
T data;
// Increase the reference count.
inline void IncrementRef();
// Release the reference count, and return whether the result must be freed or not.
[[nodiscard]] inline bool DecrementRef();
};
/// An atomically reference counted shared pointer
///
/// See the documentation for [`Arc`] in the standard library. Unlike the
/// standard library `Arc`, this `Arc` does not support weak reference counting.
///
/// usage of PhantomData.
///
///
template<typename T>
struct StyleArc {
StyleArcInner<T> *p;
StyleArc() = delete;
inline StyleArc(const StyleArc& Other);
private:
inline void Release();
public:
explicit StyleArc(decltype(p) aP) : p(aP) {
MOZ_DIAGNOSTIC_ASSERT(p, "Arc shouldn't be null");
}
inline ~StyleArc();
inline StyleArc& operator=(const StyleArc&);
inline StyleArc& operator=(StyleArc&&);
const T* operator->() const {
MOZ_DIAGNOSTIC_ASSERT(p, "Arc shouldn't be null");
return &p->data;
}
const T& operator*() const {
MOZ_DIAGNOSTIC_ASSERT(p, "Arc shouldn't be null");
return p->data;
}
bool operator==(const StyleArc& other) const {
return p == other.p || *(*this) == *other;
}
bool operator!=(const StyleArc& other) const {
return !(*this == other);
}
};
/// This is functionally equivalent to Arc<(H, [T])>
///
/// When you create an `Arc` containing a dynamically sized type like a slice, the `Arc` is
/// represented on the stack as a "fat pointer", where the length of the slice is stored alongside
/// the `Arc`'s pointer. In some situations you may wish to have a thin pointer instead, perhaps
/// for FFI compatibility or space efficiency. `ThinArc` solves this by storing the length in the
/// allocation itself, via `HeaderSlice`.
template<typename H, typename T>
using StyleThinArc = StyleArc<StyleHeaderSlice<H, T>>;
/// A wrapper type for a refcounted slice using ThinArc.
template<typename T>
struct StyleArcSlice {
StyleThinArc<uint64_t, T> _0;
bool operator==(const StyleArcSlice& other) const {
return _0 == other._0;
}
bool operator!=(const StyleArcSlice& other) const {
return _0 != other._0;
}
inline StyleArcSlice();
inline explicit StyleArcSlice(const StyleForgottenArcSlicePtr<T>& aPtr);
inline Span<const T> AsSpan() const;
inline size_t Length() const;
inline bool IsEmpty() const;
};
/// The SVG path data.
///
struct StyleSVGPathData {
StyleArcSlice<StylePathCommand> _0;
bool operator==(const StyleSVGPathData& other) const {
return _0 == other._0;
}
bool operator!=(const StyleSVGPathData& other) const {
return _0 != other._0;
}
};
/// The path function.
///
struct StylePath {
/// The filling rule for the svg path.
StyleFillRule fill;
/// The svg path data.
StyleSVGPathData path;
bool operator==(const StylePath& other) const {
return fill == other.fill &&
path == other.path;
}
bool operator!=(const StylePath& other) const {
return fill != other.fill ||
path != other.path;
}
};
/// The shape function defined in css-shape-2.
/// shape() = shape(<fill-rule>? from <coordinate-pair>, <shape-command>#)
///
template<typename Angle, typename LengthPercentage>
struct StyleShape {
/// The filling rule for this shape.
StyleFillRule fill;
/// The shape command data. Note that the starting point will be the first command in this
/// slice.
StyleOwnedSlice<StyleGenericShapeCommand<Angle, LengthPercentage>> commands;
bool operator==(const StyleShape& other) const {
return fill == other.fill &&
commands == other.commands;
}
bool operator!=(const StyleShape& other) const {
return fill != other.fill ||
commands != other.commands;
}
};
/// path() function or shape() function.
template<typename Angle, typename LengthPercentage>
struct StyleGenericPathOrShapeFunction {
enum class Tag : uint8_t {
/// Defines a path with SVG path syntax.
Path,
/// Defines a shape function, which is identical to path() but it uses the CSS syntax.
Shape,
};
struct StylePath_Body {
StylePath _0;
bool operator==(const StylePath_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StylePath_Body& other) const {
return _0 != other._0;
}
};
struct StyleShape_Body {
StyleShape<Angle, LengthPercentage> _0;
bool operator==(const StyleShape_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleShape_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StylePath_Body path;
StyleShape_Body shape;
};
static StyleGenericPathOrShapeFunction Path(const StylePath &_0) {
StyleGenericPathOrShapeFunction result;
::new (&result.path._0) (StylePath)(_0);
result.tag = Tag::Path;
return result;
}
bool IsPath() const {
return tag == Tag::Path;
}
const StylePath& AsPath() const {
MOZ_DIAGNOSTIC_ASSERT(IsPath());
return path._0;
}
static StyleGenericPathOrShapeFunction Shape(const StyleShape<Angle, LengthPercentage> &_0) {
StyleGenericPathOrShapeFunction result;
::new (&result.shape._0) (StyleShape<Angle, LengthPercentage>)(_0);
result.tag = Tag::Shape;
return result;
}
bool IsShape() const {
return tag == Tag::Shape;
}
const StyleShape<Angle, LengthPercentage>& AsShape() const {
MOZ_DIAGNOSTIC_ASSERT(IsShape());
return shape._0;
}
bool operator==(const StyleGenericPathOrShapeFunction& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Path: return path == other.path;
case Tag::Shape: return shape == other.shape;
}
return true;
}
bool operator!=(const StyleGenericPathOrShapeFunction& other) const {
return !(*this == other);
}
private:
StyleGenericPathOrShapeFunction() {
}
public:
~StyleGenericPathOrShapeFunction() {
switch (tag) {
case Tag::Path: path.~StylePath_Body(); break;
case Tag::Shape: shape.~StyleShape_Body(); break;
}
}
StyleGenericPathOrShapeFunction(const StyleGenericPathOrShapeFunction& other)
: tag(other.tag) {
switch (tag) {
case Tag::Path: ::new (&path) (StylePath_Body)(other.path); break;
case Tag::Shape: ::new (&shape) (StyleShape_Body)(other.shape); break;
}
}
StyleGenericPathOrShapeFunction& operator=(const StyleGenericPathOrShapeFunction& other) {
if (this != &other) {
this->~StyleGenericPathOrShapeFunction();
new (this) StyleGenericPathOrShapeFunction(other);
}
return *this;
}
};
/// The <basic-shape>.
///
template<typename Angle, typename Position, typename LengthPercentage, typename NonNegativeLengthPercentage, typename BasicShapeRect>
struct StyleGenericBasicShape {
enum class Tag : uint8_t {
/// The <basic-shape-rect>.
Rect,
/// Defines a circle with a center and a radius.
Circle,
/// Defines an ellipse with a center and x-axis/y-axis radii.
Ellipse,
/// Defines a polygon with pair arguments.
Polygon,
/// Defines a path() or shape().
PathOrShape,
};
struct StyleRect_Body {
BasicShapeRect _0;
bool operator==(const StyleRect_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleRect_Body& other) const {
return _0 != other._0;
}
};
struct StyleCircle_Body {
StyleCircle<Position, NonNegativeLengthPercentage> _0;
bool operator==(const StyleCircle_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleCircle_Body& other) const {
return _0 != other._0;
}
};
struct StyleEllipse_Body {
StyleEllipse<Position, NonNegativeLengthPercentage> _0;
bool operator==(const StyleEllipse_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleEllipse_Body& other) const {
return _0 != other._0;
}
};
struct StylePolygon_Body {
StyleGenericPolygon<LengthPercentage> _0;
bool operator==(const StylePolygon_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StylePolygon_Body& other) const {
return _0 != other._0;
}
};
struct StylePathOrShape_Body {
StyleGenericPathOrShapeFunction<Angle, LengthPercentage> _0;
bool operator==(const StylePathOrShape_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StylePathOrShape_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StyleRect_Body rect;
StyleCircle_Body circle;
StyleEllipse_Body ellipse;
StylePolygon_Body polygon;
StylePathOrShape_Body path_or_shape;
};
static StyleGenericBasicShape Rect(const BasicShapeRect &_0) {
StyleGenericBasicShape result;
::new (&result.rect._0) (BasicShapeRect)(_0);
result.tag = Tag::Rect;
return result;
}
bool IsRect() const {
return tag == Tag::Rect;
}
const BasicShapeRect& AsRect() const {
MOZ_DIAGNOSTIC_ASSERT(IsRect());
return rect._0;
}
static StyleGenericBasicShape Circle(const StyleCircle<Position, NonNegativeLengthPercentage> &_0) {
StyleGenericBasicShape result;
::new (&result.circle._0) (StyleCircle<Position, NonNegativeLengthPercentage>)(_0);
result.tag = Tag::Circle;
return result;
}
bool IsCircle() const {
return tag == Tag::Circle;
}
const StyleCircle<Position, NonNegativeLengthPercentage>& AsCircle() const {
MOZ_DIAGNOSTIC_ASSERT(IsCircle());
return circle._0;
}
static StyleGenericBasicShape Ellipse(const StyleEllipse<Position, NonNegativeLengthPercentage> &_0) {
StyleGenericBasicShape result;
::new (&result.ellipse._0) (StyleEllipse<Position, NonNegativeLengthPercentage>)(_0);
result.tag = Tag::Ellipse;
return result;
}
bool IsEllipse() const {
return tag == Tag::Ellipse;
}
const StyleEllipse<Position, NonNegativeLengthPercentage>& AsEllipse() const {
MOZ_DIAGNOSTIC_ASSERT(IsEllipse());
return ellipse._0;
}
static StyleGenericBasicShape Polygon(const StyleGenericPolygon<LengthPercentage> &_0) {
StyleGenericBasicShape result;
::new (&result.polygon._0) (StyleGenericPolygon<LengthPercentage>)(_0);
result.tag = Tag::Polygon;
return result;
}
bool IsPolygon() const {
return tag == Tag::Polygon;
}
const StyleGenericPolygon<LengthPercentage>& AsPolygon() const {
MOZ_DIAGNOSTIC_ASSERT(IsPolygon());
return polygon._0;
}
static StyleGenericBasicShape PathOrShape(const StyleGenericPathOrShapeFunction<Angle, LengthPercentage> &_0) {
StyleGenericBasicShape result;
::new (&result.path_or_shape._0) (StyleGenericPathOrShapeFunction<Angle, LengthPercentage>)(_0);
result.tag = Tag::PathOrShape;
return result;
}
bool IsPathOrShape() const {
return tag == Tag::PathOrShape;
}
const StyleGenericPathOrShapeFunction<Angle, LengthPercentage>& AsPathOrShape() const {
MOZ_DIAGNOSTIC_ASSERT(IsPathOrShape());
return path_or_shape._0;
}
bool operator==(const StyleGenericBasicShape& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Rect: return rect == other.rect;
case Tag::Circle: return circle == other.circle;
case Tag::Ellipse: return ellipse == other.ellipse;
case Tag::Polygon: return polygon == other.polygon;
case Tag::PathOrShape: return path_or_shape == other.path_or_shape;
}
return true;
}
bool operator!=(const StyleGenericBasicShape& other) const {
return !(*this == other);
}
private:
StyleGenericBasicShape() {
}
public:
~StyleGenericBasicShape() {
switch (tag) {
case Tag::Rect: rect.~StyleRect_Body(); break;
case Tag::Circle: circle.~StyleCircle_Body(); break;
case Tag::Ellipse: ellipse.~StyleEllipse_Body(); break;
case Tag::Polygon: polygon.~StylePolygon_Body(); break;
case Tag::PathOrShape: path_or_shape.~StylePathOrShape_Body(); break;
}
}
StyleGenericBasicShape(const StyleGenericBasicShape& other)
: tag(other.tag) {
switch (tag) {
case Tag::Rect: ::new (&rect) (StyleRect_Body)(other.rect); break;
case Tag::Circle: ::new (&circle) (StyleCircle_Body)(other.circle); break;
case Tag::Ellipse: ::new (&ellipse) (StyleEllipse_Body)(other.ellipse); break;
case Tag::Polygon: ::new (&polygon) (StylePolygon_Body)(other.polygon); break;
case Tag::PathOrShape: ::new (&path_or_shape) (StylePathOrShape_Body)(other.path_or_shape); break;
}
}
StyleGenericBasicShape& operator=(const StyleGenericBasicShape& other) {
if (this != &other) {
this->~StyleGenericBasicShape();
new (this) StyleGenericBasicShape(other);
}
return *this;
}
};
/// A computed basic shape.
using StyleBasicShape = StyleGenericBasicShape<StyleAngle, StylePosition, StyleLengthPercentage, StyleNonNegativeLengthPercentage, StyleInsetRect>;
/// The `ray()` function, `ray( [ <angle> && <size> && contain? && [at <position>]? ] )`
///
template<typename Angle, typename Position>
struct StyleGenericRayFunction {
/// The bearing angle with `0deg` pointing up and positive angles
/// representing clockwise rotation.
Angle angle;
/// Decide the path length used when `offset-distance` is expressed
/// as a percentage.
StyleRaySize size;
/// Clamp `offset-distance` so that the box is entirely contained
/// within the path.
bool contain;
/// The "at <position>" part. If omitted, we use auto to represent it.
StyleGenericPositionOrAuto<Position> position;
bool operator==(const StyleGenericRayFunction& other) const {
return angle == other.angle &&
size == other.size &&
contain == other.contain &&
position == other.position;
}
bool operator!=(const StyleGenericRayFunction& other) const {
return angle != other.angle ||
size != other.size ||
contain != other.contain ||
position != other.position;
}
};
/// The computed value of ray() function.
using StyleRayFunction = StyleGenericRayFunction<StyleAngle, StylePosition>;
/// A struct that basically replaces a Box<str>, but with a defined layout,
/// suitable for FFI.
struct StyleOwnedStr {
StyleOwnedSlice<uint8_t> _0;
bool operator==(const StyleOwnedStr& other) const {
return _0 == other._0;
}
bool operator!=(const StyleOwnedStr& other) const {
return _0 != other._0;
}
inline nsDependentCSubstring AsString() const;
};
#if defined(CBINDGEN_IS_GECKO)
/// Extra data that the backend may need to resolve url values.
///
/// If the usize's lowest bit is 0, then this is a strong reference to a
/// structs::URLExtraData object.
///
/// Otherwise, shifting the usize's bits the right by one gives the
/// UserAgentStyleSheetID value corresponding to the style sheet whose
/// URLExtraData this is, which is stored in URLExtraData_sShared. We don't
/// hold a strong reference to that object from here, but we rely on that
/// array's objects being held alive until shutdown.
///
/// We use this packed representation rather than an enum so that
/// `from_ptr_ref` can work.
struct StyleUrlExtraData {
uintptr_t _0;
bool operator==(const StyleUrlExtraData& other) const {
return _0 == other._0;
}
bool operator!=(const StyleUrlExtraData& other) const {
return _0 != other._0;
}
StyleUrlExtraData() = delete;
// Could be implemented if wanted.
StyleUrlExtraData(const StyleUrlExtraData&) = delete;
StyleUrlExtraData& operator=(const StyleUrlExtraData&) = delete;
inline bool IsShared() const;
inline ~StyleUrlExtraData();
inline const URLExtraData& get() const;
};
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Various bits of mutable state that are kept for image loads.
struct StyleLoadDataFlags {
uint8_t bits;
constexpr explicit operator bool() const {
return !!bits;
}
constexpr StyleLoadDataFlags operator~() const {
return StyleLoadDataFlags { static_cast<decltype(bits)>(~bits) };
}
constexpr StyleLoadDataFlags operator|(const StyleLoadDataFlags& other) const {
return StyleLoadDataFlags { static_cast<decltype(bits)>(this->bits | other.bits) };
}
StyleLoadDataFlags& operator|=(const StyleLoadDataFlags& other) {
*this = (*this | other);
return *this;
}
constexpr StyleLoadDataFlags operator&(const StyleLoadDataFlags& other) const {
return StyleLoadDataFlags { static_cast<decltype(bits)>(this->bits & other.bits) };
}
StyleLoadDataFlags& operator&=(const StyleLoadDataFlags& other) {
*this = (*this & other);
return *this;
}
constexpr StyleLoadDataFlags operator^(const StyleLoadDataFlags& other) const {
return StyleLoadDataFlags { static_cast<decltype(bits)>(this->bits ^ other.bits) };
}
StyleLoadDataFlags& operator^=(const StyleLoadDataFlags& other) {
*this = (*this ^ other);
return *this;
}
bool operator==(const StyleLoadDataFlags& other) const {
return bits == other.bits;
}
bool operator!=(const StyleLoadDataFlags& other) const {
return bits != other.bits;
}
static const StyleLoadDataFlags TRIED_TO_RESOLVE_URI;
static const StyleLoadDataFlags TRIED_TO_RESOLVE_IMAGE;
};
#if defined(CBINDGEN_IS_GECKO)
/// Whether we tried to resolve the uri at least once.
constexpr inline const StyleLoadDataFlags StyleLoadDataFlags::TRIED_TO_RESOLVE_URI = StyleLoadDataFlags{
/* .bits = */ (uint8_t)(1 << 0)
};
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Whether we tried to resolve the image at least once.
constexpr inline const StyleLoadDataFlags StyleLoadDataFlags::TRIED_TO_RESOLVE_IMAGE = StyleLoadDataFlags{
/* .bits = */ (uint8_t)(1 << 1)
};
#endif
#endif
#if defined(CBINDGEN_IS_GECKO)
/// The load data for a given URL. This is mutable from C++, and shouldn't be
/// accessed from rust for anything.
struct StyleLoadData {
/// A strong reference to the imgRequestProxy, if any, that should be
/// released on drop.
///
/// These are raw pointers because they are not safe to reference-count off
/// the main thread.
imgRequestProxy *resolved_image;
/// A strong reference to the resolved URI of this image.
nsIURI *resolved_uri;
/// A few flags that are set when resolving the image or such.
StyleLoadDataFlags flags;
bool operator==(const StyleLoadData& other) const {
return resolved_image == other.resolved_image &&
resolved_uri == other.resolved_uri &&
flags == other.flags;
}
bool operator!=(const StyleLoadData& other) const {
return resolved_image != other.resolved_image ||
resolved_uri != other.resolved_uri ||
flags != other.flags;
}
~StyleLoadData();
};
#endif
#if defined(CBINDGEN_IS_GECKO)
/// The data for a load, or a lazy-loaded, static member that will be stored in
/// LOAD_DATA_TABLE, keyed by the memory location of this object, which is
/// always in the heap because it's inside the CssUrlData object.
///
/// This type is meant not to be used from C++ so we don't derive helper
/// methods.
///
struct StyleLoadDataSource {
enum class Tag : uint8_t {
#if defined(CBINDGEN_IS_GECKO)
/// An owned copy of the load data.
Owned,
#endif
#if defined(CBINDGEN_IS_GECKO)
/// A lazily-resolved copy of it.
Lazy,
#endif
};
#if defined(CBINDGEN_IS_GECKO)
struct StyleOwned_Body {
StyleLoadData _0;
bool operator==(const StyleOwned_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleOwned_Body& other) const {
return _0 != other._0;
}
};
#endif
Tag tag;
union {
#if defined(CBINDGEN_IS_GECKO)
StyleOwned_Body owned;
#endif
};
bool operator==(const StyleLoadDataSource& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
#if defined(CBINDGEN_IS_GECKO)
case Tag::Owned: return owned == other.owned;
#endif
default: break;
}
return true;
}
bool operator!=(const StyleLoadDataSource& other) const {
return !(*this == other);
}
private:
StyleLoadDataSource() {
}
public:
~StyleLoadDataSource() {
switch (tag) {
#if defined(CBINDGEN_IS_GECKO)
case Tag::Owned: owned.~StyleOwned_Body(); break;
#endif
default: break;
}
}
StyleLoadDataSource(const StyleLoadDataSource& other)
: tag(other.tag) {
switch (tag) {
#if defined(CBINDGEN_IS_GECKO)
case Tag::Owned: ::new (&owned) (StyleOwned_Body)(other.owned); break;
#endif
default: break;
}
}
StyleLoadDataSource& operator=(const StyleLoadDataSource& other) {
if (this != &other) {
this->~StyleLoadDataSource();
new (this) StyleLoadDataSource(other);
}
return *this;
}
};
#endif
#if defined(CBINDGEN_IS_GECKO)
/// Data shared between CssUrls.
///
struct StyleCssUrlData {
/// The URL in unresolved string form.
StyleOwnedStr serialization;
/// The URL extra data.
StyleUrlExtraData extra_data;
/// The CORS mode that will be used for the load.
StyleCorsMode cors_mode;
/// Data to trigger a load from Gecko. This is mutable in C++.
///
/// TODO(emilio): Maybe we can eagerly resolve URLs and make this immutable?
StyleLoadDataSource load_data;
// Implemented in nsStyleStruct.cpp
bool operator==(const StyleCssUrlData& other) const;
bool operator!=(const StyleCssUrlData& other) const {
return !(*this == other);
}
};
#endif
#if defined(CBINDGEN_IS_GECKO)
/// A CSS url() value for gecko.
struct StyleCssUrl {
StyleArc<StyleCssUrlData> _0;
bool operator==(const StyleCssUrl& other) const {
return _0 == other._0;
}
bool operator!=(const StyleCssUrl& other) const {
return _0 != other._0;
}
inline nsDependentCSubstring SpecifiedSerialization() const;
inline const URLExtraData& ExtraData() const;
inline const StyleLoadData& LoadData() const;
inline StyleLoadData& MutLoadData() const;
inline nsIURI* GetURI() const;
};
#endif
#if defined(CBINDGEN_IS_GECKO)
/// A specified non-image `url()` value.
using StyleSpecifiedUrl = StyleCssUrl;
#endif
#if defined(CBINDGEN_IS_SERVO)
/// A specified url() value for servo.
using StyleSpecifiedUrl = StyleCssUrl;
#endif
#if defined(CBINDGEN_IS_GECKO)
/// The computed value of a CSS non-image `url()`.
///
/// The only difference between specified and computed URLs is the
/// serialization.
struct StyleComputedUrl {
StyleSpecifiedUrl _0;
bool operator==(const StyleComputedUrl& other) const {
return _0 == other._0;
}
bool operator!=(const StyleComputedUrl& other) const {
return _0 != other._0;
}
// Forwarded from CssUrl.
inline nsDependentCSubstring SpecifiedSerialization() const;
inline const URLExtraData& ExtraData() const;
inline nsIURI* GetURI() const;
inline const StyleLoadData& LoadData() const;
inline StyleLoadData& MutLoadData() const;
inline bool IsLocalRef() const;
inline bool HasRef() const;
inline StyleCorsMode CorsMode() const;
// Only relevant for images.
inline bool IsImageResolved() const;
inline imgRequestProxy* GetImage() const;
void ResolveImage(dom::Document&, const StyleComputedUrl* aOldImage);
};
#endif
/// The <offset-path> value.
/// <offset-path> = <ray()> | <url> | <basic-shape>
///
template<typename Shapes, typename RayFunction, typename U>
struct StyleGenericOffsetPathFunction {
enum class Tag : uint8_t {
/// ray() function, which defines a path in the polar coordinate system.
/// Use Box<> to make sure the size of offset-path is not too large.
Ray,
/// A URL reference to an SVG shape element. If the URL does not reference a shape element,
/// this behaves as path("m 0 0") instead.
Url,
/// The <basic-shape> value.
Shape,
};
struct StyleRay_Body {
RayFunction _0;
bool operator==(const StyleRay_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleRay_Body& other) const {
return _0 != other._0;
}
};
struct StyleUrl_Body {
U _0;
bool operator==(const StyleUrl_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleUrl_Body& other) const {
return _0 != other._0;
}
};
struct StyleShape_Body {
Shapes _0;
bool operator==(const StyleShape_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleShape_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StyleRay_Body ray;
StyleUrl_Body url;
StyleShape_Body shape;
};
static StyleGenericOffsetPathFunction Ray(const RayFunction &_0) {
StyleGenericOffsetPathFunction result;
::new (&result.ray._0) (RayFunction)(_0);
result.tag = Tag::Ray;
return result;
}
bool IsRay() const {
return tag == Tag::Ray;
}
const RayFunction& AsRay() const {
MOZ_DIAGNOSTIC_ASSERT(IsRay());
return ray._0;
}
static StyleGenericOffsetPathFunction Url(const U &_0) {
StyleGenericOffsetPathFunction result;
::new (&result.url._0) (U)(_0);
result.tag = Tag::Url;
return result;
}
bool IsUrl() const {
return tag == Tag::Url;
}
const U& AsUrl() const {
MOZ_DIAGNOSTIC_ASSERT(IsUrl());
return url._0;
}
static StyleGenericOffsetPathFunction Shape(const Shapes &_0) {
StyleGenericOffsetPathFunction result;
::new (&result.shape._0) (Shapes)(_0);
result.tag = Tag::Shape;
return result;
}
bool IsShape() const {
return tag == Tag::Shape;
}
const Shapes& AsShape() const {
MOZ_DIAGNOSTIC_ASSERT(IsShape());
return shape._0;
}
bool operator==(const StyleGenericOffsetPathFunction& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Ray: return ray == other.ray;
case Tag::Url: return url == other.url;
case Tag::Shape: return shape == other.shape;
}
return true;
}
bool operator!=(const StyleGenericOffsetPathFunction& other) const {
return !(*this == other);
}
private:
StyleGenericOffsetPathFunction() {
}
public:
~StyleGenericOffsetPathFunction() {
switch (tag) {
case Tag::Ray: ray.~StyleRay_Body(); break;
case Tag::Url: url.~StyleUrl_Body(); break;
case Tag::Shape: shape.~StyleShape_Body(); break;
}
}
StyleGenericOffsetPathFunction(const StyleGenericOffsetPathFunction& other)
: tag(other.tag) {
switch (tag) {
case Tag::Ray: ::new (&ray) (StyleRay_Body)(other.ray); break;
case Tag::Url: ::new (&url) (StyleUrl_Body)(other.url); break;
case Tag::Shape: ::new (&shape) (StyleShape_Body)(other.shape); break;
}
}
StyleGenericOffsetPathFunction& operator=(const StyleGenericOffsetPathFunction& other) {
if (this != &other) {
this->~StyleGenericOffsetPathFunction();
new (this) StyleGenericOffsetPathFunction(other);
}
return *this;
}
};
/// The computed value of <offset-path>.
using StyleOffsetPathFunction = StyleGenericOffsetPathFunction<StyleBasicShape, StyleRayFunction, StyleComputedUrl>;
/// The offset-path property.
/// offset-path: none | <offset-path> || <coord-box>
///
template<typename Function>
struct StyleGenericOffsetPath {
enum class Tag : uint8_t {
/// <offset-path> || <coord-box>.
OffsetPath,
/// Only <coord-box>. This represents that <offset-path> is omitted, so we use the default
/// value, inset(0 round X), where X is the value of border-radius on the element that
/// establishes the containing block for this element.
CoordBox,
/// None value.
None,
};
struct StyleOffsetPath_Body {
/// <offset-path> part.
StyleBox<Function> path;
/// <coord-box> part.
StyleCoordBox coord_box;
bool operator==(const StyleOffsetPath_Body& other) const {
return path == other.path &&
coord_box == other.coord_box;
}
bool operator!=(const StyleOffsetPath_Body& other) const {
return path != other.path ||
coord_box != other.coord_box;
}
};
struct StyleCoordBox_Body {
StyleCoordBox _0;
bool operator==(const StyleCoordBox_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleCoordBox_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StyleOffsetPath_Body offset_path;
StyleCoordBox_Body coord_box;
};
static StyleGenericOffsetPath OffsetPath(const StyleBox<Function> &path,
const StyleCoordBox &coord_box) {
StyleGenericOffsetPath result;
::new (&result.offset_path.path) (StyleBox<Function>)(path);
::new (&result.offset_path.coord_box) (StyleCoordBox)(coord_box);
result.tag = Tag::OffsetPath;
return result;
}
bool IsOffsetPath() const {
return tag == Tag::OffsetPath;
}
const StyleOffsetPath_Body& AsOffsetPath() const {
MOZ_DIAGNOSTIC_ASSERT(IsOffsetPath());
return offset_path;
}
static StyleGenericOffsetPath CoordBox(const StyleCoordBox &_0) {
StyleGenericOffsetPath result;
::new (&result.coord_box._0) (StyleCoordBox)(_0);
result.tag = Tag::CoordBox;
return result;
}
bool IsCoordBox() const {
return tag == Tag::CoordBox;
}
const StyleCoordBox& AsCoordBox() const {
MOZ_DIAGNOSTIC_ASSERT(IsCoordBox());
return coord_box._0;
}
static StyleGenericOffsetPath None() {
StyleGenericOffsetPath result;
result.tag = Tag::None;
return result;
}
bool IsNone() const {
return tag == Tag::None;
}
bool operator==(const StyleGenericOffsetPath& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::OffsetPath: return offset_path == other.offset_path;
case Tag::CoordBox: return coord_box == other.coord_box;
default: break;
}
return true;
}
bool operator!=(const StyleGenericOffsetPath& other) const {
return !(*this == other);
}
private:
StyleGenericOffsetPath() {
}
public:
~StyleGenericOffsetPath() {
switch (tag) {
case Tag::OffsetPath: offset_path.~StyleOffsetPath_Body(); break;
case Tag::CoordBox: coord_box.~StyleCoordBox_Body(); break;
default: break;
}
}
StyleGenericOffsetPath(const StyleGenericOffsetPath& other)
: tag(other.tag) {
switch (tag) {
case Tag::OffsetPath: ::new (&offset_path) (StyleOffsetPath_Body)(other.offset_path); break;
case Tag::CoordBox: ::new (&coord_box) (StyleCoordBox_Body)(other.coord_box); break;
default: break;
}
}
StyleGenericOffsetPath& operator=(const StyleGenericOffsetPath& other) {
if (this != &other) {
this->~StyleGenericOffsetPath();
new (this) StyleGenericOffsetPath(other);
}
return *this;
}
// Return true if the <offset-path> is ray().
bool IsRay() const {
return IsOffsetPath() && AsOffsetPath().path->IsRay();
}
const StyleRayFunction& AsRay() const {
return AsOffsetPath().path->AsRay();
}
// Return true if the <offset-path> is url().
bool IsUrl() const {
return IsOffsetPath() && AsOffsetPath().path->IsUrl();
}
const StyleComputedUrl& AsUrl() const {
return AsOffsetPath().path->AsUrl();
}
// Return true if the <basic-shape> is path().
bool IsPath() const {
if (!IsOffsetPath()) {
return false;
}
const auto& path = AsOffsetPath().path;
if (!path->IsShape()) {
return false;
}
const auto& shape = path->AsShape();
return shape.IsPathOrShape() && shape.AsPathOrShape().IsPath();
}
const StyleSVGPathData& AsSVGPathData() const {
return AsOffsetPath().path->AsShape().AsPathOrShape().AsPath().path;
}
// Return true if this is "<basic-shape> || <coord-box>".
bool IsBasicShapeOrCoordBox() const {
return IsCoordBox() || (IsOffsetPath() && AsOffsetPath().path->IsShape());
}
};
/// The computed value of `offset-path`.
using StyleOffsetPath = StyleGenericOffsetPath<StyleOffsetPathFunction>;
/// A computed offset-rotate.
struct StyleOffsetRotate {
/// If auto is false, this is a fixed angle which indicates a
/// constant clockwise rotation transformation applied to it by this
/// specified rotation angle. Otherwise, the angle will be added to
/// the angle of the direction in layout.
bool auto_;
/// The angle value.
StyleAngle angle;
bool operator==(const StyleOffsetRotate& other) const {
return auto_ == other.auto_ &&
angle == other.angle;
}
bool operator!=(const StyleOffsetRotate& other) const {
return auto_ != other.auto_ ||
angle != other.angle;
}
};
/// The computed value of an `auto | <position>`
using StylePositionOrAuto = StyleGenericPositionOrAuto<StylePosition>;
/// The offset-position property, which specifies the offset starting position that is used by the
/// <offset-path> functions if they don’t specify their own starting position.
///
template<typename H, typename V>
struct StyleGenericOffsetPosition {
enum class Tag : uint8_t {
/// The element does not have an offset starting position.
Normal,
/// The offset starting position is the top-left corner of the box.
Auto,
/// The offset starting position is the result of using the <position> to position a 0x0 object
/// area within the box’s containing block.
Position,
};
struct StylePosition_Body {
StyleGenericPosition<H, V> _0;
bool operator==(const StylePosition_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StylePosition_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StylePosition_Body position;
};
static StyleGenericOffsetPosition Normal() {
StyleGenericOffsetPosition result;
result.tag = Tag::Normal;
return result;
}
bool IsNormal() const {
return tag == Tag::Normal;
}
static StyleGenericOffsetPosition Auto() {
StyleGenericOffsetPosition result;
result.tag = Tag::Auto;
return result;
}
bool IsAuto() const {
return tag == Tag::Auto;
}
static StyleGenericOffsetPosition Position(const StyleGenericPosition<H, V> &_0) {
StyleGenericOffsetPosition result;
::new (&result.position._0) (StyleGenericPosition<H, V>)(_0);
result.tag = Tag::Position;
return result;
}
bool IsPosition() const {
return tag == Tag::Position;
}
const StyleGenericPosition<H, V>& AsPosition() const {
MOZ_DIAGNOSTIC_ASSERT(IsPosition());
return position._0;
}
bool operator==(const StyleGenericOffsetPosition& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Position: return position == other.position;
default: break;
}
return true;
}
bool operator!=(const StyleGenericOffsetPosition& other) const {
return !(*this == other);
}
private:
StyleGenericOffsetPosition() {
}
public:
~StyleGenericOffsetPosition() {
switch (tag) {
case Tag::Position: position.~StylePosition_Body(); break;
default: break;
}
}
StyleGenericOffsetPosition(const StyleGenericOffsetPosition& other)
: tag(other.tag) {
switch (tag) {
case Tag::Position: ::new (&position) (StylePosition_Body)(other.position); break;
default: break;
}
}
StyleGenericOffsetPosition& operator=(const StyleGenericOffsetPosition& other) {
if (this != &other) {
this->~StyleGenericOffsetPosition();
new (this) StyleGenericOffsetPosition(other);
}
return *this;
}
};
/// The computed value of `offset-position`.
using StyleOffsetPosition = StyleGenericOffsetPosition<StyleLengthPercentage, StyleLengthPercentage>;
struct StyleShouldTransitionResult {
bool should_animate;
bool old_transition_value_matches;
bool operator==(const StyleShouldTransitionResult& other) const {
return should_animate == other.should_animate &&
old_transition_value_matches == other.old_transition_value_matches;
}
bool operator!=(const StyleShouldTransitionResult& other) const {
return should_animate != other.should_animate ||
old_transition_value_matches != other.old_transition_value_matches;
}
};
#if defined(XP_UNIX)
/// Platform-specific handle to a thread.
using StylePlatformThreadHandle = pthread_t;
#endif
#if defined(XP_WIN)
/// Platform-specific handle to a thread.
using StylePlatformThreadHandle = void*;
#endif
#if !defined(CBINDGEN_IS_GECKO)
/// Platform-specific handle to a thread.
using StylePlatformThreadHandle = StyleDummyThreadHandle;
#endif
/// The computed representation of the above so Gecko can read them easily.
///
/// This one is needed because cbindgen doesn't know how to generate
/// specified::Number.
struct StyleComputedFontWeightRange {
float _0;
float _1;
bool operator==(const StyleComputedFontWeightRange& other) const {
return _0 == other._0 &&
_1 == other._1;
}
bool operator!=(const StyleComputedFontWeightRange& other) const {
return _0 != other._0 ||
_1 != other._1;
}
};
/// Generic template for font property type classes that use a fixed-point
/// internal representation with `FRACTION_BITS` for the fractional part.
///
/// Values are constructed from and exposed as floating-point, but stored
/// internally as fixed point, so there will be a quantization effect on
/// fractional values, depending on the number of fractional bits used.
///
/// Using (16-bit) fixed-point types rather than floats for these style
/// attributes reduces the memory footprint of gfxFontEntry and gfxFontStyle; it
/// will also tend to reduce the number of distinct font instances that get
/// created, particularly when styles are animated or set to arbitrary values
/// (e.g. by sliders in the UI), which should reduce pressure on graphics
/// resources and improve cache hit rates.
///
template<typename T, uint16_t FRACTION_BITS>
struct StyleFixedPoint {
/// The actual representation.
T value;
bool operator==(const StyleFixedPoint& other) const {
return value == other.value;
}
bool operator!=(const StyleFixedPoint& other) const {
return value != other.value;
}
bool operator<(const StyleFixedPoint& other) const {
return value < other.value;
}
bool operator<=(const StyleFixedPoint& other) const {
return value <= other.value;
}
bool operator>(const StyleFixedPoint& other) const {
return value > other.value;
}
bool operator>=(const StyleFixedPoint& other) const {
return value >= other.value;
}
};
/// This is an alias which is useful mostly as a cbindgen / C++ inference
/// workaround.
using StyleFontStretchFixedPoint = StyleFixedPoint<uint16_t, StyleFONT_STRETCH_FRACTION_BITS>;
/// A value for the font-stretch property per:
///
///
struct StyleFontStretch {
StyleFontStretchFixedPoint _0;
bool operator==(const StyleFontStretch& other) const {
return _0 == other._0;
}
bool operator!=(const StyleFontStretch& other) const {
return _0 != other._0;
}
bool operator<(const StyleFontStretch& other) const {
return _0 < other._0;
}
bool operator<=(const StyleFontStretch& other) const {
return _0 <= other._0;
}
bool operator>(const StyleFontStretch& other) const {
return _0 > other._0;
}
bool operator>=(const StyleFontStretch& other) const {
return _0 >= other._0;
}
SERVO_FIXED_POINT_HELPERS(StyleFontStretch, uint16_t, StyleFONT_STRETCH_FRACTION_BITS);
bool IsNormal() const { return *this == NORMAL; }
static const uint16_t FRACTION_BITS;
static const uint16_t HALF;
static const StyleFontStretch ULTRA_CONDENSED;
static const StyleFontStretch EXTRA_CONDENSED;
static const StyleFontStretch CONDENSED;
static const StyleFontStretch SEMI_CONDENSED;
static const StyleFontStretch NORMAL;
static const StyleFontStretch SEMI_EXPANDED;
static const StyleFontStretch EXPANDED;
static const StyleFontStretch EXTRA_EXPANDED;
static const StyleFontStretch ULTRA_EXPANDED;
};
/// The fraction bits, as an easy-to-access-constant.
constexpr inline const uint16_t StyleFontStretch::FRACTION_BITS = StyleFONT_STRETCH_FRACTION_BITS;
/// 0.5 in our floating point representation.
constexpr inline const uint16_t StyleFontStretch::HALF = (1 << (StyleFontStretch::FRACTION_BITS - 1));
/// The `ultra-condensed` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::ULTRA_CONDENSED = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ (50 << StyleFontStretch::FRACTION_BITS)
}
};
/// The `extra-condensed` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::EXTRA_CONDENSED = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ ((62 << StyleFontStretch::FRACTION_BITS) + StyleFontStretch::HALF)
}
};
/// The `condensed` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::CONDENSED = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ (75 << StyleFontStretch::FRACTION_BITS)
}
};
/// The `semi-condensed` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::SEMI_CONDENSED = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ ((87 << StyleFontStretch::FRACTION_BITS) + StyleFontStretch::HALF)
}
};
/// The `normal` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::NORMAL = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ (100 << StyleFontStretch::FRACTION_BITS)
}
};
/// The `semi-expanded` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::SEMI_EXPANDED = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ ((112 << StyleFontStretch::FRACTION_BITS) + StyleFontStretch::HALF)
}
};
/// The `expanded` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::EXPANDED = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ (125 << StyleFontStretch::FRACTION_BITS)
}
};
/// The `extra-expanded` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::EXTRA_EXPANDED = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ (150 << StyleFontStretch::FRACTION_BITS)
}
};
/// The `ultra-expanded` keyword.
constexpr inline const StyleFontStretch StyleFontStretch::ULTRA_EXPANDED = StyleFontStretch{
/* ._0 = */ StyleFontStretchFixedPoint{
/* .value = */ (200 << StyleFontStretch::FRACTION_BITS)
}
};
/// The computed representation of the above, so that Gecko can read them
/// easily.
struct StyleComputedFontStretchRange {
StyleFontStretch _0;
StyleFontStretch _1;
bool operator==(const StyleComputedFontStretchRange& other) const {
return _0 == other._0 &&
_1 == other._1;
}
bool operator!=(const StyleComputedFontStretchRange& other) const {
return _0 != other._0 ||
_1 != other._1;
}
};
/// The computed representation of the above, with angles in degrees, so that
/// Gecko can read them easily.
union StyleComputedFontStyleDescriptor {
enum class Tag : uint8_t {
Italic,
Oblique,
};
struct Oblique_Body {
Tag tag;
float _0;
float _1;
bool operator==(const Oblique_Body& other) const {
return _0 == other._0 &&
_1 == other._1;
}
bool operator!=(const Oblique_Body& other) const {
return _0 != other._0 ||
_1 != other._1;
}
};
struct {
Tag tag;
};
Oblique_Body oblique;
static StyleComputedFontStyleDescriptor Italic() {
StyleComputedFontStyleDescriptor result;
result.tag = Tag::Italic;
return result;
}
bool IsItalic() const {
return tag == Tag::Italic;
}
static StyleComputedFontStyleDescriptor Oblique(const float &_0,
const float &_1) {
StyleComputedFontStyleDescriptor result;
::new (&result.oblique._0) (float)(_0);
::new (&result.oblique._1) (float)(_1);
result.tag = Tag::Oblique;
return result;
}
bool IsOblique() const {
return tag == Tag::Oblique;
}
const Oblique_Body& AsOblique() const {
MOZ_DIAGNOSTIC_ASSERT(IsOblique());
return oblique;
}
bool operator==(const StyleComputedFontStyleDescriptor& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Oblique: return oblique == other.oblique;
default: break;
}
return true;
}
bool operator!=(const StyleComputedFontStyleDescriptor& other) const {
return !(*this == other);
}
private:
StyleComputedFontStyleDescriptor() {
}
public:
~StyleComputedFontStyleDescriptor() {
switch (tag) {
case Tag::Oblique: oblique.~Oblique_Body(); break;
default: break;
}
}
StyleComputedFontStyleDescriptor(const StyleComputedFontStyleDescriptor& other)
: tag(other.tag) {
switch (tag) {
case Tag::Oblique: ::new (&oblique) (Oblique_Body)(other.oblique); break;
default: break;
}
}
StyleComputedFontStyleDescriptor& operator=(const StyleComputedFontStyleDescriptor& other) {
if (this != &other) {
this->~StyleComputedFontStyleDescriptor();
new (this) StyleComputedFontStyleDescriptor(other);
}
return *this;
}
inline static StyleComputedFontStyleDescriptor Normal() {
return StyleComputedFontStyleDescriptor::Oblique(0, 0);
}
};
/// font-language-override can only have a single 1-4 ASCII character
/// OpenType "language system" tag, so we should be able to compute
/// it and store it as a 32-bit integer
struct StyleFontLanguageOverride {
uint32_t _0;
bool operator==(const StyleFontLanguageOverride& other) const {
return _0 == other._0;
}
bool operator!=(const StyleFontLanguageOverride& other) const {
return _0 != other._0;
}
};
/// One contiguous range of code points.
///
/// Can not be empty. Can represent a single code point when start == end.
struct StyleUnicodeRange {
/// Inclusive start of the range. In [0, end].
uint32_t start;
/// Inclusive end of the range. In [0, 0x10FFFF].
uint32_t end;
bool operator==(const StyleUnicodeRange& other) const {
return start == other.start &&
end == other.end;
}
bool operator!=(const StyleUnicodeRange& other) const {
return start != other.start ||
end != other.end;
}
};
/// Flags for the @font-face tech() function, indicating font technologies
/// required by the resource.
struct StyleFontFaceSourceTechFlags {
uint16_t _0;
constexpr explicit operator bool() const {
return !!_0;
}
constexpr StyleFontFaceSourceTechFlags operator~() const {
return StyleFontFaceSourceTechFlags { static_cast<decltype(_0)>(~_0) };
}
constexpr StyleFontFaceSourceTechFlags operator|(const StyleFontFaceSourceTechFlags& other) const {
return StyleFontFaceSourceTechFlags { static_cast<decltype(_0)>(this->_0 | other._0) };
}
StyleFontFaceSourceTechFlags& operator|=(const StyleFontFaceSourceTechFlags& other) {
*this = (*this | other);
return *this;
}
constexpr StyleFontFaceSourceTechFlags operator&(const StyleFontFaceSourceTechFlags& other) const {
return StyleFontFaceSourceTechFlags { static_cast<decltype(_0)>(this->_0 & other._0) };
}
StyleFontFaceSourceTechFlags& operator&=(const StyleFontFaceSourceTechFlags& other) {
*this = (*this & other);
return *this;
}
constexpr StyleFontFaceSourceTechFlags operator^(const StyleFontFaceSourceTechFlags& other) const {
return StyleFontFaceSourceTechFlags { static_cast<decltype(_0)>(this->_0 ^ other._0) };
}
StyleFontFaceSourceTechFlags& operator^=(const StyleFontFaceSourceTechFlags& other) {
*this = (*this ^ other);
return *this;
}
bool operator==(const StyleFontFaceSourceTechFlags& other) const {
return _0 == other._0;
}
bool operator!=(const StyleFontFaceSourceTechFlags& other) const {
return _0 != other._0;
}
inline static StyleFontFaceSourceTechFlags Empty() {
return StyleFontFaceSourceTechFlags{0};
}
static const StyleFontFaceSourceTechFlags FEATURES_OPENTYPE;
static const StyleFontFaceSourceTechFlags FEATURES_AAT;
static const StyleFontFaceSourceTechFlags FEATURES_GRAPHITE;
static const StyleFontFaceSourceTechFlags COLOR_COLRV0;
static const StyleFontFaceSourceTechFlags COLOR_COLRV1;
static const StyleFontFaceSourceTechFlags COLOR_SVG;
static const StyleFontFaceSourceTechFlags COLOR_SBIX;
static const StyleFontFaceSourceTechFlags COLOR_CBDT;
static const StyleFontFaceSourceTechFlags VARIATIONS;
static const StyleFontFaceSourceTechFlags PALETTES;
static const StyleFontFaceSourceTechFlags INCREMENTAL;
};
/// Font requires OpenType feature support.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::FEATURES_OPENTYPE = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 0)
};
/// Font requires Apple Advanced Typography support.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::FEATURES_AAT = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 1)
};
/// Font requires Graphite shaping support.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::FEATURES_GRAPHITE = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 2)
};
/// Font requires COLRv0 rendering support (simple list of colored layers).
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::COLOR_COLRV0 = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 3)
};
/// Font requires COLRv1 rendering support (graph of paint operations).
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::COLOR_COLRV1 = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 4)
};
/// Font requires SVG glyph rendering support.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::COLOR_SVG = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 5)
};
/// Font has bitmap glyphs in 'sbix' format.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::COLOR_SBIX = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 6)
};
/// Font has bitmap glyphs in 'CBDT' format.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::COLOR_CBDT = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 7)
};
/// Font requires OpenType Variations support.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::VARIATIONS = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 8)
};
/// Font requires CPAL palette selection support.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::PALETTES = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 9)
};
/// Font requires support for incremental downloading.
constexpr inline const StyleFontFaceSourceTechFlags StyleFontFaceSourceTechFlags::INCREMENTAL = StyleFontFaceSourceTechFlags{
/* ._0 = */ (uint16_t)(1 << 10)
};
#if defined(CBINDGEN_IS_GECKO)
/// A POD representation for Gecko. All pointers here are non-owned and as such
/// can't outlive the rule they came from, but we can't enforce that via C++.
///
/// All the strings are of course utf8.
union StyleFontFaceSourceListComponent {
enum class Tag : uint8_t {
Url,
Local,
FormatHintKeyword,
FormatHintString,
TechFlags,
};
struct Url_Body {
Tag tag;
const StyleCssUrl *_0;
bool operator==(const Url_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Url_Body& other) const {
return _0 != other._0;
}
};
struct Local_Body {
Tag tag;
nsAtom *_0;
bool operator==(const Local_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Local_Body& other) const {
return _0 != other._0;
}
};
struct FormatHintKeyword_Body {
Tag tag;
StyleFontFaceSourceFormatKeyword _0;
bool operator==(const FormatHintKeyword_Body& other) const {
return _0 == other._0;
}
bool operator!=(const FormatHintKeyword_Body& other) const {
return _0 != other._0;
}
};
struct FormatHintString_Body {
Tag tag;
uintptr_t length;
const uint8_t *utf8_bytes;
bool operator==(const FormatHintString_Body& other) const {
return length == other.length &&
utf8_bytes == other.utf8_bytes;
}
bool operator!=(const FormatHintString_Body& other) const {
return length != other.length ||
utf8_bytes != other.utf8_bytes;
}
};
struct TechFlags_Body {
Tag tag;
StyleFontFaceSourceTechFlags _0;
bool operator==(const TechFlags_Body& other) const {
return _0 == other._0;
}
bool operator!=(const TechFlags_Body& other) const {
return _0 != other._0;
}
};
struct {
Tag tag;
};
Url_Body url;
Local_Body local;
FormatHintKeyword_Body format_hint_keyword;
FormatHintString_Body format_hint_string;
TechFlags_Body tech_flags;
static StyleFontFaceSourceListComponent Url(const StyleCssUrl *const &_0) {
StyleFontFaceSourceListComponent result;
::new (&result.url._0) (const StyleCssUrl*)(_0);
result.tag = Tag::Url;
return result;
}
bool IsUrl() const {
return tag == Tag::Url;
}
const StyleCssUrl*const & AsUrl() const {
MOZ_DIAGNOSTIC_ASSERT(IsUrl());
return url._0;
}
static StyleFontFaceSourceListComponent Local(nsAtom *const &_0) {
StyleFontFaceSourceListComponent result;
::new (&result.local._0) (nsAtom*)(_0);
result.tag = Tag::Local;
return result;
}
bool IsLocal() const {
return tag == Tag::Local;
}
nsAtom*const & AsLocal() const {
MOZ_DIAGNOSTIC_ASSERT(IsLocal());
return local._0;
}
static StyleFontFaceSourceListComponent FormatHintKeyword(const StyleFontFaceSourceFormatKeyword &_0) {
StyleFontFaceSourceListComponent result;
::new (&result.format_hint_keyword._0) (StyleFontFaceSourceFormatKeyword)(_0);
result.tag = Tag::FormatHintKeyword;
return result;
}
bool IsFormatHintKeyword() const {
return tag == Tag::FormatHintKeyword;
}
const StyleFontFaceSourceFormatKeyword& AsFormatHintKeyword() const {
MOZ_DIAGNOSTIC_ASSERT(IsFormatHintKeyword());
return format_hint_keyword._0;
}
static StyleFontFaceSourceListComponent FormatHintString(const uintptr_t &length,
const uint8_t *const &utf8_bytes) {
StyleFontFaceSourceListComponent result;
::new (&result.format_hint_string.length) (uintptr_t)(length);
::new (&result.format_hint_string.utf8_bytes) (const uint8_t*)(utf8_bytes);
result.tag = Tag::FormatHintString;
return result;
}
bool IsFormatHintString() const {
return tag == Tag::FormatHintString;
}
const FormatHintString_Body& AsFormatHintString() const {
MOZ_DIAGNOSTIC_ASSERT(IsFormatHintString());
return format_hint_string;
}
static StyleFontFaceSourceListComponent TechFlags(const StyleFontFaceSourceTechFlags &_0) {
StyleFontFaceSourceListComponent result;
::new (&result.tech_flags._0) (StyleFontFaceSourceTechFlags)(_0);
result.tag = Tag::TechFlags;
return result;
}
bool IsTechFlags() const {
return tag == Tag::TechFlags;
}
const StyleFontFaceSourceTechFlags& AsTechFlags() const {
MOZ_DIAGNOSTIC_ASSERT(IsTechFlags());
return tech_flags._0;
}
bool operator==(const StyleFontFaceSourceListComponent& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Url: return url == other.url;
case Tag::Local: return local == other.local;
case Tag::FormatHintKeyword: return format_hint_keyword == other.format_hint_keyword;
case Tag::FormatHintString: return format_hint_string == other.format_hint_string;
case Tag::TechFlags: return tech_flags == other.tech_flags;
}
return true;
}
bool operator!=(const StyleFontFaceSourceListComponent& other) const {
return !(*this == other);
}
private:
StyleFontFaceSourceListComponent() {
}
public:
~StyleFontFaceSourceListComponent() {
switch (tag) {
case Tag::Url: url.~Url_Body(); break;
case Tag::Local: local.~Local_Body(); break;
case Tag::FormatHintKeyword: format_hint_keyword.~FormatHintKeyword_Body(); break;
case Tag::FormatHintString: format_hint_string.~FormatHintString_Body(); break;
case Tag::TechFlags: tech_flags.~TechFlags_Body(); break;
}
}
StyleFontFaceSourceListComponent(const StyleFontFaceSourceListComponent& other)
: tag(other.tag) {
switch (tag) {
case Tag::Url: ::new (&url) (Url_Body)(other.url); break;
case Tag::Local: ::new (&local) (Local_Body)(other.local); break;
case Tag::FormatHintKeyword: ::new (&format_hint_keyword) (FormatHintKeyword_Body)(other.format_hint_keyword); break;
case Tag::FormatHintString: ::new (&format_hint_string) (FormatHintString_Body)(other.format_hint_string); break;
case Tag::TechFlags: ::new (&tech_flags) (TechFlags_Body)(other.tech_flags); break;
}
}
StyleFontFaceSourceListComponent& operator=(const StyleFontFaceSourceListComponent& other) {
if (this != &other) {
this->~StyleFontFaceSourceListComponent();
new (this) StyleFontFaceSourceListComponent(other);
}
return *this;
}
};
#endif
#if defined(CBINDGEN_IS_GECKO)
/// A handle to a Gecko atom. This is a type that can represent either:
///
/// * A strong reference to a dynamic atom (an `nsAtom` pointer), in which case
/// the `usize` just holds the pointer value.
///
/// * An index from `gGkAtoms` to the `nsStaticAtom` object (shifted to the left one bit, and with
/// the lower bit set to `1` to differentiate it from the above), so `(index << 1 | 1)`.
///
struct StyleAtom {
StyleNonZeroUsize _0;
bool operator==(const StyleAtom& other) const {
return _0 == other._0;
}
bool operator!=(const StyleAtom& other) const {
return _0 != other._0;
}
StyleAtom(size_t) = delete;
StyleAtom() = delete;
inline bool IsStatic() const;
inline nsAtom* AsAtom() const;
private:
inline void AddRef();
inline void Release();
public:
inline explicit StyleAtom(already_AddRefed<nsAtom>);
inline explicit StyleAtom(nsStaticAtom*);
inline StyleAtom(const StyleAtom& aOther);
inline StyleAtom& operator=(const StyleAtom&);
inline ~StyleAtom();
};
#endif
struct StyleCustomIdent {
StyleAtom _0;
bool operator==(const StyleCustomIdent& other) const {
return _0 == other._0;
}
bool operator!=(const StyleCustomIdent& other) const {
return _0 != other._0;
}
inline nsAtom* AsAtom() const;
};
union StyleSymbol {
enum class Tag : uint8_t {
/// <string>
String,
/// <custom-ident>
Ident,
};
struct String_Body {
Tag tag;
StyleOwnedStr _0;
bool operator==(const String_Body& other) const {
return _0 == other._0;
}
bool operator!=(const String_Body& other) const {
return _0 != other._0;
}
};
struct Ident_Body {
Tag tag;
StyleCustomIdent _0;
bool operator==(const Ident_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Ident_Body& other) const {
return _0 != other._0;
}
};
struct {
Tag tag;
};
String_Body string;
Ident_Body ident;
static StyleSymbol String(const StyleOwnedStr &_0) {
StyleSymbol result;
::new (&result.string._0) (StyleOwnedStr)(_0);
result.tag = Tag::String;
return result;
}
bool IsString() const {
return tag == Tag::String;
}
const StyleOwnedStr& AsString() const {
MOZ_DIAGNOSTIC_ASSERT(IsString());
return string._0;
}
static StyleSymbol Ident(const StyleCustomIdent &_0) {
StyleSymbol result;
::new (&result.ident._0) (StyleCustomIdent)(_0);
result.tag = Tag::Ident;
return result;
}
bool IsIdent() const {
return tag == Tag::Ident;
}
const StyleCustomIdent& AsIdent() const {
MOZ_DIAGNOSTIC_ASSERT(IsIdent());
return ident._0;
}
bool operator==(const StyleSymbol& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::String: return string == other.string;
case Tag::Ident: return ident == other.ident;
}
return true;
}
bool operator!=(const StyleSymbol& other) const {
return !(*this == other);
}
private:
StyleSymbol() {
}
public:
~StyleSymbol() {
switch (tag) {
case Tag::String: string.~String_Body(); break;
case Tag::Ident: ident.~Ident_Body(); break;
}
}
StyleSymbol(const StyleSymbol& other)
: tag(other.tag) {
switch (tag) {
case Tag::String: ::new (&string) (String_Body)(other.string); break;
case Tag::Ident: ::new (&ident) (Ident_Body)(other.ident); break;
}
}
StyleSymbol& operator=(const StyleSymbol& other) {
if (this != &other) {
this->~StyleSymbol();
new (this) StyleSymbol(other);
}
return *this;
}
};
struct StyleAdditiveSymbol {
int32_t weight;
nsString symbol;
bool operator==(const StyleAdditiveSymbol& other) const {
return weight == other.weight &&
symbol == other.symbol;
}
bool operator!=(const StyleAdditiveSymbol& other) const {
return weight != other.weight ||
symbol != other.symbol;
}
};
struct StyleCounterSpeakAs {
enum class Tag : uint8_t {
None,
Auto,
Bullets,
Numbers,
Words,
Ident,
};
struct StyleIdent_Body {
nsAtom *_0;
bool operator==(const StyleIdent_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleIdent_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StyleIdent_Body ident;
};
static StyleCounterSpeakAs None() {
StyleCounterSpeakAs result;
result.tag = Tag::None;
return result;
}
bool IsNone() const {
return tag == Tag::None;
}
static StyleCounterSpeakAs Auto() {
StyleCounterSpeakAs result;
result.tag = Tag::Auto;
return result;
}
bool IsAuto() const {
return tag == Tag::Auto;
}
static StyleCounterSpeakAs Bullets() {
StyleCounterSpeakAs result;
result.tag = Tag::Bullets;
return result;
}
bool IsBullets() const {
return tag == Tag::Bullets;
}
static StyleCounterSpeakAs Numbers() {
StyleCounterSpeakAs result;
result.tag = Tag::Numbers;
return result;
}
bool IsNumbers() const {
return tag == Tag::Numbers;
}
static StyleCounterSpeakAs Words() {
StyleCounterSpeakAs result;
result.tag = Tag::Words;
return result;
}
bool IsWords() const {
return tag == Tag::Words;
}
static StyleCounterSpeakAs Ident(nsAtom *const &_0) {
StyleCounterSpeakAs result;
::new (&result.ident._0) (nsAtom*)(_0);
result.tag = Tag::Ident;
return result;
}
bool IsIdent() const {
return tag == Tag::Ident;
}
nsAtom*const & AsIdent() const {
MOZ_DIAGNOSTIC_ASSERT(IsIdent());
return ident._0;
}
bool operator==(const StyleCounterSpeakAs& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Ident: return ident == other.ident;
default: break;
}
return true;
}
bool operator!=(const StyleCounterSpeakAs& other) const {
return !(*this == other);
}
private:
StyleCounterSpeakAs() {
}
public:
~StyleCounterSpeakAs() {
switch (tag) {
case Tag::Ident: ident.~StyleIdent_Body(); break;
default: break;
}
}
StyleCounterSpeakAs(const StyleCounterSpeakAs& other)
: tag(other.tag) {
switch (tag) {
case Tag::Ident: ::new (&ident) (StyleIdent_Body)(other.ident); break;
default: break;
}
}
StyleCounterSpeakAs& operator=(const StyleCounterSpeakAs& other) {
if (this != &other) {
this->~StyleCounterSpeakAs();
new (this) StyleCounterSpeakAs(other);
}
return *this;
}
};
/// Bit-flags for pseudo-class. This should only be used for querying if a
/// page-rule applies.
///
struct StylePagePseudoClassFlags {
uint8_t bits;
constexpr explicit operator bool() const {
return !!bits;
}
constexpr StylePagePseudoClassFlags operator~() const {
return StylePagePseudoClassFlags { static_cast<decltype(bits)>(~bits) };
}
constexpr StylePagePseudoClassFlags operator|(const StylePagePseudoClassFlags& other) const {
return StylePagePseudoClassFlags { static_cast<decltype(bits)>(this->bits | other.bits) };
}
StylePagePseudoClassFlags& operator|=(const StylePagePseudoClassFlags& other) {
*this = (*this | other);
return *this;
}
constexpr StylePagePseudoClassFlags operator&(const StylePagePseudoClassFlags& other) const {
return StylePagePseudoClassFlags { static_cast<decltype(bits)>(this->bits & other.bits) };
}
StylePagePseudoClassFlags& operator&=(const StylePagePseudoClassFlags& other) {
*this = (*this & other);
return *this;
}
constexpr StylePagePseudoClassFlags operator^(const StylePagePseudoClassFlags& other) const {
return StylePagePseudoClassFlags { static_cast<decltype(bits)>(this->bits ^ other.bits) };
}
StylePagePseudoClassFlags& operator^=(const StylePagePseudoClassFlags& other) {
*this = (*this ^ other);
return *this;
}
bool operator==(const StylePagePseudoClassFlags& other) const {
return bits == other.bits;
}
bool operator!=(const StylePagePseudoClassFlags& other) const {
return bits != other.bits;
}
static const StylePagePseudoClassFlags NONE;
static const StylePagePseudoClassFlags FIRST;
static const StylePagePseudoClassFlags BLANK;
static const StylePagePseudoClassFlags LEFT;
static const StylePagePseudoClassFlags RIGHT;
};
/// No pseudo-classes
constexpr inline const StylePagePseudoClassFlags StylePagePseudoClassFlags::NONE = StylePagePseudoClassFlags{
/* .bits = */ (uint8_t)0
};
/// Flag for PagePseudoClass::First
constexpr inline const StylePagePseudoClassFlags StylePagePseudoClassFlags::FIRST = StylePagePseudoClassFlags{
/* .bits = */ (uint8_t)(1 << 0)
};
/// Flag for PagePseudoClass::Blank
constexpr inline const StylePagePseudoClassFlags StylePagePseudoClassFlags::BLANK = StylePagePseudoClassFlags{
/* .bits = */ (uint8_t)(1 << 1)
};
/// Flag for PagePseudoClass::Left
constexpr inline const StylePagePseudoClassFlags StylePagePseudoClassFlags::LEFT = StylePagePseudoClassFlags{
/* .bits = */ (uint8_t)(1 << 2)
};
/// Flag for PagePseudoClass::Right
constexpr inline const StylePagePseudoClassFlags StylePagePseudoClassFlags::RIGHT = StylePagePseudoClassFlags{
/* .bits = */ (uint8_t)(1 << 3)
};
/// The mode to use when parsing values.
struct StyleParsingMode {
uint8_t bits;
constexpr explicit operator bool() const {
return !!bits;
}
constexpr StyleParsingMode operator~() const {
return StyleParsingMode { static_cast<decltype(bits)>(~bits) };
}
constexpr StyleParsingMode operator|(const StyleParsingMode& other) const {
return StyleParsingMode { static_cast<decltype(bits)>(this->bits | other.bits) };
}
StyleParsingMode& operator|=(const StyleParsingMode& other) {
*this = (*this | other);
return *this;
}
constexpr StyleParsingMode operator&(const StyleParsingMode& other) const {
return StyleParsingMode { static_cast<decltype(bits)>(this->bits & other.bits) };
}
StyleParsingMode& operator&=(const StyleParsingMode& other) {
*this = (*this & other);
return *this;
}
constexpr StyleParsingMode operator^(const StyleParsingMode& other) const {
return StyleParsingMode { static_cast<decltype(bits)>(this->bits ^ other.bits) };
}
StyleParsingMode& operator^=(const StyleParsingMode& other) {
*this = (*this ^ other);
return *this;
}
bool operator==(const StyleParsingMode& other) const {
return bits == other.bits;
}
bool operator!=(const StyleParsingMode& other) const {
return bits != other.bits;
}
static const StyleParsingMode DEFAULT;
static const StyleParsingMode ALLOW_UNITLESS_LENGTH;
static const StyleParsingMode ALLOW_ALL_NUMERIC_VALUES;
static const StyleParsingMode DISALLOW_COMPUTATIONALLY_DEPENDENT;
};
/// In CSS; lengths must have units, except for zero values, where the unit can be omitted.
constexpr inline const StyleParsingMode StyleParsingMode::DEFAULT = StyleParsingMode{
/* .bits = */ (uint8_t)0
};
/// In SVG; a coordinate or length value without a unit identifier (e.g., "25") is assumed
/// to be in user units (px).
constexpr inline const StyleParsingMode StyleParsingMode::ALLOW_UNITLESS_LENGTH = StyleParsingMode{
/* .bits = */ (uint8_t)1
};
/// In SVG; out-of-range values are not treated as an error in parsing.
constexpr inline const StyleParsingMode StyleParsingMode::ALLOW_ALL_NUMERIC_VALUES = StyleParsingMode{
/* .bits = */ (uint8_t)(1 << 1)
};
/// In CSS Properties and Values, the initial value must be computationally
/// independent.
constexpr inline const StyleParsingMode StyleParsingMode::DISALLOW_COMPUTATIONALLY_DEPENDENT = StyleParsingMode{
/* .bits = */ (uint8_t)(1 << 2)
};
using StyleValueType = StyleCSSFloat;
/// a single entry in a piecewise linear function.
struct StylePiecewiseLinearFunctionEntry {
StyleValueType x;
StyleValueType y;
bool operator==(const StylePiecewiseLinearFunctionEntry& other) const {
return x == other.x &&
y == other.y;
}
bool operator!=(const StylePiecewiseLinearFunctionEntry& other) const {
return x != other.x ||
y != other.y;
}
};
/// Representation of a piecewise linear function, a series of linear functions.
struct StylePiecewiseLinearFunction {
StyleArcSlice<StylePiecewiseLinearFunctionEntry> entries;
bool operator==(const StylePiecewiseLinearFunction& other) const {
return entries == other.entries;
}
bool operator!=(const StylePiecewiseLinearFunction& other) const {
return entries != other.entries;
}
};
/// A generic easing function.
template<typename Integer, typename Number, typename LinearStops>
struct StyleTimingFunction {
enum class Tag : uint8_t {
/// `linear | ease | ease-in | ease-out | ease-in-out`
Keyword,
/// `cubic-bezier(<number>, <number>, <number>, <number>)`
CubicBezier,
/// `step-start | step-end | steps(<integer>, [ <step-position> ]?)`
/// `<step-position> = jump-start | jump-end | jump-none | jump-both | start | end`
Steps,
/// linear([<linear-stop>]#)
/// <linear-stop> = <output> && <linear-stop-length>?
/// <linear-stop-length> = <percentage>{1, 2}
LinearFunction,
};
struct StyleKeyword_Body {
StyleTimingKeyword _0;
bool operator==(const StyleKeyword_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleKeyword_Body& other) const {
return _0 != other._0;
}
};
struct StyleCubicBezier_Body {
Number x1;
Number y1;
Number x2;
Number y2;
bool operator==(const StyleCubicBezier_Body& other) const {
return x1 == other.x1 &&
y1 == other.y1 &&
x2 == other.x2 &&
y2 == other.y2;
}
bool operator!=(const StyleCubicBezier_Body& other) const {
return x1 != other.x1 ||
y1 != other.y1 ||
x2 != other.x2 ||
y2 != other.y2;
}
};
struct StyleSteps_Body {
Integer _0;
StyleStepPosition _1;
bool operator==(const StyleSteps_Body& other) const {
return _0 == other._0 &&
_1 == other._1;
}
bool operator!=(const StyleSteps_Body& other) const {
return _0 != other._0 ||
_1 != other._1;
}
};
struct StyleLinearFunction_Body {
LinearStops _0;
bool operator==(const StyleLinearFunction_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleLinearFunction_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StyleKeyword_Body keyword;
StyleCubicBezier_Body cubic_bezier;
StyleSteps_Body steps;
StyleLinearFunction_Body linear_function;
};
static StyleTimingFunction Keyword(const StyleTimingKeyword &_0) {
StyleTimingFunction result;
::new (&result.keyword._0) (StyleTimingKeyword)(_0);
result.tag = Tag::Keyword;
return result;
}
bool IsKeyword() const {
return tag == Tag::Keyword;
}
const StyleTimingKeyword& AsKeyword() const {
MOZ_DIAGNOSTIC_ASSERT(IsKeyword());
return keyword._0;
}
static StyleTimingFunction CubicBezier(const Number &x1,
const Number &y1,
const Number &x2,
const Number &y2) {
StyleTimingFunction result;
::new (&result.cubic_bezier.x1) (Number)(x1);
::new (&result.cubic_bezier.y1) (Number)(y1);
::new (&result.cubic_bezier.x2) (Number)(x2);
::new (&result.cubic_bezier.y2) (Number)(y2);
result.tag = Tag::CubicBezier;
return result;
}
bool IsCubicBezier() const {
return tag == Tag::CubicBezier;
}
const StyleCubicBezier_Body& AsCubicBezier() const {
MOZ_DIAGNOSTIC_ASSERT(IsCubicBezier());
return cubic_bezier;
}
static StyleTimingFunction Steps(const Integer &_0,
const StyleStepPosition &_1) {
StyleTimingFunction result;
::new (&result.steps._0) (Integer)(_0);
::new (&result.steps._1) (StyleStepPosition)(_1);
result.tag = Tag::Steps;
return result;
}
bool IsSteps() const {
return tag == Tag::Steps;
}
const StyleSteps_Body& AsSteps() const {
MOZ_DIAGNOSTIC_ASSERT(IsSteps());
return steps;
}
static StyleTimingFunction LinearFunction(const LinearStops &_0) {
StyleTimingFunction result;
::new (&result.linear_function._0) (LinearStops)(_0);
result.tag = Tag::LinearFunction;
return result;
}
bool IsLinearFunction() const {
return tag == Tag::LinearFunction;
}
const LinearStops& AsLinearFunction() const {
MOZ_DIAGNOSTIC_ASSERT(IsLinearFunction());
return linear_function._0;
}
bool operator==(const StyleTimingFunction& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Keyword: return keyword == other.keyword;
case Tag::CubicBezier: return cubic_bezier == other.cubic_bezier;
case Tag::Steps: return steps == other.steps;
case Tag::LinearFunction: return linear_function == other.linear_function;
}
return true;
}
bool operator!=(const StyleTimingFunction& other) const {
return !(*this == other);
}
private:
StyleTimingFunction() {
}
public:
~StyleTimingFunction() {
switch (tag) {
case Tag::Keyword: keyword.~StyleKeyword_Body(); break;
case Tag::CubicBezier: cubic_bezier.~StyleCubicBezier_Body(); break;
case Tag::Steps: steps.~StyleSteps_Body(); break;
case Tag::LinearFunction: linear_function.~StyleLinearFunction_Body(); break;
}
}
StyleTimingFunction(const StyleTimingFunction& other)
: tag(other.tag) {
switch (tag) {
case Tag::Keyword: ::new (&keyword) (StyleKeyword_Body)(other.keyword); break;
case Tag::CubicBezier: ::new (&cubic_bezier) (StyleCubicBezier_Body)(other.cubic_bezier); break;
case Tag::Steps: ::new (&steps) (StyleSteps_Body)(other.steps); break;
case Tag::LinearFunction: ::new (&linear_function) (StyleLinearFunction_Body)(other.linear_function); break;
}
}
StyleTimingFunction& operator=(const StyleTimingFunction& other) {
if (this != &other) {
this->~StyleTimingFunction();
new (this) StyleTimingFunction(other);
}
return *this;
}
public:
bool IsLinearKeyword() const { return IsKeyword() && AsKeyword() == StyleTimingKeyword::Linear; }
static StyleTimingFunction LinearKeyword() { return Keyword(StyleTimingKeyword::Linear); }
inline double At(double, bool aBeforeFlag) const;
inline void AppendToString(nsACString&) const;
inline static double GetPortion(const Maybe<StyleTimingFunction>&, double, bool aBeforeFlag);
};
/// A computed timing function.
using StyleComputedTimingFunction = StyleTimingFunction<StyleInteger, StyleNumber, StylePiecewiseLinearFunction>;
/// A wrapper of Number, but the value >= 0.
using StyleNonNegativeNumber = StyleNonNegative<StyleCSSFloat>;
/// A wrapper of values between zero and one.
template<typename T>
using StyleZeroToOne = T;
/// A wrapper of Number, but the value between 0 and 1
using StyleZeroToOneNumber = StyleZeroToOne<StyleCSSFloat>;
/// A wrapper of Length, whose value must be >= 0.
using StyleNonNegativeLength = StyleNonNegative<StyleLength>;
/// The 3 components that make up a color. (Does not include the alpha component)
struct StyleColorComponents {
float _0;
float _1;
float _2;
bool operator==(const StyleColorComponents& other) const {
return _0 == other._0 &&
_1 == other._1 &&
_2 == other._2;
}
bool operator!=(const StyleColorComponents& other) const {
return _0 != other._0 ||
_1 != other._1 ||
_2 != other._2;
}
};
/// Flags used when serializing colors.
struct StyleColorFlags {
uint8_t _0;
constexpr explicit operator bool() const {
return !!_0;
}
constexpr StyleColorFlags operator~() const {
return StyleColorFlags { static_cast<decltype(_0)>(~_0) };
}
constexpr StyleColorFlags operator|(const StyleColorFlags& other) const {
return StyleColorFlags { static_cast<decltype(_0)>(this->_0 | other._0) };
}
StyleColorFlags& operator|=(const StyleColorFlags& other) {
*this = (*this | other);
return *this;
}
constexpr StyleColorFlags operator&(const StyleColorFlags& other) const {
return StyleColorFlags { static_cast<decltype(_0)>(this->_0 & other._0) };
}
StyleColorFlags& operator&=(const StyleColorFlags& other) {
*this = (*this & other);
return *this;
}
constexpr StyleColorFlags operator^(const StyleColorFlags& other) const {
return StyleColorFlags { static_cast<decltype(_0)>(this->_0 ^ other._0) };
}
StyleColorFlags& operator^=(const StyleColorFlags& other) {
*this = (*this ^ other);
return *this;
}
bool operator==(const StyleColorFlags& other) const {
return _0 == other._0;
}
bool operator!=(const StyleColorFlags& other) const {
return _0 != other._0;
}
static const StyleColorFlags C0_IS_NONE;
static const StyleColorFlags C1_IS_NONE;
static const StyleColorFlags C2_IS_NONE;
static const StyleColorFlags ALPHA_IS_NONE;
static const StyleColorFlags IS_LEGACY_SRGB;
};
/// Whether the 1st color component is `none`.
constexpr inline const StyleColorFlags StyleColorFlags::C0_IS_NONE = StyleColorFlags{
/* ._0 = */ (uint8_t)(1 << 0)
};
/// Whether the 2nd color component is `none`.
constexpr inline const StyleColorFlags StyleColorFlags::C1_IS_NONE = StyleColorFlags{
/* ._0 = */ (uint8_t)(1 << 1)
};
/// Whether the 3rd color component is `none`.
constexpr inline const StyleColorFlags StyleColorFlags::C2_IS_NONE = StyleColorFlags{
/* ._0 = */ (uint8_t)(1 << 2)
};
/// Whether the alpha component is `none`.
constexpr inline const StyleColorFlags StyleColorFlags::ALPHA_IS_NONE = StyleColorFlags{
/* ._0 = */ (uint8_t)(1 << 3)
};
/// Marks that this color is in the legacy color format. This flag is
/// only valid for the `Srgb` color space.
constexpr inline const StyleColorFlags StyleColorFlags::IS_LEGACY_SRGB = StyleColorFlags{
/* ._0 = */ (uint8_t)(1 << 4)
};
/// An absolutely specified color, using either rgb(), rgba(), lab(), lch(),
/// oklab(), oklch() or color().
struct StyleAbsoluteColor {
/// The 3 components that make up colors in any color space.
StyleColorComponents components;
/// The alpha component of the color.
float alpha;
/// The current color space that the components represent.
StyleColorSpace color_space;
/// Extra flags used durring serialization of this color.
StyleColorFlags flags;
bool operator==(const StyleAbsoluteColor& other) const {
return components == other.components &&
alpha == other.alpha &&
color_space == other.color_space &&
flags == other.flags;
}
bool operator!=(const StyleAbsoluteColor& other) const {
return components != other.components ||
alpha != other.alpha ||
color_space != other.color_space ||
flags != other.flags;
}
/**
* Create a new AbsoluteColor in the sRGB color space in legacy color syntax.
*/
static inline StyleAbsoluteColor SrgbLegacy(float red, float green, float blue, float alpha);
static inline StyleAbsoluteColor FromColor(nscolor);
/**
* Convert this color into the given color space.
*/
StyleAbsoluteColor ToColorSpace(StyleColorSpace aColorSpace) const;
/**
* Convert this color to an nscolor. The color will be converted to sRGB first
* if required.
*/
nscolor ToColor() const;
static const StyleAbsoluteColor TRANSPARENT_BLACK;
static const StyleAbsoluteColor BLACK;
static const StyleAbsoluteColor WHITE;
};
/// A fully transparent color in the legacy syntax.
constexpr inline const StyleAbsoluteColor StyleAbsoluteColor::TRANSPARENT_BLACK = StyleAbsoluteColor{
/* .components = */ StyleColorComponents{
/* ._0 = */ 0.0,
/* ._1 = */ 0.0,
/* ._2 = */ 0.0
},
/* .alpha = */ 0.0,
/* .color_space = */ StyleColorSpace::Srgb,
/* .flags = */ StyleColorFlags::IS_LEGACY_SRGB
};
/// An opaque black color in the legacy syntax.
constexpr inline const StyleAbsoluteColor StyleAbsoluteColor::BLACK = StyleAbsoluteColor{
/* .components = */ StyleColorComponents{
/* ._0 = */ 0.0,
/* ._1 = */ 0.0,
/* ._2 = */ 0.0
},
/* .alpha = */ 1.0,
/* .color_space = */ StyleColorSpace::Srgb,
/* .flags = */ StyleColorFlags::IS_LEGACY_SRGB
};
/// An opaque white color in the legacy syntax.
constexpr inline const StyleAbsoluteColor StyleAbsoluteColor::WHITE = StyleAbsoluteColor{
/* .components = */ StyleColorComponents{
/* ._0 = */ 1.0,
/* ._1 = */ 1.0,
/* ._2 = */ 1.0
},
/* .alpha = */ 1.0,
/* .color_space = */ StyleColorSpace::Srgb,
/* .flags = */ StyleColorFlags::IS_LEGACY_SRGB
};
/// An optional value, much like `Option<T>`, but with a defined struct layout
/// to be able to use it from C++ as well.
///
/// Note that this is relatively inefficient, struct-layout-wise, as you have
/// one byte for the tag, but padding to the alignment of T. If you have
/// multiple optional values and care about struct compactness, you might be
/// better off "coalescing" the combinations into a parent enum. But that
/// shouldn't matter for most use cases.
template<typename T>
struct StyleOptional {
enum class Tag : uint8_t {
None,
Some,
};
struct StyleSome_Body {
T _0;
bool operator==(const StyleSome_Body& other) const {
return _0 == other._0;
}
bool operator!=(const StyleSome_Body& other) const {
return _0 != other._0;
}
};
Tag tag;
union {
StyleSome_Body some;
};
static StyleOptional None() {
StyleOptional result;
result.tag = Tag::None;
return result;
}
bool IsNone() const {
return tag == Tag::None;
}
static StyleOptional Some(const T &_0) {
StyleOptional result;
::new (&result.some._0) (T)(_0);
result.tag = Tag::Some;
return result;
}
bool IsSome() const {
return tag == Tag::Some;
}
const T& AsSome() const {
MOZ_DIAGNOSTIC_ASSERT(IsSome());
return some._0;
}
bool operator==(const StyleOptional& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Some: return some == other.some;
default: break;
}
return true;
}
bool operator!=(const StyleOptional& other) const {
return !(*this == other);
}
private:
StyleOptional() {
}
public:
~StyleOptional() {
switch (tag) {
case Tag::Some: some.~StyleSome_Body(); break;
default: break;
}
}
StyleOptional(const StyleOptional& other)
: tag(other.tag) {
switch (tag) {
case Tag::Some: ::new (&some) (StyleSome_Body)(other.some); break;
default: break;
}
}
StyleOptional& operator=(const StyleOptional& other) {
if (this != &other) {
this->~StyleOptional();
new (this) StyleOptional(other);
}
return *this;
}
};
/// Either a percentage or a number.
union StyleNumberOrPercentageComponent {
enum class Tag : uint8_t {
/// `<number>`.
Number,
/// `<percentage>`
/// The value as a float, divided by 100 so that the nominal range is 0.0 to 1.0.
Percentage,
};
struct Number_Body {
Tag tag;
float _0;
bool operator==(const Number_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Number_Body& other) const {
return _0 != other._0;
}
};
struct Percentage_Body {
Tag tag;
float _0;
bool operator==(const Percentage_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Percentage_Body& other) const {
return _0 != other._0;
}
};
struct {
Tag tag;
};
Number_Body number;
Percentage_Body percentage;
static StyleNumberOrPercentageComponent Number(const float &_0) {
StyleNumberOrPercentageComponent result;
::new (&result.number._0) (float)(_0);
result.tag = Tag::Number;
return result;
}
bool IsNumber() const {
return tag == Tag::Number;
}
const float& AsNumber() const {
MOZ_DIAGNOSTIC_ASSERT(IsNumber());
return number._0;
}
static StyleNumberOrPercentageComponent Percentage(const float &_0) {
StyleNumberOrPercentageComponent result;
::new (&result.percentage._0) (float)(_0);
result.tag = Tag::Percentage;
return result;
}
bool IsPercentage() const {
return tag == Tag::Percentage;
}
const float& AsPercentage() const {
MOZ_DIAGNOSTIC_ASSERT(IsPercentage());
return percentage._0;
}
bool operator==(const StyleNumberOrPercentageComponent& other) const {
if (tag != other.tag) {
return false;
}
switch (tag) {
case Tag::Number: return number == other.number;
case Tag::Percentage: return percentage == other.percentage;
}
return true;
}
bool operator!=(const StyleNumberOrPercentageComponent& other) const {
return !(*this == other);
}
private:
StyleNumberOrPercentageComponent() {
}
public:
~StyleNumberOrPercentageComponent() {
switch (tag) {
case Tag::Number: number.~Number_Body(); break;
case Tag::Percentage: percentage.~Percentage_Body(); break;
}
}
StyleNumberOrPercentageComponent(const StyleNumberOrPercentageComponent& other)
: tag(other.tag) {
switch (tag) {
case Tag::Number: ::new (&number) (Number_Body)(other.number); break;
case Tag::Percentage: ::new (&percentage) (Percentage_Body)(other.percentage); break;
}
}
StyleNumberOrPercentageComponent& operator=(const StyleNumberOrPercentageComponent& other) {
if (this != &other) {
this->~StyleNumberOrPercentageComponent();
new (this) StyleNumberOrPercentageComponent(other);
}
return *this;
}
};
/// Represents an absolute length with its unit
union StyleAbsoluteLength {
enum class Tag : uint8_t {
/// An absolute length in pixels (px)
Px,
/// An absolute length in inches (in)
In,
/// An absolute length in centimeters (cm)
Cm,
/// An absolute length in millimeters (mm)
Mm,
/// An absolute length in quarter-millimeters (q)
Q,
/// An absolute length in points (pt)
Pt,
/// An absolute length in pica (pc)
Pc,
};
struct Px_Body {
Tag tag;
StyleCSSFloat _0;
bool operator==(const Px_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Px_Body& other) const {
return _0 != other._0;
}
};
struct In_Body {
Tag tag;
StyleCSSFloat _0;
bool operator==(const In_Body& other) const {
return _0 == other._0;
}
bool operator!=(const In_Body& other) const {
return _0 != other._0;
}
};
struct Cm_Body {
Tag tag;
StyleCSSFloat _0;
bool operator==(const Cm_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Cm_Body& other) const {
return _0 != other._0;
}
};
struct Mm_Body {
Tag tag;
StyleCSSFloat _0;
bool operator==(const Mm_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Mm_Body& other) const {
return _0 != other._0;
}
};
struct Q_Body {
Tag tag;
StyleCSSFloat _0;
bool operator==(const Q_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Q_Body& other) const {
return _0 != other._0;
}
};
struct Pt_Body {
Tag tag;
StyleCSSFloat _0;
bool operator==(const Pt_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Pt_Body& other) const {
return _0 != other._0;
}
};
struct Pc_Body {
Tag tag;
StyleCSSFloat _0;
bool operator==(const Pc_Body& other) const {
return _0 == other._0;
}
bool operator!=(const Pc_Body& other) const {
return _0 != other._0;
}
};
struct {
Tag tag;
};
Px_Body px;
In_Body in;
Cm_Body cm;
Mm_Body mm;
Q_Body q;
Pt_Body pt;
Pc_Body pc;
static StyleAbsoluteLength Px(const StyleCSSFloat &_0) {
StyleAbsoluteLength result;
::new (&result.px._0) (StyleCSSFloat)(_0);
result.tag = Tag::Px;
return result;
}
bool IsPx() const {
return tag == Tag::Px;
}
const StyleCSSFloat& AsPx() const {
MOZ_DIAGNOSTIC_ASSERT(IsPx());
return px._0;
}
static StyleAbsoluteLength In(const StyleCSSFloat &_0) {
StyleAbsoluteLength result;
::new (&result.in._0) (StyleCSSFloat)(_0);
result.tag = Tag::In;
return result;
}
bool IsIn() const {
return tag == Tag::In;
}
const StyleCSSFloat& AsIn() const {
MOZ_DIAGNOSTIC_ASSERT(IsIn());
return in._0;
}
static StyleAbsoluteLength Cm(const StyleCSSFloat &_0) {
StyleAbsoluteLength result;
::new (&result.cm._0) (StyleCSSFloat)(_0);
result.tag = Tag::Cm;
return result;
}
bool IsCm() const {
return tag == Tag::Cm;
}
const StyleCSSFloat& AsCm() const {
MOZ_DIAGNOSTIC_ASSERT(IsCm());
return cm._0;
}
static StyleAbsoluteLength Mm(const StyleCSSFloat &_0) {
StyleAbsoluteLength result;
::new (&result.mm._0) (StyleCSSFloat)(_0);
result.tag = Tag::Mm;
return result;
}
bool IsMm() const {
return tag == Tag::Mm;
}
const StyleCSSFloat& AsMm() const {
MOZ_DIAGNOSTIC_ASSERT(IsMm());
return mm._0;
}
static StyleAbsoluteLength Q(const StyleCSSFloat &_0) {
StyleAbsoluteLength result;
::new (&result.q._0) (StyleCSSFloat)(_0);
result.tag = Tag::Q;
return result;
}
bool IsQ() const {
return tag == Tag::Q;
}
const StyleCSSFloat& AsQ() const {
MOZ_DIAGNOSTIC_ASSERT(IsQ());
return q._0;
}
static StyleAbsoluteLength Pt(const StyleCSSFloat &_0) {
StyleAbsoluteLength result;
::new (&result.pt._0) (StyleCSSFloat)(_0);
result.tag = Tag::Pt;
return result;
}
bool IsPt() const {
return tag == Tag::Pt;
}
const StyleCSSFloat& AsPt() const {