mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
style: Use ScriptPercentScaleDown and ScriptScriptPercentScaleDown constants
The math-depth implementation is refined to take into account the ScriptPercentScaleDown and ScriptScriptPercentScaleDown constants (if the parent's first valid font has a MATH table) in order to calculate the scale factor between math-deth 0 and 1, and between 0 and 2 respectively. Behavior is unchanged if the legacy scriptsizemultiplier attribute is specified or if no MATH table is available. The preference layout.css.math-depth.enabled remains disabled in nightly until the remaining bit (support for font-size: math) is implemented in bug 1667090. Differential Revision: https://phabricator.services.mozilla.com/D91604
This commit is contained in:
parent
12a2c88605
commit
f196c19106
2 changed files with 83 additions and 3 deletions
|
@ -22,6 +22,12 @@ pub struct FontMetrics {
|
|||
pub ic_width: Option<Length>,
|
||||
/// The ascent of the font (a value is always available for this).
|
||||
pub ascent: Length,
|
||||
/// Script scale down factor for math-depth 1.
|
||||
/// https://w3c.github.io/mathml-core/#dfn-scriptpercentscaledown
|
||||
pub script_percent_scale_down: Option<f32>,
|
||||
/// Script scale down factor for math-depth 2.
|
||||
/// https://w3c.github.io/mathml-core/#dfn-scriptscriptpercentscaledown
|
||||
pub script_script_percent_scale_down: Option<f32>,
|
||||
}
|
||||
|
||||
impl Default for FontMetrics {
|
||||
|
@ -32,6 +38,8 @@ impl Default for FontMetrics {
|
|||
cap_height: None,
|
||||
ic_width: None,
|
||||
ascent: Length::new(0.0),
|
||||
script_percent_scale_down: None,
|
||||
script_script_percent_scale_down: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ use servo_arc::Arc;
|
|||
use smallvec::SmallVec;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum CanHaveLogicalProperties {
|
||||
|
@ -1053,8 +1054,58 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
return;
|
||||
}
|
||||
|
||||
let builder = &mut self.context.builder;
|
||||
const SCALE_FACTOR_WHEN_INCREMENTING_MATH_DEPTH_BY_ONE : f32 = 0.71;
|
||||
|
||||
// Helper function that calculates the scale factor applied to font-size
|
||||
// when math-depth goes from parent_math_depth to computed_math_depth.
|
||||
// This function is essentially a modification of the MathML3's formula
|
||||
// 0.71^(parent_math_depth - computed_math_depth) so that a scale factor
|
||||
// of parent_script_percent_scale_down is applied when math-depth goes
|
||||
// from 0 to 1 and parent_script_script_percent_scale_down is applied
|
||||
// when math-depth goes from 0 to 2. This is also a straightforward
|
||||
// implementation of the specification's algorithm:
|
||||
// https://w3c.github.io/mathml-core/#the-math-script-level-property
|
||||
fn scale_factor_for_math_depth_change(
|
||||
parent_math_depth: i32,
|
||||
computed_math_depth: i32,
|
||||
parent_script_percent_scale_down: Option<f32>,
|
||||
parent_script_script_percent_scale_down: Option<f32>,
|
||||
) -> f32 {
|
||||
let mut a = parent_math_depth;
|
||||
let mut b = computed_math_depth;
|
||||
let c = SCALE_FACTOR_WHEN_INCREMENTING_MATH_DEPTH_BY_ONE;
|
||||
let scale_between_0_and_1 = parent_script_percent_scale_down.unwrap_or_else(|| c);
|
||||
let scale_between_0_and_2 = parent_script_script_percent_scale_down.unwrap_or_else(|| c * c);
|
||||
let mut s = 1.0;
|
||||
let mut invert_scale_factor = false;
|
||||
if a == b {
|
||||
return s;
|
||||
}
|
||||
if b < a {
|
||||
mem::swap(&mut a, &mut b);
|
||||
invert_scale_factor = true;
|
||||
}
|
||||
let mut e = b - a;
|
||||
if a <= 0 && b >= 2 {
|
||||
s *= scale_between_0_and_2;
|
||||
e -= 2;
|
||||
} else if a == 1 {
|
||||
s *= scale_between_0_and_2 / scale_between_0_and_1;
|
||||
e -= 1;
|
||||
} else if b == 1 {
|
||||
s *= scale_between_0_and_1;
|
||||
e -= 1;
|
||||
}
|
||||
s *= (c as f32).powi(e);
|
||||
if invert_scale_factor {
|
||||
1.0 / s.max(f32::MIN_POSITIVE)
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
let (new_size, new_unconstrained_size) = {
|
||||
let builder = &self.context.builder;
|
||||
let font = builder.get_font().gecko();
|
||||
let parent_font = builder.get_parent_font().gecko();
|
||||
|
||||
|
@ -1069,7 +1120,28 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
min = builder.device.zoom_text(min);
|
||||
}
|
||||
|
||||
let scale = (parent_font.mScriptSizeMultiplier as f32).powi(delta as i32);
|
||||
// If the scriptsizemultiplier has been set to something other than
|
||||
// the default scale, use MathML3's implementation for backward
|
||||
// compatibility. Otherwise, follow MathML Core's algorithm.
|
||||
let scale = if parent_font.mScriptSizeMultiplier !=
|
||||
SCALE_FACTOR_WHEN_INCREMENTING_MATH_DEPTH_BY_ONE {
|
||||
(parent_font.mScriptSizeMultiplier as f32).powi(delta as i32)
|
||||
} else {
|
||||
builder.add_flags(ComputedValueFlags::DEPENDS_ON_SELF_FONT_METRICS);
|
||||
// Script scale factors are independent of orientation.
|
||||
let font_metrics = self.context
|
||||
.font_metrics_provider
|
||||
.query(self.context, FontBaseSize::InheritedStyle,
|
||||
FontMetricsOrientation::Horizontal,
|
||||
true /* retrieve_math_scales */);
|
||||
scale_factor_for_math_depth_change(
|
||||
parent_font.mMathDepth as i32,
|
||||
font.mMathDepth as i32,
|
||||
font_metrics.script_percent_scale_down,
|
||||
font_metrics.script_script_percent_scale_down
|
||||
)
|
||||
};
|
||||
|
||||
let parent_size = parent_font.mSize.0;
|
||||
let parent_unconstrained_size = parent_font.mScriptUnconstrainedSize.0;
|
||||
let new_size = parent_size.scale_by(scale);
|
||||
|
@ -1097,7 +1169,7 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
|||
)
|
||||
}
|
||||
};
|
||||
let font = builder.mutate_font().gecko_mut();
|
||||
let font = self.context.builder.mutate_font().gecko_mut();
|
||||
font.mFont.size = NonNegative(new_size);
|
||||
font.mSize = NonNegative(new_size);
|
||||
font.mScriptUnconstrainedSize = NonNegative(new_unconstrained_size);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue