mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
style: Keep track of whether a style is affected by font metrics.
Differential Revision: https://phabricator.services.mozilla.com/D20728
This commit is contained in:
parent
fe7b3a6b11
commit
ed4a23eccf
4 changed files with 47 additions and 34 deletions
|
@ -56,10 +56,13 @@ bitflags! {
|
||||||
/// Whether the child explicitly inherits any reset property.
|
/// Whether the child explicitly inherits any reset property.
|
||||||
const INHERITS_RESET_STYLE = 1 << 8;
|
const INHERITS_RESET_STYLE = 1 << 8;
|
||||||
|
|
||||||
|
/// Whether any value on our style is font-metric-dependent.
|
||||||
|
const DEPENDS_ON_FONT_METRICS = 1 << 9;
|
||||||
|
|
||||||
/// Whether the style or any of the ancestors has a multicol style.
|
/// Whether the style or any of the ancestors has a multicol style.
|
||||||
///
|
///
|
||||||
/// Only used in Servo.
|
/// Only used in Servo.
|
||||||
const CAN_BE_FRAGMENTED = 1 << 9;
|
const CAN_BE_FRAGMENTED = 1 << 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ use crate::rule_tree::StrongRuleNode;
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
use self::computed_value_flags::*;
|
use self::computed_value_flags::*;
|
||||||
use crate::str::{CssString, CssStringBorrow, CssStringWriter};
|
use crate::str::{CssString, CssStringBorrow, CssStringWriter};
|
||||||
|
use std::cell::Cell;
|
||||||
|
|
||||||
pub use self::declaration_block::*;
|
pub use self::declaration_block::*;
|
||||||
pub use self::cascade::*;
|
pub use self::cascade::*;
|
||||||
|
@ -2758,7 +2759,7 @@ pub struct ComputedValuesInner {
|
||||||
pub writing_mode: WritingMode,
|
pub writing_mode: WritingMode,
|
||||||
|
|
||||||
/// A set of flags we use to store misc information regarding this style.
|
/// A set of flags we use to store misc information regarding this style.
|
||||||
pub flags: ComputedValueFlags,
|
flags: ComputedValueFlags,
|
||||||
|
|
||||||
/// The rule node representing the ordered list of rules matched for this
|
/// The rule node representing the ordered list of rules matched for this
|
||||||
/// node. Can be None for default values and text nodes. This is
|
/// node. Can be None for default values and text nodes. This is
|
||||||
|
@ -3322,8 +3323,10 @@ pub struct StyleBuilder<'a> {
|
||||||
///
|
///
|
||||||
/// TODO(emilio): Make private.
|
/// TODO(emilio): Make private.
|
||||||
pub writing_mode: WritingMode,
|
pub writing_mode: WritingMode,
|
||||||
|
|
||||||
/// Flags for the computed value.
|
/// Flags for the computed value.
|
||||||
pub flags: ComputedValueFlags,
|
pub flags: Cell<ComputedValueFlags>,
|
||||||
|
|
||||||
/// The element's style if visited, only computed if there's a relevant link
|
/// The element's style if visited, only computed if there's a relevant link
|
||||||
/// for this element. A element's "relevant link" is the element being
|
/// for this element. A element's "relevant link" is the element being
|
||||||
/// matched if it is a link or the nearest ancestor link.
|
/// matched if it is a link or the nearest ancestor link.
|
||||||
|
@ -3365,7 +3368,7 @@ impl<'a> StyleBuilder<'a> {
|
||||||
modified_reset: false,
|
modified_reset: false,
|
||||||
custom_properties,
|
custom_properties,
|
||||||
writing_mode: inherited_style.writing_mode,
|
writing_mode: inherited_style.writing_mode,
|
||||||
flags,
|
flags: Cell::new(flags),
|
||||||
visited_style: None,
|
visited_style: None,
|
||||||
% for style_struct in data.active_style_structs():
|
% for style_struct in data.active_style_structs():
|
||||||
% if style_struct.inherited:
|
% if style_struct.inherited:
|
||||||
|
@ -3404,7 +3407,7 @@ impl<'a> StyleBuilder<'a> {
|
||||||
rules: None,
|
rules: None,
|
||||||
custom_properties: style_to_derive_from.custom_properties().cloned(),
|
custom_properties: style_to_derive_from.custom_properties().cloned(),
|
||||||
writing_mode: style_to_derive_from.writing_mode,
|
writing_mode: style_to_derive_from.writing_mode,
|
||||||
flags: style_to_derive_from.flags,
|
flags: Cell::new(style_to_derive_from.flags),
|
||||||
visited_style: None,
|
visited_style: None,
|
||||||
% for style_struct in data.active_style_structs():
|
% for style_struct in data.active_style_structs():
|
||||||
${style_struct.ident}: StyleStructRef::Borrowed(
|
${style_struct.ident}: StyleStructRef::Borrowed(
|
||||||
|
@ -3434,14 +3437,14 @@ impl<'a> StyleBuilder<'a> {
|
||||||
.get_${property.style_struct.name_lower}();
|
.get_${property.style_struct.name_lower}();
|
||||||
|
|
||||||
self.modified_reset = true;
|
self.modified_reset = true;
|
||||||
self.flags.insert(ComputedValueFlags::INHERITS_RESET_STYLE);
|
self.add_flags(ComputedValueFlags::INHERITS_RESET_STYLE);
|
||||||
|
|
||||||
% if property.ident == "content":
|
% if property.ident == "content":
|
||||||
self.flags.insert(ComputedValueFlags::INHERITS_CONTENT);
|
self.add_flags(ComputedValueFlags::INHERITS_CONTENT);
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
% if property.ident == "display":
|
% if property.ident == "display":
|
||||||
self.flags.insert(ComputedValueFlags::INHERITS_DISPLAY);
|
self.add_flags(ComputedValueFlags::INHERITS_DISPLAY);
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
if self.${property.style_struct.ident}.ptr_eq(inherited_struct) {
|
if self.${property.style_struct.ident}.ptr_eq(inherited_struct) {
|
||||||
|
@ -3628,13 +3631,33 @@ impl<'a> StyleBuilder<'a> {
|
||||||
self.modified_reset
|
self.modified_reset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the current flags.
|
||||||
|
#[inline]
|
||||||
|
pub fn flags(&self) -> ComputedValueFlags {
|
||||||
|
self.flags.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a flag to the current builder.
|
||||||
|
#[inline]
|
||||||
|
pub fn add_flags(&self, flag: ComputedValueFlags) {
|
||||||
|
let flags = self.flags() | flag;
|
||||||
|
self.flags.set(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Removes a flag to the current builder.
|
||||||
|
#[inline]
|
||||||
|
pub fn remove_flags(&self, flag: ComputedValueFlags) {
|
||||||
|
let flags = self.flags() & !flag;
|
||||||
|
self.flags.set(flags);
|
||||||
|
}
|
||||||
|
|
||||||
/// Turns this `StyleBuilder` into a proper `ComputedValues` instance.
|
/// Turns this `StyleBuilder` into a proper `ComputedValues` instance.
|
||||||
pub fn build(self) -> Arc<ComputedValues> {
|
pub fn build(self) -> Arc<ComputedValues> {
|
||||||
ComputedValues::new(
|
ComputedValues::new(
|
||||||
self.pseudo,
|
self.pseudo,
|
||||||
self.custom_properties,
|
self.custom_properties,
|
||||||
self.writing_mode,
|
self.writing_mode,
|
||||||
self.flags,
|
self.flags.get(),
|
||||||
self.rules,
|
self.rules,
|
||||||
self.visited_style,
|
self.visited_style,
|
||||||
% for style_struct in data.active_style_structs():
|
% for style_struct in data.active_style_structs():
|
||||||
|
@ -3721,7 +3744,7 @@ mod lazy_static_module {
|
||||||
writing_mode: WritingMode::empty(),
|
writing_mode: WritingMode::empty(),
|
||||||
rules: None,
|
rules: None,
|
||||||
visited_style: None,
|
visited_style: None,
|
||||||
flags: ComputedValueFlags::empty(),
|
flags: Cell::new(ComputedValueFlags::empty()),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,23 +225,17 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
.clone_text_decoration_line()
|
.clone_text_decoration_line()
|
||||||
.is_empty()
|
.is_empty()
|
||||||
{
|
{
|
||||||
self.style
|
self.style.add_flags(ComputedValueFlags::HAS_TEXT_DECORATION_LINES);
|
||||||
.flags
|
|
||||||
.insert(ComputedValueFlags::HAS_TEXT_DECORATION_LINES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.style.is_pseudo_element() {
|
if self.style.is_pseudo_element() {
|
||||||
self.style
|
self.style.add_flags(ComputedValueFlags::IS_IN_PSEUDO_ELEMENT_SUBTREE);
|
||||||
.flags
|
|
||||||
.insert(ComputedValueFlags::IS_IN_PSEUDO_ELEMENT_SUBTREE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
{
|
{
|
||||||
if self.style.get_parent_column().is_multicol() {
|
if self.style.get_parent_column().is_multicol() {
|
||||||
self.style
|
self.style.add_flags(ComputedValueFlags::CAN_BE_FRAGMENTED);
|
||||||
.flags
|
|
||||||
.insert(ComputedValueFlags::CAN_BE_FRAGMENTED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,9 +274,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
if writing_mode != WritingMode::HorizontalTb &&
|
if writing_mode != WritingMode::HorizontalTb &&
|
||||||
text_combine_upright == TextCombineUpright::All
|
text_combine_upright == TextCombineUpright::All
|
||||||
{
|
{
|
||||||
self.style
|
self.style.add_flags(ComputedValueFlags::IS_TEXT_COMBINED);
|
||||||
.flags
|
|
||||||
.insert(ComputedValueFlags::IS_TEXT_COMBINED);
|
|
||||||
self.style
|
self.style
|
||||||
.mutate_inherited_box()
|
.mutate_inherited_box()
|
||||||
.set_writing_mode(WritingMode::HorizontalTb);
|
.set_writing_mode(WritingMode::HorizontalTb);
|
||||||
|
@ -303,9 +295,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
.get_parent_flags()
|
.get_parent_flags()
|
||||||
.contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK)
|
.contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK)
|
||||||
{
|
{
|
||||||
self.style
|
self.style.add_flags(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK);
|
||||||
.flags
|
|
||||||
.insert(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,9 +581,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
let self_display = self.style.get_box().clone_display();
|
let self_display = self.style.get_box().clone_display();
|
||||||
// Check whether line break should be suppressed for this element.
|
// Check whether line break should be suppressed for this element.
|
||||||
if self.should_suppress_linebreak(layout_parent_style) {
|
if self.should_suppress_linebreak(layout_parent_style) {
|
||||||
self.style
|
self.style.add_flags(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK);
|
||||||
.flags
|
|
||||||
.insert(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK);
|
|
||||||
// Inlinify the display type if allowed.
|
// Inlinify the display type if allowed.
|
||||||
if !self.skip_item_display_fixup(element) {
|
if !self.skip_item_display_fixup(element) {
|
||||||
let inline_display = self_display.inlinify();
|
let inline_display = self_display.inlinify();
|
||||||
|
@ -651,14 +639,10 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if element.unwrap().is_visited_link() {
|
if element.unwrap().is_visited_link() {
|
||||||
self.style
|
self.style.add_flags(ComputedValueFlags::IS_RELEVANT_LINK_VISITED);
|
||||||
.flags
|
|
||||||
.insert(ComputedValueFlags::IS_RELEVANT_LINK_VISITED);
|
|
||||||
} else {
|
} else {
|
||||||
// Need to remove to handle unvisited link inside visited.
|
// Need to remove to handle unvisited link inside visited.
|
||||||
self.style
|
self.style.remove_flags(ComputedValueFlags::IS_RELEVANT_LINK_VISITED);
|
||||||
.flags
|
|
||||||
.remove(ComputedValueFlags::IS_RELEVANT_LINK_VISITED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
|
use super::{AllowQuirks, Number, Percentage, ToComputedValue};
|
||||||
use crate::font_metrics::FontMetricsQueryResult;
|
use crate::font_metrics::FontMetricsQueryResult;
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
|
use crate::properties::computed_value_flags::ComputedValueFlags;
|
||||||
use crate::values::computed::{self, CSSPixelLength, Context};
|
use crate::values::computed::{self, CSSPixelLength, Context};
|
||||||
use crate::values::generics::length as generics;
|
use crate::values::generics::length as generics;
|
||||||
use crate::values::generics::length::{
|
use crate::values::generics::length::{
|
||||||
|
@ -158,6 +159,7 @@ impl FontRelativeLength {
|
||||||
if context.for_non_inherited_property.is_some() {
|
if context.for_non_inherited_property.is_some() {
|
||||||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||||
}
|
}
|
||||||
|
context.builder.add_flags(ComputedValueFlags::DEPENDS_ON_FONT_METRICS);
|
||||||
let reference_size = match query_font_metrics(context, base_size) {
|
let reference_size = match query_font_metrics(context, base_size) {
|
||||||
FontMetricsQueryResult::Available(metrics) => metrics.x_height,
|
FontMetricsQueryResult::Available(metrics) => metrics.x_height,
|
||||||
// https://drafts.csswg.org/css-values/#ex
|
// https://drafts.csswg.org/css-values/#ex
|
||||||
|
@ -174,6 +176,7 @@ impl FontRelativeLength {
|
||||||
if context.for_non_inherited_property.is_some() {
|
if context.for_non_inherited_property.is_some() {
|
||||||
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
context.rule_cache_conditions.borrow_mut().set_uncacheable();
|
||||||
}
|
}
|
||||||
|
context.builder.add_flags(ComputedValueFlags::DEPENDS_ON_FONT_METRICS);
|
||||||
let reference_size = match query_font_metrics(context, base_size) {
|
let reference_size = match query_font_metrics(context, base_size) {
|
||||||
FontMetricsQueryResult::Available(metrics) => metrics.zero_advance_measure,
|
FontMetricsQueryResult::Available(metrics) => metrics.zero_advance_measure,
|
||||||
// https://drafts.csswg.org/css-values/#ch
|
// https://drafts.csswg.org/css-values/#ch
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue