servo / font-kit

A cross-platform font loading library written in Rust
Apache License 2.0
678 stars 100 forks source link

Glyph rendering does not work on macOS Big Sur #177

Closed berkus closed 3 years ago

berkus commented 3 years ago

Big Sur on M1 mac:

Running example list-fonts lists a bunch of fonts.

Running example render-glyph with any font face renders nothing, glyph data is empty:

❯ cargo run --example render-glyph -- Arial 'A'
    Finished dev [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/examples/render-glyph Arial A`
glyph 36:

Any tips how to debug it?

berkus commented 3 years ago
Process 96665 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x00000001000131b4 render-glyph`font_kit::loaders::core_text::Font::typographic_bounds::he1e3ef41c5dc828f(self=0x000000016fdfeef8, glyph_id=48) at core_text.rs:354:27
   351              .core_text_font
   352              .get_bounding_rects_for_glyphs(kCTFontDefaultOrientation, &[glyph_id as u16]);
   353          let rect = RectF::new(
-> 354              Vector2F::new(rect.origin.x as f32, rect.origin.y as f32),
   355              Vector2F::new(rect.size.width as f32, rect.size.height as f32),
   356          );
   357          Ok(rect * self.units_per_point() as f32)
Target 0: (render-glyph) stopped.
(lldb) p rect
(core_graphics_types::geometry::CGRect) $4 = {
  origin = (x = 0.671875, y = 0)
  size = (width = 8.2734375, height = 11.6640625)
}

rect seems good after call to CTFontGetBoundingRectsForGlyphs (from .get_bounding_rects_for_glyphs)

berkus commented 3 years ago

After running

let rect = RectF::new(
    Vector2F::new(rect.origin.x as f32, rect.origin.y as f32),
    Vector2F::new(rect.size.width as f32, rect.size.height as f32),
);

it becomes

Process 96665 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x0000000100013224 render-glyph`font_kit::loaders::core_text::Font::typographic_bounds::he1e3ef41c5dc828f(self=0x000000016fdfeef8, glyph_id=48) at core_text.rs:357:19
   354              Vector2F::new(rect.origin.x as f32, rect.origin.y as f32),
   355              Vector2F::new(rect.size.width as f32, rect.size.height as f32),
   356          );
-> 357          Ok(rect * self.units_per_point() as f32)
   358      }
   359
   360      /// Returns the distance from the origin of the glyph with the given ID to the next, in font
Target 0: (render-glyph) stopped.
(lldb) p rect
(pathfinder_geometry::rect::RectF) $5 = {
  __0 = {
    __0 = (__0 = 0.671875, __1 = 0, __2 = 0.671875, __3 = 0)
  }
}

i.e. completely empty RectF.

berkus commented 3 years ago

Origin and size are ok, but constructing RectF causes it to collapse (?)

origin: CGPoint { x: 0.671875, y: 0.0 } vs Vector2F(<0.671875, 0>) size: CGSize { width: 8.2734375, height: 11.6640625 } vs Vector2F(<8.2734375, 11.6640625>)

result: RectF(<0.671875, 0, 0.671875, 0>) and point size 128.0

this is all in

    /// Returns the boundaries of a glyph in font units.
    pub fn typographic_bounds(&self, glyph_id: u32) -> Result<RectF, GlyphLoadingError> {
        let rect = self
            .core_text_font
            .get_bounding_rects_for_glyphs(kCTFontDefaultOrientation, &[glyph_id as u16]);
        let origin =
            Vector2F::new(rect.origin.x as f32, rect.origin.y as f32);
        let size =
            Vector2F::new(rect.size.width as f32, rect.size.height as f32);
println!("{:?} vs {:?}", rect.origin, origin);
println!("{:?} vs {:?}", rect.size, size);
        let rect = RectF::new(origin, size);
println!("{:?} and point size {:?}", rect, self.units_per_point());
        Ok(rect * self.units_per_point() as f32)
    }
berkus commented 3 years ago

Looks like the bug is in pathfinder_simd implementation - depending with features = ["pf-no-simd"] renders the glyph.

berkus commented 3 years ago

Fix proposed https://github.com/servo/pathfinder/issues/452

berkus commented 3 years ago

^ merged, necessary to bump and release versions.

berkus commented 3 years ago

pathfinder_simd has released 0.5.1 about two weeks ago, bump?