Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- Fixes test crash (floating point exception due to double value outside of integer range) with TAMu_Kadampari.ttf from Arch Linux's ttf-indic-otf package. sTypoLineGap is -194 in this font, and Windows 10 sets otmLineGap to 4294967295.
Also fixes the crash with GohaTibebZemen.otf from Arch's xorg-fonts-misc package. sCapHeight and sxHeight are -32768 in this font, and Windows 10 refuses to install it. However, Windows XP installs the font without complaint and sets otmsCapEmHeight and otmsXHeight to 4294966903. I think the 0.00000009% difference from UINT_MAX is just rounding error. --- dlls/gdi32/freetype.c | 11 ++++++----- dlls/gdi32/gdi_private.h | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 7c5a7ef979..961f9e5f03 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -7578,19 +7578,20 @@ static void scale_outline_font_metrics(const GdiFont *font, OUTLINETEXTMETRICW *
#define SCALE_X(x) (x) = GDI_ROUND((double)(x) * (scale_x)) #define SCALE_Y(y) (y) = GDI_ROUND((double)(y) * (scale_y)) +#define SCALE_YU(y) (y) = GDI_ROUND_UINT((double)(y) * (scale_y))
SCALE_Y(potm->otmAscent); SCALE_Y(potm->otmDescent); - SCALE_Y(potm->otmLineGap); - SCALE_Y(potm->otmsCapEmHeight); - SCALE_Y(potm->otmsXHeight); + SCALE_YU(potm->otmLineGap); + SCALE_YU(potm->otmsCapEmHeight); + SCALE_YU(potm->otmsXHeight); SCALE_Y(potm->otmrcFontBox.top); SCALE_Y(potm->otmrcFontBox.bottom); SCALE_X(potm->otmrcFontBox.left); SCALE_X(potm->otmrcFontBox.right); SCALE_Y(potm->otmMacAscent); SCALE_Y(potm->otmMacDescent); - SCALE_Y(potm->otmMacLineGap); + SCALE_YU(potm->otmMacLineGap); SCALE_X(potm->otmptSubscriptSize.x); SCALE_Y(potm->otmptSubscriptSize.y); SCALE_X(potm->otmptSubscriptOffset.x); @@ -7599,7 +7600,7 @@ static void scale_outline_font_metrics(const GdiFont *font, OUTLINETEXTMETRICW * SCALE_Y(potm->otmptSuperscriptSize.y); SCALE_X(potm->otmptSuperscriptOffset.x); SCALE_Y(potm->otmptSuperscriptOffset.y); - SCALE_Y(potm->otmsStrikeoutSize); + SCALE_YU(potm->otmsStrikeoutSize); SCALE_Y(potm->otmsStrikeoutPosition); SCALE_Y(potm->otmsUnderscoreSize); SCALE_Y(potm->otmsUnderscorePosition); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 4236aa3690..c591057e3a 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -141,6 +141,13 @@ static inline INT GDI_ROUND(double val) return (int)floor(val + 0.5); }
+static inline UINT GDI_ROUND_UINT(double val) +{ + double ret = floor(val + 0.5); + if (ret > UINT_MAX) return UINT_MAX; + return (UINT)ret; +} + #define GET_DC_PHYSDEV(dc,func) \ get_physdev_entry_point( (dc)->physDev, FIELD_OFFSET(struct gdi_dc_funcs,func))