From 4fae03d105257d0cd0665bb1522353636be15ff0 Mon Sep 17 00:00:00 2001 From: whitequark Date: Mon, 1 Aug 2016 12:27:29 +0000 Subject: [PATCH] Unbreak TTF metrics. In 2.0, the distance between the points in the TTF request specified cap height. In 2.1, that was accidentally changed to some arbitrary value near cap height instead, due to a 72pt factor mess-up. This commit restores the old behavior. --- CHANGELOG.md | 1 + src/ttf.cpp | 29 +++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c126a2b..83ba900 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Bug fixes: * OS X: do not completely hide main window when defocused. * GTK: unbreak 3Dconnexion support. * When pasting transformed entities, multiply constraint values by scale. + * Fix TTF font metrics (restore the behavior from version 2.0). 2.1 --- diff --git a/src/ttf.cpp b/src/ttf.cpp index da9d227..0d9bfa7 100644 --- a/src/ttf.cpp +++ b/src/ttf.cpp @@ -211,15 +211,19 @@ static int CubicTo(const FT_Vector *c1, const FT_Vector *c2, const FT_Vector *p, return 0; } -static const FT_Outline_Funcs outline_funcs = { - MoveTo, LineTo, ConicTo, CubicTo, 0, 0 -}; - void TtfFont::PlotString(const std::string &str, SBezierList *sbl, Vector origin, Vector u, Vector v) { if(fontFace == NULL) oops(); + FT_Outline_Funcs outlineFuncs; + outlineFuncs.move_to = MoveTo; + outlineFuncs.line_to = LineTo; + outlineFuncs.conic_to = ConicTo; + outlineFuncs.cubic_to = CubicTo; + outlineFuncs.shift = 0; + outlineFuncs.delta = 0; + FT_Pos dx = 0; for(char32_t chr : ReadUTF8(str)) { uint32_t gid = FT_Get_Char_Index(fontFace, chr); @@ -228,8 +232,17 @@ void TtfFont::PlotString(const std::string &str, chr, ft_error_string(gid)); } - FT_F26Dot6 scale = fontFace->units_per_EM; - if(int fterr = FT_Set_Char_Size(fontFace, scale, scale, 72, 72)) { + // We always ask Freetype to give us a unit size character. + // It uses fixed point; put the unit size somewhere in the middle of the dynamic + // range of its 26.6 fixed point type, and adjust the factors so that the unit + // matches cap height. + FT_Size_RequestRec sizeRequest; + sizeRequest.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; + sizeRequest.width = 1 << 16; + sizeRequest.height = 1 << 16; + sizeRequest.horiResolution = 128; + sizeRequest.vertResolution = 128; + if(int fterr = FT_Request_Size(fontFace, &sizeRequest)) { dbp("freetype: cannot set character size: %s", ft_error_string(fterr)); return; @@ -274,9 +287,9 @@ void TtfFont::PlotString(const std::string &str, data.u = u; data.v = v; data.beziers = sbl; - data.factor = 1.0f/(float)scale; + data.factor = 1.0f/(float)(1 << 16); data.bx = bx; - if(int fterr = FT_Outline_Decompose(&fontFace->glyph->outline, &outline_funcs, &data)) { + if(int fterr = FT_Outline_Decompose(&fontFace->glyph->outline, &outlineFuncs, &data)) { dbp("freetype: bezier decomposition failed (gid %d): %s", gid, ft_error_string(fterr)); }