aboutsummaryrefslogtreecommitdiffstats
path: root/components/fonts/font.rs
diff options
context:
space:
mode:
authorCristian Brinza <cristianb@gmail.com>2024-08-31 02:16:26 +0300
committerGitHub <noreply@github.com>2024-08-30 23:16:26 +0000
commit4ae2610c24bfbd7acabf7ff327cf97d6df55c06f (patch)
treef4acf03c839c43a16867f922c8acf70c77e103bb /components/fonts/font.rs
parent6f333a8e299d84c98a07a0b708fe32f40aeeeb72 (diff)
downloadservo-4ae2610c24bfbd7acabf7ff327cf97d6df55c06f.tar.gz
servo-4ae2610c24bfbd7acabf7ff327cf97d6df55c06f.zip
fonts: Enable fast text shaping on Windows (#33123)
* Use patched dwrote Signed-off-by: crbrz <cristianb@gmail.com> * Enable fast text shaping Signed-off-by: crbrz <cristianb@gmail.com> * Add fast text shape test Signed-off-by: crbrz <cristianb@gmail.com> * Update dwrote to 0.11.1 Signed-off-by: crbrz <cristianb@gmail.com> --------- Signed-off-by: crbrz <cristianb@gmail.com>
Diffstat (limited to 'components/fonts/font.rs')
-rw-r--r--components/fonts/font.rs96
1 files changed, 92 insertions, 4 deletions
diff --git a/components/fonts/font.rs b/components/fonts/font.rs
index 14c55b928de..809d852ef26 100644
--- a/components/fonts/font.rs
+++ b/components/fonts/font.rs
@@ -325,7 +325,6 @@ struct ShapeCacheEntry {
impl Font {
pub fn shape_text(&self, text: &str, options: &ShapingOptions) -> Arc<GlyphStore> {
- let this = self as *const Font;
let lookup_key = ShapeCacheEntry {
text: text.to_owned(),
options: *options,
@@ -353,9 +352,7 @@ impl Font {
self.shape_text_fast(text, options, &mut glyphs);
} else {
debug!("shape_text: Using Harfbuzz.");
- self.shaper
- .get_or_init(|| Shaper::new(this))
- .shape_text(text, options, &mut glyphs);
+ self.shape_text_harfbuzz(text, options, &mut glyphs);
}
let shaped_text = Arc::new(glyphs);
@@ -371,6 +368,13 @@ impl Font {
shaped_text
}
+ fn shape_text_harfbuzz(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) {
+ let this = self as *const Font;
+ self.shaper
+ .get_or_init(|| Shaper::new(this))
+ .shape_text(text, options, glyphs);
+ }
+
fn can_do_fast_shaping(&self, text: &str, options: &ShapingOptions) -> bool {
options.script == Script::Latin &&
!options.flags.contains(ShapingFlags::RTL_FLAG) &&
@@ -869,3 +873,87 @@ pub(crate) fn map_platform_values_to_style_values(mapping: &[(f64, f64)], value:
mapping[mapping.len() - 1].1
}
+
+#[cfg(test)]
+mod test {
+ #[cfg(target_os = "windows")]
+ #[test]
+ fn test_shape_text_fast() {
+ use std::fs::File;
+ use std::io::Read;
+ use std::path::PathBuf;
+ use std::sync::Arc;
+
+ use app_units::Au;
+ use euclid::num::Zero;
+ use servo_url::ServoUrl;
+ use style::properties::longhands::font_variant_caps::computed_value::T as FontVariantCaps;
+ use style::values::computed::{FontStretch, FontStyle, FontWeight};
+ use unicode_script::Script;
+
+ use crate::platform::font::PlatformFont;
+ use crate::{
+ Font, FontDescriptor, FontIdentifier, FontTemplate, GlyphStore, PlatformFontMethods,
+ ShapingFlags, ShapingOptions,
+ };
+
+ let path: PathBuf = [
+ env!("CARGO_MANIFEST_DIR"),
+ "tests",
+ "support",
+ "dejavu-fonts-ttf-2.37",
+ "ttf",
+ "DejaVuSans.ttf",
+ ]
+ .iter()
+ .collect();
+
+ let identifier = FontIdentifier::Web(ServoUrl::from_file_path(path.clone()).unwrap());
+ let file = File::open(path).unwrap();
+ let data: Arc<Vec<u8>> = Arc::new(file.bytes().map(|b| b.unwrap()).collect());
+ let platform_font =
+ PlatformFont::new_from_data(identifier.clone(), data.clone(), 0, None).unwrap();
+
+ let template = FontTemplate {
+ identifier,
+ descriptor: platform_font.descriptor(),
+ data: Some(data),
+ stylesheet: None,
+ };
+ let descriptor = FontDescriptor {
+ weight: FontWeight::normal(),
+ stretch: FontStretch::hundred(),
+ style: FontStyle::normal(),
+ variant: FontVariantCaps::Normal,
+ pt_size: Au::from_px(24),
+ };
+ let font = Font::new(
+ Arc::new(atomic_refcell::AtomicRefCell::new(template)),
+ descriptor,
+ None,
+ )
+ .unwrap();
+
+ let shaping_options = ShapingOptions {
+ letter_spacing: None,
+ word_spacing: Au::zero(),
+ script: Script::Latin,
+ flags: ShapingFlags::empty(),
+ };
+ let text = "WAVE";
+
+ assert!(font.can_do_fast_shaping(text, &shaping_options));
+
+ let mut expected_glyphs = GlyphStore::new(text.len(), false, false, false);
+ font.shape_text_harfbuzz(text, &shaping_options, &mut expected_glyphs);
+
+ let mut glyphs = GlyphStore::new(text.len(), false, false, false);
+ font.shape_text_fast(text, &shaping_options, &mut glyphs);
+
+ assert_eq!(glyphs.len(), expected_glyphs.len());
+ assert_eq!(
+ glyphs.total_advance().to_nearest_px(),
+ expected_glyphs.total_advance().to_nearest_px()
+ );
+ }
+}