The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

Fix text rendering

These changes was commited to the Birdfont repository Mon, 21 Sep 2015 17:16:37 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
author Johan Mattsson <johan.mattsson.m@gmail.com>
Mon, 21 Sep 2015 17:16:37 +0000 (19:16 +0200)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Mon, 21 Sep 2015 17:16:37 +0000 (19:16 +0200)
commit a94c39a194784fece1aee60451dea2d08fcecc1c
tree 773f157f792e2ff81f4d9cd2ac07b92db556aef8
parent c23fd2b9033eccb62ad99074cecaf7033cd34bd1
Fix text rendering
Store font size for each glyph loaded from a fallback font. (Animated case bug)

libbirdfont/Glyph.vala
libbirdfont/Renderer/CachedFont.vala
libbirdfont/Renderer/Text.vala
libbirdfont/Renderer/TextArea.vala
libbirdfont/Tool.vala
--- a/libbirdfont/Glyph.vala +++ b/libbirdfont/Glyph.vala @@ -120,6 +120,11 @@ public int current_layer = 0; public Gee.ArrayList<Path> active_paths = new Gee.ArrayList<Path> (); public Gee.ArrayList<Layer> selected_groups = new Gee.ArrayList<Layer> (); + + // used if this glyph is fetched from a fallback font + public double top_limit = 0; + public double baseline = 0; + public double bottom_limit = 0; public Glyph (string name, unichar unichar_code = 0) { this.name = name;
--- a/libbirdfont/Renderer/CachedFont.vala +++ b/libbirdfont/Renderer/CachedFont.vala @@ -45,32 +45,50 @@ static FallbackFont? _fallback_font = null; public CachedFont (Font? font) { + Glyph? g; + Glyph glyph; + this.font = font; + + g = get_glyph_by_name ("a"); + if (g != null) { + glyph = (!) g; + base_line = glyph.baseline; + top_limit = glyph.top_limit; + bottom_limit = glyph.bottom_limit; + } else { + warning("No default chararacter found in font."); + } } public Glyph? get_glyph_by_name (string name) { Glyph? g = null; + Font f; if (font != null) { - g = ((!) font).get_glyph_by_name (name); + f = (!) font; + g = f.get_glyph_by_name (name); + g.top_limit = f.top_limit; + g.baseline = f.base_line; + g.bottom_limit = f.bottom_limit; } if (g == null && name.char_count () == 1) { - Font f = fallback_font.get_single_glyph_font (name.get_char (0)); + f = fallback_font.get_single_glyph_font (name.get_char (0)); g = f.get_glyph_by_name (name); if (g == null) { return null; } - top_limit = f.top_limit; - base_line = f.base_line; - bottom_limit = f.bottom_limit; + g.top_limit = f.top_limit; + g.baseline = f.base_line; + g.bottom_limit = f.bottom_limit; } - + return g; } } }
--- a/libbirdfont/Renderer/Text.vala +++ b/libbirdfont/Renderer/Text.vala @@ -38,7 +38,7 @@ public delegate void Iterator (Glyph glyph, double kerning, bool last); public double font_size; - public double sidebearing_extent = 0; + double sidebearing_extent = 0; public double r = 0; public double g = 0; @@ -187,7 +187,6 @@ // FIXME: some fonts doesn't have on curve extrema public double get_extent () { double x = 0; - double ratio = get_scale (); iterate ((glyph, kerning, last) => { double x1, y1, x2, y2; @@ -196,10 +195,10 @@ lsb = glyph.left_limit; if (!last) { - x += (glyph.get_width () + kerning) * ratio; + x += (glyph.get_width () + kerning) * get_scale (glyph); } else { glyph.boundaries (out x1, out y1, out x2, out y2); - x += (x2 - lsb) * ratio; + x += (x2 - lsb) * get_scale (glyph); } }); @@ -215,16 +214,11 @@ } x = 0; - ratio = get_scale (); - - if (unlikely (ratio == 0)) { - warning ("No scale."); - } - + iterate ((glyph, kerning, last) => { double lsb; lsb = glyph.left_limit; - x += (glyph.get_width () + kerning) * ratio; + x += (glyph.get_width () + kerning) * get_scale (glyph); }); sidebearing_extent = x; @@ -236,25 +230,24 @@ } public double get_acender () { - double ratio = get_scale (); double max_height = 0; - + iterate ((glyph, kerning, last) => { double x1, y1, x2, y2; double h; glyph.boundaries (out x1, out y1, out x2, out y2); - h = Math.fmax (y1, y2) - Math.fmin (y1, y2) ; + h = Math.fmax (y1, y2) - Math.fmin (y1, y2); + h *= get_scale(glyph) - glyph.baseline * get_scale(glyph); if (h > max_height) { max_height = h; } }); - return max_height * ratio - cached_font.base_line * ratio; + return max_height; } public override double get_width () { double x = 0; - double ratio = get_scale (); bool first = true; iterate ((glyph, kerning, last) => { @@ -265,13 +258,13 @@ if (first) { glyph.boundaries (out x1, out y1, out x2, out y2); - x += (glyph.get_width () + kerning - Math.fmin (x1, x2)) * ratio; + x += (glyph.get_width () + kerning - Math.fmin (x1, x2)) * get_scale (glyph); first = false; } else if (!last) { - x += (glyph.get_width () + kerning) * ratio; + x += (glyph.get_width () + kerning) * get_scale (glyph); } else { glyph.boundaries (out x1, out y1, out x2, out y2); - x += (x2 - lsb) * ratio; + x += (x2 - lsb) * get_scale (glyph); } }); @@ -279,32 +272,31 @@ } public double get_decender () { - double ratio = get_scale (); - double min_y = 0; - double decender; + double decender = 0; + double decender_max = 0; iterate ((glyph, kerning, last) => { double x1, y1, x2, y2; double y; glyph.boundaries (out x1, out y1, out x2, out y2); y = Math.fmin (y1, y2); - if (y < min_y) { - min_y = y; + decender = (glyph.baseline - y) * get_scale (glyph); + if (decender > decender_max) { + decender_max = decender; } }); - decender = cached_font.base_line * ratio - min_y * ratio; - return decender > 0 ? decender : 0; + return decender_max > 0 ? decender_max : 0; } public override void draw (Context cr) { double descender = cached_font.bottom_limit + cached_font.base_line; - double y = widget_y + get_height () + get_scale () * descender; + double y = widget_y + get_height () + get_font_scale () * descender; // FIXME: draw_at_baseline (cr, widget_x, y); } public void draw_at_top (Context cr, double px, double py, string cacheid = "") { - double s = get_scale (); + double s = get_font_scale (); double y = py + s * (cached_font.top_limit - cached_font.base_line); draw_at_baseline (cr, px, y, cacheid); } @@ -336,7 +328,7 @@ double ratio; double cc_y; - ratio = get_scale (); + ratio = get_font_scale (); cc_y = (cached_font.top_limit - cached_font.base_line) * ratio; y = py; @@ -451,7 +443,7 @@ EditPoint e, prev; double xa, ya, xb, yb, xc, yc, xd, yd; double by; - double s = get_scale (); + double s = get_scale (glyph); if (path.points.size > 0) { if (unlikely (path.is_open ())) { @@ -488,14 +480,28 @@ } } - public double get_baseline_to_bottom () { - return get_scale () * (-cached_font.base_line - cached_font.bottom_limit); + public double get_baseline_to_bottom (Glyph g) { + return get_scale (g) * (-g.baseline - g.bottom_limit); } - public double get_scale () { + public double get_scale (Glyph g) { + double s = g.top_limit - g.bottom_limit; + + if (s == 0) { + s = cached_font.top_limit - cached_font.bottom_limit; + } + + return font_size / s; + } + + public double get_font_scale () { return font_size / (cached_font.top_limit - cached_font.bottom_limit); } + public double get_baseline_to_bottom_for_font () { + return get_font_scale () * (-cached_font.base_line - cached_font.bottom_limit); + } + public void truncate (double max_width) { truncated_width = max_width; }
--- a/libbirdfont/Renderer/TextArea.vala +++ b/libbirdfont/Renderer/TextArea.vala @@ -829,7 +829,7 @@ c.paragraph = i; } - cw = (glyph.get_width ()) * next_word.get_scale () + kerning; + cw = (glyph.get_width ()) * next_word.get_font_scale () + kerning; ci = gc.length; tx += cw; @@ -1070,7 +1070,7 @@ width = this.width - padding; x += padding; - scale = word.get_scale (); + scale = word.get_font_scale (); y += font_size; // draw selection background @@ -1100,7 +1100,7 @@ w = next_word.text; wl = w.length; - scale = next_word.get_scale (); + scale = next_word.get_font_scale (); if (selection_start.paragraph == selection_stop.paragraph) { partial_start = true; @@ -1132,7 +1132,7 @@ || (index < selection_stop.character_index && !partial_start && partial_stop) || (selection_start.character_index <= index < selection_stop.character_index && partial_start && partial_stop); - cwi = (glyph.get_width ()) * next_word.get_scale () + kerning; + cwi = (glyph.get_width ()) * next_word.get_font_scale () + kerning; if (draw) { double selection_y = widget_y + next_word.widget_y + scale * -next_word.cached_font.bottom_limit - font_size; @@ -1263,10 +1263,10 @@ if (carret.character_index == ch_index) { pos_x = next_word.widget_x + widget_x + padding; - pos_y = widget_y + next_word.widget_y + next_word.get_baseline_to_bottom (); + pos_y = widget_y + next_word.widget_y + next_word.get_baseline_to_bottom_for_font (); } else if (carret.character_index >= ch_index + wl) { pos_x = next_word.widget_x + next_word.get_sidebearing_extent () + widget_x + padding; - pos_y = widget_y + next_word.widget_y + next_word.get_baseline_to_bottom (); + pos_y = widget_y + next_word.widget_y + next_word.get_baseline_to_bottom_for_font (); if (next_word.text.has_suffix ("\n")) { pos_x = widget_x + padding; @@ -1274,7 +1274,7 @@ } } else if (ch_index < carret.character_index <= ch_index + wl) { tx = widget_x + next_word.widget_x; - ty = widget_y + next_word.widget_y + next_word.get_baseline_to_bottom (); + ty = widget_y + next_word.widget_y + next_word.get_baseline_to_bottom_for_font (); if (carret.character_index <= ch_index) { pos_x = widget_x + padding; @@ -1285,7 +1285,7 @@ double cw; int ci; - cw = (glyph.get_width ()) * next_word.get_scale () + kerning; + cw = (glyph.get_width ()) * next_word.get_font_scale () + kerning; ci = ((!) glyph.get_unichar ().to_string ()).length; if (ch_index < carret.character_index <= ch_index + ci) {
--- a/libbirdfont/Tool.vala +++ b/libbirdfont/Tool.vala @@ -354,7 +354,7 @@ icon_font.widget_x = iconx; icon_font.widget_y = icony; - + icon_font.draw (cr); cr.restore ();