Bug 1844195 - Avoid duplicating rust and C++ display definitions. r=layout-reviewers,jfkthame

We need to inline Self::new() so cbindgen generates the constants, which
is kinda lame, but seems better than duplicating the values and type
definitions.

Differential Revision: https://phabricator.services.mozilla.com/D183921
This commit is contained in:
Emilio Cobos Álvarez
2023-07-26 06:46:32 +00:00
parent 3e07e5796c
commit ec9b2f185b
13 changed files with 194 additions and 252 deletions

View File

@@ -3185,13 +3185,13 @@ void nsRange::GetInnerTextNoFlush(DOMString& aValue, ErrorResult& aError,
if (currentNode->IsHTMLElement(nsGkAtoms::br)) { if (currentNode->IsHTMLElement(nsGkAtoms::br)) {
result.Append('\n'); result.Append('\n');
} }
switch (f->StyleDisplay()->mDisplay) { switch (f->StyleDisplay()->DisplayInside()) {
case StyleDisplay::TableCell: case StyleDisplayInside::TableCell:
if (!IsLastCellOfRow(f)) { if (!IsLastCellOfRow(f)) {
result.Append('\t'); result.Append('\t');
} }
break; break;
case StyleDisplay::TableRow: case StyleDisplayInside::TableRow:
if (!IsLastRowOfRowGroup(f) || if (!IsLastRowOfRowGroup(f) ||
!IsLastNonemptyRowGroupOfTable(f->GetParent())) { !IsLastNonemptyRowGroupOfTable(f->GetParent())) {
result.Append('\n'); result.Append('\n');

View File

@@ -1314,7 +1314,7 @@ void nsGenericHTMLElement::MapCommonAttributesInto(
MapCommonAttributesIntoExceptHidden(aBuilder); MapCommonAttributesIntoExceptHidden(aBuilder);
if (!aBuilder.PropertyIsSet(eCSSProperty_display)) { if (!aBuilder.PropertyIsSet(eCSSProperty_display)) {
if (aBuilder.GetAttr(nsGkAtoms::hidden)) { if (aBuilder.GetAttr(nsGkAtoms::hidden)) {
aBuilder.SetKeywordValue(eCSSProperty_display, StyleDisplay::None); aBuilder.SetKeywordValue(eCSSProperty_display, StyleDisplay::None._0);
} }
} }
} }

View File

@@ -5277,7 +5277,7 @@ nsCSSFrameConstructor::FindElementData(const Element& aElement,
bool isRootElement = false; bool isRootElement = false;
uint16_t rawDisplayValue = uint16_t rawDisplayValue =
Servo_ComputedValues_BlockifiedDisplay(&aStyle, isRootElement); Servo_ComputedValues_BlockifiedDisplay(&aStyle, isRootElement);
display.mDisplay = StyleDisplay(rawDisplayValue); display.mDisplay = StyleDisplay{rawDisplayValue};
return FindDisplayData(display, aElement); return FindDisplayData(display, aElement);
} }
@@ -8808,8 +8808,7 @@ void nsCSSFrameConstructor::CreateNeededAnonFlexOrGridItems(
/* static */ nsCSSFrameConstructor::RubyWhitespaceType /* static */ nsCSSFrameConstructor::RubyWhitespaceType
nsCSSFrameConstructor::ComputeRubyWhitespaceType(StyleDisplay aPrevDisplay, nsCSSFrameConstructor::ComputeRubyWhitespaceType(StyleDisplay aPrevDisplay,
StyleDisplay aNextDisplay) { StyleDisplay aNextDisplay) {
MOZ_ASSERT(nsStyleDisplay::IsRubyDisplayType(aPrevDisplay) && MOZ_ASSERT(aPrevDisplay.IsRuby() && aNextDisplay.IsRuby());
nsStyleDisplay::IsRubyDisplayType(aNextDisplay));
if (aPrevDisplay == aNextDisplay && if (aPrevDisplay == aNextDisplay &&
(aPrevDisplay == StyleDisplay::RubyBase || (aPrevDisplay == StyleDisplay::RubyBase ||
aPrevDisplay == StyleDisplay::RubyText)) { aPrevDisplay == StyleDisplay::RubyText)) {
@@ -9254,10 +9253,9 @@ void nsCSSFrameConstructor::WrapItemsInPseudoParent(
pseudoType); pseudoType);
} }
FrameConstructionItem* newItem = new (this) // Use the content of our parent frame
FrameConstructionItem(&pseudoData.mFCData, auto* newItem = new (this) FrameConstructionItem(
// Use the content of our parent frame &pseudoData.mFCData, aParentContent, wrapperStyle.forget(), true);
aParentContent, wrapperStyle.forget(), true);
const nsStyleDisplay* disp = newItem->mComputedStyle->StyleDisplay(); const nsStyleDisplay* disp = newItem->mComputedStyle->StyleDisplay();
// Here we're cheating a tad... technically, table-internal items should be // Here we're cheating a tad... technically, table-internal items should be

View File

@@ -1217,8 +1217,7 @@ static bool IsLineClampRoot(const nsBlockFrame* aFrame) {
} }
return aFrame->StyleDisplay()->mOriginalDisplay; return aFrame->StyleDisplay()->mOriginalDisplay;
}(); }();
return nsStyleDisplay::DisplayInside(origDisplay) == return origDisplay.Inside() == StyleDisplayInside::WebkitBox;
StyleDisplayInside::WebkitBox;
} }
bool nsBlockFrame::IsInLineClampContext() const { bool nsBlockFrame::IsInLineClampContext() const {

View File

@@ -518,19 +518,18 @@ static bool IsFontSizeInflationContainer(nsIFrame* aFrame,
LayoutFrameType frameType = aFrame->Type(); LayoutFrameType frameType = aFrame->Type();
bool isInline = bool isInline =
(nsStyleDisplay::IsInlineFlow(aFrame->GetDisplay()) || aFrame->GetDisplay().IsInlineFlow() || RubyUtils::IsRubyBox(frameType) ||
RubyUtils::IsRubyBox(frameType) || (aStyleDisplay->IsFloatingStyle() &&
(aStyleDisplay->IsFloatingStyle() && frameType == LayoutFrameType::Letter) ||
frameType == LayoutFrameType::Letter) || // Given multiple frames for the same node, only the
// Given multiple frames for the same node, only the // outer one should be considered a container.
// outer one should be considered a container. // (Important, e.g., for nsSelectsAreaFrame.)
// (Important, e.g., for nsSelectsAreaFrame.) (aFrame->GetParent()->GetContent() == content) ||
(aFrame->GetParent()->GetContent() == content) || (content &&
(content && // Form controls shouldn't become inflation containers.
// Form controls shouldn't become inflation containers. (content->IsAnyOfHTMLElements(nsGkAtoms::option, nsGkAtoms::optgroup,
(content->IsAnyOfHTMLElements( nsGkAtoms::select, nsGkAtoms::input,
nsGkAtoms::option, nsGkAtoms::optgroup, nsGkAtoms::select, nsGkAtoms::button, nsGkAtoms::textarea)));
nsGkAtoms::input, nsGkAtoms::button, nsGkAtoms::textarea))));
NS_ASSERTION(!aFrame->IsFrameOfType(nsIFrame::eLineParticipant) || isInline || NS_ASSERTION(!aFrame->IsFrameOfType(nsIFrame::eLineParticipant) || isInline ||
// br frames and mathml frames report being line // br frames and mathml frames report being line
// participants even when their position or display is // participants even when their position or display is
@@ -2439,10 +2438,9 @@ bool nsIFrame::CanBeDynamicReflowRoot() const {
return false; return false;
} }
auto& display = *StyleDisplay(); const auto& display = *StyleDisplay();
if (IsFrameOfType(nsIFrame::eLineParticipant) || if (IsFrameOfType(nsIFrame::eLineParticipant) || display.mDisplay.IsRuby() ||
nsStyleDisplay::IsRubyDisplayType(display.mDisplay) || display.IsInnerTableStyle() ||
display.DisplayOutside() == StyleDisplayOutside::InternalTable ||
display.DisplayInside() == StyleDisplayInside::Table) { display.DisplayInside() == StyleDisplayInside::Table) {
// We have a display type where 'width' and 'height' don't actually set the // We have a display type where 'width' and 'height' don't actually set the
// width or height (i.e., the size depends on content). // width or height (i.e., the size depends on content).
@@ -2456,7 +2454,7 @@ bool nsIFrame::CanBeDynamicReflowRoot() const {
// //
// FIXME: For display:block, we should probably optimize inline-size: auto. // FIXME: For display:block, we should probably optimize inline-size: auto.
// FIXME: Other flex and grid cases? // FIXME: Other flex and grid cases?
auto& pos = *StylePosition(); const auto& pos = *StylePosition();
const auto& width = pos.mWidth; const auto& width = pos.mWidth;
const auto& height = pos.mHeight; const auto& height = pos.mHeight;
if (!width.IsLengthPercentage() || width.HasPercent() || if (!width.IsLengthPercentage() || width.HasPercent() ||

View File

@@ -4735,10 +4735,10 @@ void nsTextFrame::GetTextDecorations(
// If we're on a ruby frame other than ruby text container, we // If we're on a ruby frame other than ruby text container, we
// should continue. // should continue.
mozilla::StyleDisplay display = f->GetDisplay(); mozilla::StyleDisplay display = f->GetDisplay();
if (!nsStyleDisplay::IsInlineFlow(display) && if (!display.IsInlineFlow() &&
(!nsStyleDisplay::IsRubyDisplayType(display) || (!display.IsRuby() ||
display == mozilla::StyleDisplay::RubyTextContainer) && display == mozilla::StyleDisplay::RubyTextContainer) &&
nsStyleDisplay::IsDisplayTypeInlineOutside(display)) { display.IsInlineOutside()) {
break; break;
} }

View File

@@ -1085,6 +1085,45 @@ inline StyleViewTimelineInset::StyleGenericViewTimelineInset()
: start(LengthPercentageOrAuto::Auto()), : start(LengthPercentageOrAuto::Auto()),
end(LengthPercentageOrAuto::Auto()) {} end(LengthPercentageOrAuto::Auto()) {}
inline StyleDisplayOutside StyleDisplay::Outside() const {
return StyleDisplayOutside((_0 & OUTSIDE_MASK) >> OUTSIDE_SHIFT);
}
inline StyleDisplayInside StyleDisplay::Inside() const {
return StyleDisplayInside(_0 & INSIDE_MASK);
}
inline bool StyleDisplay::IsListItem() const { return _0 & LIST_ITEM_MASK; }
inline bool StyleDisplay::IsInternalTable() const {
return Outside() == StyleDisplayOutside::InternalTable;
}
inline bool StyleDisplay::IsInternalTableExceptCell() const {
return IsInternalTable() && *this != TableCell;
}
inline bool StyleDisplay::IsInternalRuby() const {
return Outside() == StyleDisplayOutside::InternalRuby;
}
inline bool StyleDisplay::IsRuby() const {
return Inside() == StyleDisplayInside::Ruby || IsInternalRuby();
}
inline bool StyleDisplay::IsInlineFlow() const {
return Outside() == StyleDisplayOutside::Inline &&
Inside() == StyleDisplayInside::Flow;
}
inline bool StyleDisplay::IsInlineInside() const {
return IsInlineFlow() || IsRuby();
}
inline bool StyleDisplay::IsInlineOutside() const {
return Outside() == StyleDisplayOutside::Inline || IsInternalRuby();
}
} // namespace mozilla } // namespace mozilla
#endif #endif

View File

@@ -20,78 +20,6 @@
namespace mozilla { namespace mozilla {
static constexpr uint16_t STYLE_DISPLAY_LIST_ITEM_BIT = 0x8000;
static constexpr uint8_t STYLE_DISPLAY_OUTSIDE_BITS = 7;
static constexpr uint8_t STYLE_DISPLAY_INSIDE_BITS = 8;
// The `display` longhand.
uint16_t constexpr StyleDisplayFrom(StyleDisplayOutside aOuter,
StyleDisplayInside aInner) {
return uint16_t(uint16_t(aOuter) << STYLE_DISPLAY_INSIDE_BITS) |
uint16_t(aInner);
}
enum class StyleDisplay : uint16_t {
// These MUST be in sync with the Rust enum values in
// servo/components/style/values/specified/box.rs
/// https://drafts.csswg.org/css-display/#the-display-properties
None = StyleDisplayFrom(StyleDisplayOutside::None, StyleDisplayInside::None),
Contents =
StyleDisplayFrom(StyleDisplayOutside::None, StyleDisplayInside::Contents),
Inline =
StyleDisplayFrom(StyleDisplayOutside::Inline, StyleDisplayInside::Flow),
Block =
StyleDisplayFrom(StyleDisplayOutside::Block, StyleDisplayInside::Flow),
FlowRoot = StyleDisplayFrom(StyleDisplayOutside::Block,
StyleDisplayInside::FlowRoot),
Flex = StyleDisplayFrom(StyleDisplayOutside::Block, StyleDisplayInside::Flex),
Grid = StyleDisplayFrom(StyleDisplayOutside::Block, StyleDisplayInside::Grid),
Table =
StyleDisplayFrom(StyleDisplayOutside::Block, StyleDisplayInside::Table),
InlineTable =
StyleDisplayFrom(StyleDisplayOutside::Inline, StyleDisplayInside::Table),
TableCaption = StyleDisplayFrom(StyleDisplayOutside::TableCaption,
StyleDisplayInside::Flow),
Ruby =
StyleDisplayFrom(StyleDisplayOutside::Inline, StyleDisplayInside::Ruby),
WebkitBox = StyleDisplayFrom(StyleDisplayOutside::Block,
StyleDisplayInside::WebkitBox),
WebkitInlineBox = StyleDisplayFrom(StyleDisplayOutside::Inline,
StyleDisplayInside::WebkitBox),
ListItem = Block | STYLE_DISPLAY_LIST_ITEM_BIT,
/// Internal table boxes.
TableRowGroup = StyleDisplayFrom(StyleDisplayOutside::InternalTable,
StyleDisplayInside::TableRowGroup),
TableHeaderGroup = StyleDisplayFrom(StyleDisplayOutside::InternalTable,
StyleDisplayInside::TableHeaderGroup),
TableFooterGroup = StyleDisplayFrom(StyleDisplayOutside::InternalTable,
StyleDisplayInside::TableFooterGroup),
TableColumn = StyleDisplayFrom(StyleDisplayOutside::InternalTable,
StyleDisplayInside::TableColumn),
TableColumnGroup = StyleDisplayFrom(StyleDisplayOutside::InternalTable,
StyleDisplayInside::TableColumnGroup),
TableRow = StyleDisplayFrom(StyleDisplayOutside::InternalTable,
StyleDisplayInside::TableRow),
TableCell = StyleDisplayFrom(StyleDisplayOutside::InternalTable,
StyleDisplayInside::TableCell),
/// Internal ruby boxes.
RubyBase = StyleDisplayFrom(StyleDisplayOutside::InternalRuby,
StyleDisplayInside::RubyBase),
RubyBaseContainer = StyleDisplayFrom(StyleDisplayOutside::InternalRuby,
StyleDisplayInside::RubyBaseContainer),
RubyText = StyleDisplayFrom(StyleDisplayOutside::InternalRuby,
StyleDisplayInside::RubyText),
RubyTextContainer = StyleDisplayFrom(StyleDisplayOutside::InternalRuby,
StyleDisplayInside::RubyTextContainer),
};
// The order of the StyleDisplay values isn't meaningful.
bool operator<(const StyleDisplay&, const StyleDisplay&) = delete;
bool operator<=(const StyleDisplay&, const StyleDisplay&) = delete;
bool operator>(const StyleDisplay&, const StyleDisplay&) = delete;
bool operator>=(const StyleDisplay&, const StyleDisplay&) = delete;
// box-align // box-align
enum class StyleBoxAlign : uint8_t { enum class StyleBoxAlign : uint8_t {
Stretch, Stretch,

View File

@@ -1456,81 +1456,31 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
} }
} }
static mozilla::StyleDisplayOutside DisplayOutside(
mozilla::StyleDisplay aDisplay) {
return mozilla::StyleDisplayOutside(
(uint16_t(aDisplay) >> mozilla::STYLE_DISPLAY_INSIDE_BITS) &
uint16_t(((1 << mozilla::STYLE_DISPLAY_OUTSIDE_BITS) - 1)));
}
mozilla::StyleDisplayOutside DisplayOutside() const { mozilla::StyleDisplayOutside DisplayOutside() const {
return DisplayOutside(mDisplay); return mDisplay.Outside();
}
static mozilla::StyleDisplayInside DisplayInside(
mozilla::StyleDisplay aDisplay) {
return mozilla::StyleDisplayInside(
uint16_t(aDisplay) &
uint16_t(((1 << mozilla::STYLE_DISPLAY_INSIDE_BITS) - 1)));
} }
mozilla::StyleDisplayInside DisplayInside() const { mozilla::StyleDisplayInside DisplayInside() const {
return DisplayInside(mDisplay); return mDisplay.Inside();
} }
bool IsListItem() const { return mDisplay.IsListItem(); }
bool IsInlineFlow() const { return mDisplay.IsInlineFlow(); }
static bool IsListItem(mozilla::StyleDisplay aDisplay) { bool IsInlineInsideStyle() const { return mDisplay.IsInlineInside(); }
return !!(uint16_t(aDisplay) & mozilla::STYLE_DISPLAY_LIST_ITEM_BIT);
}
bool IsListItem() const { return IsListItem(mDisplay); }
// Whether display is `inline` or `inline list-item`.
static bool IsInlineFlow(mozilla::StyleDisplay aDisplay) {
return DisplayOutside(aDisplay) == mozilla::StyleDisplayOutside::Inline &&
DisplayInside(aDisplay) == mozilla::StyleDisplayInside::Flow;
}
bool IsInlineFlow() const { return IsInlineFlow(mDisplay); }
bool IsInlineInsideStyle() const {
auto inside = DisplayInside();
return IsInlineFlow() || inside == mozilla::StyleDisplayInside::Ruby ||
inside == mozilla::StyleDisplayInside::RubyBase ||
inside == mozilla::StyleDisplayInside::RubyBaseContainer ||
inside == mozilla::StyleDisplayInside::RubyText ||
inside == mozilla::StyleDisplayInside::RubyTextContainer;
}
bool IsBlockOutsideStyle() const { bool IsBlockOutsideStyle() const {
return DisplayOutside() == mozilla::StyleDisplayOutside::Block; return DisplayOutside() == mozilla::StyleDisplayOutside::Block;
} }
static bool IsDisplayTypeInlineOutside(mozilla::StyleDisplay aDisplay) { bool IsInlineOutsideStyle() const { return mDisplay.IsInlineOutside(); }
auto outside = DisplayOutside(aDisplay);
if (outside == mozilla::StyleDisplayOutside::Inline) {
return true;
}
// just an optimization for the common case:
if (outside == mozilla::StyleDisplayOutside::Block) {
return false;
}
return mozilla::StyleDisplay::RubyBase == aDisplay ||
mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
mozilla::StyleDisplay::RubyText == aDisplay ||
mozilla::StyleDisplay::RubyTextContainer == aDisplay;
}
bool IsInlineOutsideStyle() const {
return IsDisplayTypeInlineOutside(mDisplay);
}
bool IsOriginalDisplayInlineOutside() const { bool IsOriginalDisplayInlineOutside() const {
return IsDisplayTypeInlineOutside(mOriginalDisplay); return mOriginalDisplay.IsInlineOutside();
} }
bool IsInnerTableStyle() const { bool IsInnerTableStyle() const { return mDisplay.IsInternalTable(); }
return DisplayOutside() == mozilla::StyleDisplayOutside::InternalTable;
}
bool IsInternalTableStyleExceptCell() const { bool IsInternalTableStyleExceptCell() const {
return IsInnerTableStyle() && mozilla::StyleDisplay::TableCell != mDisplay; return mDisplay.IsInternalTableExceptCell();
} }
bool IsFloatingStyle() const { return mozilla::StyleFloat::None != mFloat; } bool IsFloatingStyle() const { return mozilla::StyleFloat::None != mFloat; }
@@ -1560,23 +1510,9 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
mozilla::StylePositionProperty::Fixed == mPosition; mozilla::StylePositionProperty::Fixed == mPosition;
} }
static bool IsRubyDisplayType(mozilla::StyleDisplay aDisplay) { bool IsRubyDisplayType() const { return mDisplay.IsRuby(); }
return DisplayInside(aDisplay) == mozilla::StyleDisplayInside::Ruby ||
IsInternalRubyDisplayType(aDisplay);
}
static bool IsInternalRubyDisplayType(mozilla::StyleDisplay aDisplay) { bool IsInternalRubyDisplayType() const { return mDisplay.IsInternalRuby(); }
return mozilla::StyleDisplay::RubyBase == aDisplay ||
mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
mozilla::StyleDisplay::RubyText == aDisplay ||
mozilla::StyleDisplay::RubyTextContainer == aDisplay;
}
bool IsRubyDisplayType() const { return IsRubyDisplayType(mDisplay); }
bool IsInternalRubyDisplayType() const {
return IsInternalRubyDisplayType(mDisplay);
}
bool IsOutOfFlowStyle() const { bool IsOutOfFlowStyle() const {
return (IsAbsolutelyPositionedStyle() || IsFloatingStyle()); return (IsAbsolutelyPositionedStyle() || IsFloatingStyle());

View File

@@ -2162,14 +2162,14 @@ void nsCellMap::Dump(bool aIsBorderCollapse) const {
printf("\n ***** START GROUP CELL MAP DUMP ***** %p\n", (void*)this); printf("\n ***** START GROUP CELL MAP DUMP ***** %p\n", (void*)this);
nsTableRowGroupFrame* rg = GetRowGroup(); nsTableRowGroupFrame* rg = GetRowGroup();
const nsStyleDisplay* display = rg->StyleDisplay(); const nsStyleDisplay* display = rg->StyleDisplay();
switch (display->mDisplay) { switch (display->DisplayInside()) {
case StyleDisplay::TableHeaderGroup: case StyleDisplayInside::TableHeaderGroup:
printf(" thead "); printf(" thead ");
break; break;
case StyleDisplay::TableFooterGroup: case StyleDisplayInside::TableFooterGroup:
printf(" tfoot "); printf(" tfoot ");
break; break;
case StyleDisplay::TableRowGroup: case StyleDisplayInside::TableRowGroup:
printf(" tbody "); printf(" tbody ");
break; break;
default: default:

View File

@@ -2624,22 +2624,22 @@ void nsTableFrame::OrderRowGroups(RowGroupArray& aChildren,
nsTableRowGroupFrame* rowGroup = nsTableRowGroupFrame* rowGroup =
static_cast<nsTableRowGroupFrame*>(kidFrame); static_cast<nsTableRowGroupFrame*>(kidFrame);
switch (kidDisplay->mDisplay) { switch (kidDisplay->DisplayInside()) {
case mozilla::StyleDisplay::TableHeaderGroup: case StyleDisplayInside::TableHeaderGroup:
if (head) { // treat additional thead like tbody if (head) { // treat additional thead like tbody
aChildren.AppendElement(rowGroup); aChildren.AppendElement(rowGroup);
} else { } else {
head = rowGroup; head = rowGroup;
} }
break; break;
case mozilla::StyleDisplay::TableFooterGroup: case StyleDisplayInside::TableFooterGroup:
if (foot) { // treat additional tfoot like tbody if (foot) { // treat additional tfoot like tbody
aChildren.AppendElement(rowGroup); aChildren.AppendElement(rowGroup);
} else { } else {
foot = rowGroup; foot = rowGroup;
} }
break; break;
case mozilla::StyleDisplay::TableRowGroup: case StyleDisplayInside::TableRowGroup:
aChildren.AppendElement(rowGroup); aChildren.AppendElement(rowGroup);
break; break;
default: default:

View File

@@ -106,102 +106,134 @@ pub enum DisplayInside {
ToResolvedValue, ToResolvedValue,
ToShmem, ToShmem,
)] )]
#[repr(transparent)] #[repr(C)]
pub struct Display(u16); pub struct Display(u16);
/// Gecko-only impl block for Display (shared stuff later in this file): /// Gecko-only impl block for Display (shared stuff later in this file):
#[allow(missing_docs)] #[allow(missing_docs)]
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
impl Display { impl Display {
// Our u16 bits are used as follows: LOOOOOOOIIIIIIII // Our u16 bits are used as follows: LOOOOOOOIIIIIIII
const LIST_ITEM_BIT: u16 = 0x8000; //^ pub const LIST_ITEM_MASK: u16 = 0b1000000000000000;
const DISPLAY_OUTSIDE_BITS: u16 = 7; // ^^^^^^^ pub const OUTSIDE_MASK: u16 = 0b0111111100000000;
const DISPLAY_INSIDE_BITS: u16 = 8; // ^^^^^^^^ pub const INSIDE_MASK: u16 = 0b0000000011111111;
pub const OUTSIDE_SHIFT: u16 = 8;
/// https://drafts.csswg.org/css-display/#the-display-properties /// https://drafts.csswg.org/css-display/#the-display-properties
pub const None: Self = Self::new(DisplayOutside::None, DisplayInside::None); /// ::new() inlined so cbindgen can use it
pub const None: Self =
Self(((DisplayOutside::None as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::None as u16);
#[cfg(any(feature = "servo-layout-2020", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2020", feature = "gecko"))]
pub const Contents: Self = Self::new(DisplayOutside::None, DisplayInside::Contents); pub const Contents: Self = Self(
pub const Inline: Self = Self::new(DisplayOutside::Inline, DisplayInside::Flow); ((DisplayOutside::None as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Contents as u16,
pub const InlineBlock: Self = Self::new(DisplayOutside::Inline, DisplayInside::FlowRoot); );
pub const Block: Self = Self::new(DisplayOutside::Block, DisplayInside::Flow); pub const Inline: Self =
Self(((DisplayOutside::Inline as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Flow as u16);
pub const InlineBlock: Self = Self(
((DisplayOutside::Inline as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::FlowRoot as u16,
);
pub const Block: Self =
Self(((DisplayOutside::Block as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Flow as u16);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const FlowRoot: Self = Self::new(DisplayOutside::Block, DisplayInside::FlowRoot); pub const FlowRoot: Self =
pub const Flex: Self = Self::new(DisplayOutside::Block, DisplayInside::Flex); Self(((DisplayOutside::Block as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::FlowRoot as u16);
pub const InlineFlex: Self = Self::new(DisplayOutside::Inline, DisplayInside::Flex); pub const Flex: Self =
Self(((DisplayOutside::Block as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Flex as u16);
pub const InlineFlex: Self =
Self(((DisplayOutside::Inline as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Flex as u16);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const Grid: Self = Self::new(DisplayOutside::Block, DisplayInside::Grid); pub const Grid: Self =
Self(((DisplayOutside::Block as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Grid as u16);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const InlineGrid: Self = Self::new(DisplayOutside::Inline, DisplayInside::Grid); pub const InlineGrid: Self =
Self(((DisplayOutside::Inline as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Grid as u16);
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const Table: Self = Self::new(DisplayOutside::Block, DisplayInside::Table); pub const Table: Self =
Self(((DisplayOutside::Block as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Table as u16);
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const InlineTable: Self = Self::new(DisplayOutside::Inline, DisplayInside::Table); pub const InlineTable: Self = Self(
((DisplayOutside::Inline as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Table as u16,
);
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableCaption: Self = Self::new(DisplayOutside::TableCaption, DisplayInside::Flow); pub const TableCaption: Self = Self(
((DisplayOutside::TableCaption as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Flow as u16,
);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const Ruby: Self = Self::new(DisplayOutside::Inline, DisplayInside::Ruby); pub const Ruby: Self =
Self(((DisplayOutside::Inline as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::Ruby as u16);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const WebkitBox: Self = Self::new(DisplayOutside::Block, DisplayInside::WebkitBox); pub const WebkitBox: Self = Self(
((DisplayOutside::Block as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::WebkitBox as u16,
);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const WebkitInlineBox: Self = Self::new(DisplayOutside::Inline, DisplayInside::WebkitBox); pub const WebkitInlineBox: Self = Self(
((DisplayOutside::Inline as u16) << Self::OUTSIDE_SHIFT) | DisplayInside::WebkitBox as u16,
);
// Internal table boxes. // Internal table boxes.
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableRowGroup: Self = pub const TableRowGroup: Self = Self(
Self::new(DisplayOutside::InternalTable, DisplayInside::TableRowGroup); ((DisplayOutside::InternalTable as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::TableRowGroup as u16,
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableHeaderGroup: Self = Self::new(
DisplayOutside::InternalTable,
DisplayInside::TableHeaderGroup,
); );
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableFooterGroup: Self = Self::new( pub const TableHeaderGroup: Self = Self(
DisplayOutside::InternalTable, ((DisplayOutside::InternalTable as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::TableFooterGroup, DisplayInside::TableHeaderGroup as u16,
); );
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableColumn: Self = pub const TableFooterGroup: Self = Self(
Self::new(DisplayOutside::InternalTable, DisplayInside::TableColumn); ((DisplayOutside::InternalTable as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::TableFooterGroup as u16,
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableColumnGroup: Self = Self::new(
DisplayOutside::InternalTable,
DisplayInside::TableColumnGroup,
); );
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableRow: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableRow); pub const TableColumn: Self = Self(
((DisplayOutside::InternalTable as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::TableColumn as u16,
);
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))] #[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableCell: Self = Self::new(DisplayOutside::InternalTable, DisplayInside::TableCell); pub const TableColumnGroup: Self = Self(
((DisplayOutside::InternalTable as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::TableColumnGroup as u16,
);
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableRow: Self = Self(
((DisplayOutside::InternalTable as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::TableRow as u16,
);
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
pub const TableCell: Self = Self(
((DisplayOutside::InternalTable as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::TableCell as u16,
);
/// Internal ruby boxes. /// Internal ruby boxes.
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const RubyBase: Self = Self::new(DisplayOutside::InternalRuby, DisplayInside::RubyBase); pub const RubyBase: Self = Self(
#[cfg(feature = "gecko")] ((DisplayOutside::InternalRuby as u16) << Self::OUTSIDE_SHIFT) |
pub const RubyBaseContainer: Self = Self::new( DisplayInside::RubyBase as u16,
DisplayOutside::InternalRuby,
DisplayInside::RubyBaseContainer,
); );
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const RubyText: Self = Self::new(DisplayOutside::InternalRuby, DisplayInside::RubyText); pub const RubyBaseContainer: Self = Self(
((DisplayOutside::InternalRuby as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::RubyBaseContainer as u16,
);
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
pub const RubyTextContainer: Self = Self::new( pub const RubyText: Self = Self(
DisplayOutside::InternalRuby, ((DisplayOutside::InternalRuby as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::RubyTextContainer, DisplayInside::RubyText as u16,
);
#[cfg(feature = "gecko")]
pub const RubyTextContainer: Self = Self(
((DisplayOutside::InternalRuby as u16) << Self::OUTSIDE_SHIFT) |
DisplayInside::RubyTextContainer as u16,
); );
/// Make a raw display value from <display-outside> and <display-inside> values. /// Make a raw display value from <display-outside> and <display-inside> values.
#[inline] #[inline]
const fn new(outside: DisplayOutside, inside: DisplayInside) -> Self { const fn new(outside: DisplayOutside, inside: DisplayInside) -> Self {
let o: u16 = ((outside as u8) as u16) << Self::DISPLAY_INSIDE_BITS; Self((outside as u16) << Self::OUTSIDE_SHIFT | inside as u16)
let i: u16 = (inside as u8) as u16;
Self(o | i)
} }
/// Make a display enum value from <display-outside> and <display-inside> values. /// Make a display enum value from <display-outside> and <display-inside> values.
@@ -211,22 +243,19 @@ impl Display {
if !list_item { if !list_item {
return v; return v;
} }
Self(v.0 | Self::LIST_ITEM_BIT) Self(v.0 | Self::LIST_ITEM_MASK)
} }
/// Accessor for the <display-inside> value. /// Accessor for the <display-inside> value.
#[inline] #[inline]
pub fn inside(&self) -> DisplayInside { pub fn inside(&self) -> DisplayInside {
DisplayInside::from_u16(self.0 & ((1 << Self::DISPLAY_INSIDE_BITS) - 1)).unwrap() DisplayInside::from_u16(self.0 & Self::INSIDE_MASK).unwrap()
} }
/// Accessor for the <display-outside> value. /// Accessor for the <display-outside> value.
#[inline] #[inline]
pub fn outside(&self) -> DisplayOutside { pub fn outside(&self) -> DisplayOutside {
DisplayOutside::from_u16( DisplayOutside::from_u16((self.0 & Self::OUTSIDE_MASK) >> Self::OUTSIDE_SHIFT).unwrap()
(self.0 >> Self::DISPLAY_INSIDE_BITS) & ((1 << Self::DISPLAY_OUTSIDE_BITS) - 1),
)
.unwrap()
} }
/// Returns the raw underlying u16 value. /// Returns the raw underlying u16 value.
@@ -244,7 +273,7 @@ impl Display {
/// Returns whether this `display` value is some kind of list-item. /// Returns whether this `display` value is some kind of list-item.
#[inline] #[inline]
pub const fn is_list_item(&self) -> bool { pub const fn is_list_item(&self) -> bool {
(self.0 & Self::LIST_ITEM_BIT) != 0 (self.0 & Self::LIST_ITEM_MASK) != 0
} }
/// Returns whether this `display` value is a ruby level container. /// Returns whether this `display` value is a ruby level container.

View File

@@ -94,6 +94,7 @@ include = [
"ComputedTimingFunction", "ComputedTimingFunction",
"ComputedValueFlags", "ComputedValueFlags",
"CursorKind", "CursorKind",
"Display",
"DisplayOutside", "DisplayOutside",
"DisplayInside", "DisplayInside",
"DisplayMode", "DisplayMode",
@@ -1009,3 +1010,17 @@ renaming_overrides_prefixing = true
"GenericContainIntrinsicSize" = """ "GenericContainIntrinsicSize" = """
bool HasAuto() const { return IsAutoLength() || IsAutoNone(); } bool HasAuto() const { return IsAutoLength() || IsAutoNone(); }
""" """
"Display" = """
inline StyleDisplayOutside Outside() const;
inline StyleDisplayInside Inside() const;
inline bool IsListItem() const;
inline bool IsInlineFlow() const;
inline bool IsInlineInside() const;
inline bool IsInlineOutside() const;
inline bool IsBlockOutside() const;
inline bool IsRuby() const;
inline bool IsInternalRuby() const;
inline bool IsInternalTable() const;
inline bool IsInternalTableExceptCell() const;
"""