diff --git a/core/src/font.rs b/core/src/font.rs index 2e8f61b36486..c4e0fb2a53c7 100644 --- a/core/src/font.rs +++ b/core/src/font.rs @@ -586,6 +586,9 @@ impl<'gc> Font<'gc> { /// of transforms and glyphs which will be consumed by the `glyph_func` /// closure. This corresponds to the series of drawing operations necessary /// to render the text on a single horizontal line. + /// + /// It's guaranteed that this function will iterate over all characters + /// from the text, irrespectively of whether they have a glyph or not. pub fn evaluate( &self, text: &WStr, // TODO: take an `IntoIterator`, to not depend on string representation? @@ -600,6 +603,9 @@ impl<'gc> Font<'gc> { transform.matrix.a = scale; transform.matrix.d = scale; + + // TODO [KJ] I'm not sure whether we should iterate over characters here or over code units. + // I suspect Flash Player does not support full UTF-16 when displaying and laying out text. let mut char_indices = text.char_indices().peekable(); let has_kerning_info = self.has_kerning_info(); let mut x = Twips::ZERO; @@ -631,6 +637,10 @@ impl<'gc> Font<'gc> { // Step horizontally. transform.matrix.tx += twips_advance; x += twips_advance; + } else { + // No glyph, zero advance. This makes it possible to use this method for purposes + // other than rendering the font, e.g. measurement, iterating over characters. + glyph_func(pos, &transform, &Glyph::empty(), Twips::ZERO, x); } } } @@ -809,6 +819,15 @@ pub struct Glyph { } impl Glyph { + /// Returns an empty glyph with zero advance. + pub fn empty() -> Self { + Self { + shape_handle: Default::default(), + shape: GlyphShape::None, + advance: Twips::ZERO, + } + } + pub fn shape_handle(&self, renderer: &mut dyn RenderBackend) -> Option { self.shape_handle .borrow_mut()