Fixed calculation of glyph dimensions on Windows
The dimensions in the `DWRITE_GLYPH_METRICS` are a bit special: the `rightSideBearing` is measured from the right edge of the character boundary, not the left edge. So, doing (right - left) would usually return a negative or very small number, which, when casted to a u32 in an unsafe block, would silently overflow to a very large number and make webrender crash. Therefore, in order to calculate the metrics correctly, we have to first calculate the full width of the character, then subtract the right and left edges, same width the height.
This commit is contained in:
parent
2701757e29
commit
9223717234
|
@ -213,6 +213,9 @@ impl<FK> FontContext<FK> where FK: Clone + Hash + Eq + Ord {
|
||||||
glyph_key: &GlyphKey,
|
glyph_key: &GlyphKey,
|
||||||
_exact: bool)
|
_exact: bool)
|
||||||
-> Result<GlyphDimensions, ()> {
|
-> Result<GlyphDimensions, ()> {
|
||||||
|
|
||||||
|
let mut metrics: DWRITE_GLYPH_METRICS = unsafe { mem::zeroed() };
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let font_face = match self.dwrite_font_faces.get(&font_instance.font_key) {
|
let font_face = match self.dwrite_font_faces.get(&font_instance.font_key) {
|
||||||
None => return Err(()),
|
None => return Err(()),
|
||||||
|
@ -220,21 +223,23 @@ impl<FK> FontContext<FK> where FK: Clone + Hash + Eq + Ord {
|
||||||
};
|
};
|
||||||
|
|
||||||
let glyph_index = glyph_key.glyph_index as UINT16;
|
let glyph_index = glyph_key.glyph_index as UINT16;
|
||||||
let mut metrics: DWRITE_GLYPH_METRICS = mem::zeroed();
|
|
||||||
|
|
||||||
let result = (**font_face).GetDesignGlyphMetrics(&glyph_index, 1, &mut metrics, FALSE);
|
let result = (**font_face).GetDesignGlyphMetrics(&glyph_index, 1, &mut metrics, FALSE);
|
||||||
if !winerror::SUCCEEDED(result) {
|
if !winerror::SUCCEEDED(result) {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let character_width = metrics.advanceWidth as i32 - metrics.rightSideBearing - metrics.leftSideBearing;
|
||||||
|
let character_height = metrics.advanceHeight as i32 - metrics.topSideBearing - metrics.bottomSideBearing;
|
||||||
|
|
||||||
Ok(GlyphDimensions {
|
Ok(GlyphDimensions {
|
||||||
advance: metrics.advanceWidth as f32,
|
advance: metrics.advanceWidth as f32,
|
||||||
origin: Point2D::new(metrics.leftSideBearing, metrics.bottomSideBearing),
|
origin: Point2D::new(metrics.leftSideBearing, metrics.bottomSideBearing),
|
||||||
size: Size2D::new((metrics.rightSideBearing - metrics.leftSideBearing) as u32,
|
size: Size2D::new(character_width as u32,
|
||||||
(metrics.topSideBearing - metrics.bottomSideBearing) as u32),
|
character_height as u32),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a list of path commands that represent the given glyph in the given font.
|
/// Returns a list of path commands that represent the given glyph in the given font.
|
||||||
pub fn glyph_outline(&mut self, font_instance: &FontInstance<FK>, glyph_key: &GlyphKey)
|
pub fn glyph_outline(&mut self, font_instance: &FontInstance<FK>, glyph_key: &GlyphKey)
|
||||||
|
|
Loading…
Reference in New Issue