From 0f304b4c649f919ac28d4858fd11e22fd3125eab Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 12 Apr 2016 13:38:09 +0000 Subject: [PATCH] Rigorously treat font scale factors. The old values were chosen without a good understanding of font metrics. --- src/drawconstraint.cpp | 6 +++--- src/drawentity.cpp | 2 +- src/glhelper.cpp | 21 +++++++++++++++------ src/solvespace.h | 3 ++- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/drawconstraint.cpp b/src/drawconstraint.cpp index 6551ee5..d748c9e 100644 --- a/src/drawconstraint.cpp +++ b/src/drawconstraint.cpp @@ -83,7 +83,7 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) { std::string s = Label(); double swidth = ssglStrWidth(s, th), - sheight = ssglStrHeight(th); + sheight = ssglStrCapHeight(th); // By default, the reference is from the center; but the style could // specify otherwise if one is present, and it could also specify a @@ -157,7 +157,7 @@ int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b) { double pixels = 1.0 / SS.GW.scale; std::string s = Label(); double swidth = ssglStrWidth(s, th) + 4*pixels, - sheight = ssglStrHeight(th) + 8*pixels; + sheight = ssglStrCapHeight(th) + 8*pixels; struct { Vector n; @@ -371,7 +371,7 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db, *ref = (*ref).ScaledBy(0.5).Plus(disp.offset); gu = gu.WithMagnitude(1); Vector trans = - (*ref).Plus(gu.ScaledBy(-1.5*ssglStrHeight(Style::DefaultTextHeight()))); + (*ref).Plus(gu.ScaledBy(-1.5*ssglStrCapHeight(Style::DefaultTextHeight()))); ssglWriteTextRefCenter("angle between skew lines", Style::DefaultTextHeight(), trans, gr, gu, LineCallback, this); } diff --git a/src/drawentity.cpp b/src/drawentity.cpp index 82dce99..5d70a46 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -679,7 +679,7 @@ void Entity::DrawOrGetDistance(void) { ssglWriteText(str, th, mm2, u, v, NULL, NULL); } else { Vector pos = mm2.Plus(u.ScaledBy(ssglStrWidth(str, th)/2)).Plus( - v.ScaledBy(ssglStrHeight(th)/2)); + v.ScaledBy(ssglStrCapHeight(th)/2)); Point2d pp = SS.GW.ProjectPoint(pos); dogd.dmin = min(dogd.dmin, pp.DistanceTo(dogd.mp) - 10); // If a line lies in a plane, then select the line, not diff --git a/src/glhelper.cpp b/src/glhelper.cpp index e4f6bb0..9c6ba4a 100644 --- a/src/glhelper.cpp +++ b/src/glhelper.cpp @@ -36,7 +36,21 @@ static const VectorGlyph &GetVectorGlyph(char32_t chr) { return GetVectorGlyph(0xfffd); // replacement character } +// The internal font metrics are as follows: +// * Cap height (measured on "A"): 87 +// * Ascender (measured on "h"): 87 +// * Descender (measured on "p"): -30 +// * Font size (ascender+descender): 126 +// Internally and in the UI, the vector font is sized using cap height. #define FONT_SCALE(h) ((h)/87.0) +double ssglStrCapHeight(double h) +{ + return /*cap height*/87.0 * FONT_SCALE(h) / SS.GW.scale; +} +double ssglStrFontSize(double h) +{ + return /*font size*/126.0 * FONT_SCALE(h) / SS.GW.scale; +} double ssglStrWidth(const std::string &str, double h) { int width = 0; @@ -51,11 +65,6 @@ double ssglStrWidth(const std::string &str, double h) } return width * FONT_SCALE(h) / SS.GW.scale; } -double ssglStrHeight(double h) -{ - // The characters have height ~90, as they appear in the table. - return 90.0 * FONT_SCALE(h) / SS.GW.scale; -} void ssglWriteTextRefCenter(const std::string &str, double h, Vector t, Vector u, Vector v, ssglLineFn *fn, void *fndata) { @@ -63,7 +72,7 @@ void ssglWriteTextRefCenter(const std::string &str, double h, Vector t, Vector u v = v.WithMagnitude(1); double scale = FONT_SCALE(h)/SS.GW.scale; - double fh = ssglStrHeight(h); + double fh = ssglStrCapHeight(h); double fw = ssglStrWidth(str, h); t = t.Plus(u.ScaledBy(-fw/2)); diff --git a/src/solvespace.h b/src/solvespace.h index 83939e3..cf2fd9f 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -355,8 +355,9 @@ void ssglWriteText(const std::string &str, double h, Vector t, Vector u, Vector ssglLineFn *fn, void *fndata); void ssglWriteTextRefCenter(const std::string &str, double h, Vector t, Vector u, Vector v, ssglLineFn *fn, void *fndata); +double ssglStrCapHeight(double h); +double ssglStrFontSize(double h); double ssglStrWidth(const std::string &str, double h); -double ssglStrHeight(double h); void ssglLockColorTo(RgbaColor rgb); void ssglStippledLine(Vector a, Vector b, double width, int stippleType, double stippleScale, bool maybeFat);