mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
style: Represent the percentage in LengthPercentage with something other than an option.
Not the prettiest, but it will work, and LengthPercentage will be 12 bytes which is pretty good (we could do better if wanted I guess): * Au(i32) length; * f32 percentage; * AllowedNumericType(u8) clamping_mode; * bool has_percentage; * bool was_calc; This will allow me to start moving C++ stuff to use this representation. Differential Revision: https://phabricator.services.mozilla.com/D16929
This commit is contained in:
parent
e27c15e2f9
commit
05881b5ab4
7 changed files with 68 additions and 52 deletions
|
@ -77,7 +77,10 @@ pub struct LengthPercentage {
|
|||
#[animation(constant)]
|
||||
pub clamping_mode: AllowedNumericType,
|
||||
length: Length,
|
||||
pub percentage: Option<Percentage>,
|
||||
percentage: Percentage,
|
||||
/// Whether we specified a percentage or not.
|
||||
#[animation(constant)]
|
||||
pub has_percentage: bool,
|
||||
/// Whether this was from a calc() expression. This is needed because right
|
||||
/// now we don't treat calc() the same way as non-calc everywhere, but
|
||||
/// that's a bug in most cases.
|
||||
|
@ -99,7 +102,8 @@ pub struct LengthPercentage {
|
|||
// like calc(0px + 5%) and such.
|
||||
impl PartialEq for LengthPercentage {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.length == other.length && self.percentage == other.percentage
|
||||
self.length == other.length && self.percentage == other.percentage &&
|
||||
self.has_percentage == other.has_percentage
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,8 +115,7 @@ impl ComputeSquaredDistance for LengthPercentage {
|
|||
Ok(self
|
||||
.unclamped_length()
|
||||
.compute_squared_distance(&other.unclamped_length())? +
|
||||
self.percentage()
|
||||
.compute_squared_distance(&other.percentage())?)
|
||||
self.percentage.compute_squared_distance(&other.percentage)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,7 +147,8 @@ impl LengthPercentage {
|
|||
Self {
|
||||
clamping_mode,
|
||||
length,
|
||||
percentage,
|
||||
percentage: percentage.unwrap_or_default(),
|
||||
has_percentage: percentage.is_some(),
|
||||
was_calc,
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +158,7 @@ impl LengthPercentage {
|
|||
/// Panics in debug mode if a percentage is present in the expression.
|
||||
#[inline]
|
||||
pub fn length(&self) -> CSSPixelLength {
|
||||
debug_assert!(self.percentage.is_none());
|
||||
debug_assert!(!self.has_percentage);
|
||||
self.length_component()
|
||||
}
|
||||
|
||||
|
@ -173,22 +177,32 @@ impl LengthPercentage {
|
|||
/// Return the percentage value as CSSFloat.
|
||||
#[inline]
|
||||
pub fn percentage(&self) -> CSSFloat {
|
||||
self.percentage.map_or(0., |p| p.0)
|
||||
self.percentage.0
|
||||
}
|
||||
|
||||
/// Return the specified percentage if any.
|
||||
#[inline]
|
||||
pub fn specified_percentage(&self) -> Option<Percentage> {
|
||||
if self.has_percentage {
|
||||
Some(self.percentage)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the percentage component if this could be represented as a
|
||||
/// non-calc percentage.
|
||||
pub fn as_percentage(&self) -> Option<Percentage> {
|
||||
if self.length.px() != 0. {
|
||||
if !self.has_percentage || self.length.px() != 0. {
|
||||
return None;
|
||||
}
|
||||
|
||||
let p = self.percentage?;
|
||||
if self.clamping_mode.clamp(p.0) != p.0 {
|
||||
if self.clamping_mode.clamp(self.percentage.0) != self.percentage.0 {
|
||||
debug_assert!(self.was_calc);
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(p)
|
||||
Some(self.percentage)
|
||||
}
|
||||
|
||||
/// Convert the computed value into used value.
|
||||
|
@ -201,14 +215,11 @@ impl LengthPercentage {
|
|||
/// the height property), they apply whenever a calc() expression contains
|
||||
/// percentages.
|
||||
pub fn maybe_to_pixel_length(&self, container_len: Option<Au>) -> Option<Length> {
|
||||
match (container_len, self.percentage) {
|
||||
(Some(len), Some(percent)) => {
|
||||
let pixel = self.length.px() + len.scale_by(percent.0).to_f32_px();
|
||||
Some(Length::new(self.clamping_mode.clamp(pixel)))
|
||||
},
|
||||
(_, None) => Some(self.length()),
|
||||
_ => None,
|
||||
if self.has_percentage {
|
||||
let length = self.unclamped_length().px() + container_len?.scale_by(self.percentage.0).to_f32_px();
|
||||
return Some(Length::new(self.clamping_mode.clamp(length)));
|
||||
}
|
||||
Some(self.length())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,12 +273,12 @@ impl specified::CalcLengthPercentage {
|
|||
}
|
||||
}
|
||||
|
||||
LengthPercentage {
|
||||
clamping_mode: self.clamping_mode,
|
||||
length: Length::new(length.min(f32::MAX).max(f32::MIN)),
|
||||
percentage: self.percentage,
|
||||
was_calc: true,
|
||||
}
|
||||
LengthPercentage::with_clamping_mode(
|
||||
Length::new(length.min(f32::MAX).max(f32::MIN)),
|
||||
self.percentage,
|
||||
self.clamping_mode,
|
||||
/* was_calc = */ true,
|
||||
)
|
||||
}
|
||||
|
||||
/// Compute font-size or line-height taking into account text-zoom if necessary.
|
||||
|
@ -322,7 +333,7 @@ impl ToComputedValue for specified::CalcLengthPercentage {
|
|||
specified::CalcLengthPercentage {
|
||||
clamping_mode: computed.clamping_mode,
|
||||
absolute: Some(AbsoluteLength::from_computed_value(&computed.length)),
|
||||
percentage: computed.percentage,
|
||||
percentage: computed.specified_percentage(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -344,7 +355,7 @@ impl LengthPercentage {
|
|||
/// Returns true if the computed value is absolute 0 or 0%.
|
||||
#[inline]
|
||||
pub fn is_definitely_zero(&self) -> bool {
|
||||
self.unclamped_length().px() == 0.0 && self.percentage.map_or(true, |p| p.0 == 0.0)
|
||||
self.unclamped_length().px() == 0.0 && self.percentage.0 == 0.0
|
||||
}
|
||||
|
||||
// CSSFloat doesn't implement Hash, so does CSSPixelLength. Therefore, we still use Au as the
|
||||
|
@ -353,7 +364,7 @@ impl LengthPercentage {
|
|||
pub fn to_hash_key(&self) -> (Au, NotNan<f32>) {
|
||||
(
|
||||
Au::from(self.unclamped_length()),
|
||||
NotNan::new(self.percentage()).unwrap(),
|
||||
NotNan::new(self.percentage.0).unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -376,14 +387,14 @@ impl LengthPercentage {
|
|||
if self.was_calc {
|
||||
return Self::with_clamping_mode(
|
||||
self.length,
|
||||
self.percentage,
|
||||
self.specified_percentage(),
|
||||
AllowedNumericType::NonNegative,
|
||||
self.was_calc,
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(self.percentage.is_none() || self.unclamped_length() == Length::zero());
|
||||
if let Some(p) = self.percentage {
|
||||
debug_assert!(!self.has_percentage || self.unclamped_length() == Length::zero());
|
||||
if let Some(p) = self.specified_percentage() {
|
||||
return Self::with_clamping_mode(
|
||||
Length::zero(),
|
||||
Some(p.clamp_to_non_negative()),
|
||||
|
@ -420,8 +431,8 @@ impl ToComputedValue for specified::LengthPercentage {
|
|||
return specified::LengthPercentage::Percentage(p);
|
||||
}
|
||||
|
||||
let percentage = computed.percentage;
|
||||
if percentage.is_none() && computed.clamping_mode.clamp(length.px()) == length.px() {
|
||||
if !computed.has_percentage &&
|
||||
computed.clamping_mode.clamp(length.px()) == length.px() {
|
||||
return specified::LengthPercentage::Length(ToComputedValue::from_computed_value(
|
||||
&length,
|
||||
));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue