From bb6ca40e99554232e696316acb873b94aa946d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 6 Oct 2023 12:20:20 +0000 Subject: [PATCH] Bug 1856755 - Add faster multiplication and division for fixed-point values. r=jfkthame,layout-reviewers Even though I ended up not using the division code, it seems useful. Differential Revision: https://phabricator.services.mozilla.com/D190024 --- .../components/style/values/computed/font.rs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/servo/components/style/values/computed/font.rs b/servo/components/style/values/computed/font.rs index b40a03f9af90..7d15a5736b29 100644 --- a/servo/components/style/values/computed/font.rs +++ b/servo/components/style/values/computed/font.rs @@ -23,6 +23,7 @@ use crate::Atom; use cssparser::{serialize_identifier, CssStringWriter, Parser}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; +use num_traits::cast::AsPrimitive; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, ToCss}; @@ -73,15 +74,15 @@ pub struct FixedPoint { impl FixedPoint where - T: num_traits::cast::AsPrimitive, - f32: num_traits::cast::AsPrimitive, + T: AsPrimitive, + f32: AsPrimitive, + u16: AsPrimitive, { const SCALE: u16 = 1 << FRACTION_BITS; const INVERSE_SCALE: f32 = 1.0 / Self::SCALE as f32; /// Returns a fixed-point bit from a floating-point context. pub fn from_float(v: f32) -> Self { - use num_traits::cast::AsPrimitive; Self { value: (v * Self::SCALE as f32).round().as_(), } @@ -93,6 +94,25 @@ where } } +// We implement this and mul below only for u16 types, because u32 types might need more care about +// overflow. But it's not hard to implement in either case. +impl std::ops::Div for FixedPoint { + type Output = Self; + fn div(self, rhs: Self) -> Self { + Self { + value: (((self.value as u32) << (FRACTION_BITS as u32)) / (rhs.value as u32)) as u16, + } + } +} +impl std::ops::Mul for FixedPoint { + type Output = Self; + fn mul(self, rhs: Self) -> Self { + Self { + value: (((self.value as u32) * (rhs.value as u32)) >> (FRACTION_BITS as u32)) as u16, + } + } +} + /// font-weight: range 1..1000, fractional values permitted; keywords /// 'normal', 'bold' aliased to 400, 700 respectively. ///