Clone in a terminal:
Commit a94c39a
Johan Mattsson - 2015-09-21T17:16:37+00:00
a94c39a194784fece1aee60451dea2d08fcecc1cjohan.mattsson.m@gmail.com

Fix text rendering Store font size for each glyph loaded from a fallback font. (Animated case bug)

Changed files (5)

Diff

diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex 511a7b4..fbd2d86 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -121,6 +121,11 @@ public class Glyph : FontDisplay { 	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; 		this.unichar_code = unichar_code;diff --git a/libbirdfont/Renderer/CachedFont.vala b/libbirdfont/Renderer/CachedFont.valaindex bd84844..4f2a095 100644--- a/libbirdfont/Renderer/CachedFont.vala+++ b/libbirdfont/Renderer/CachedFont.vala@@ -45,29 +45,47 @@ public class CachedFont : GLib.Object { 	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; 	} }diff --git a/libbirdfont/Renderer/Text.vala b/libbirdfont/Renderer/Text.valaindex ca95187..f63cf24 100644--- a/libbirdfont/Renderer/Text.vala+++ b/libbirdfont/Renderer/Text.vala@@ -38,7 +38,7 @@ public class Text : Widget { 	 	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 @@ public class Text : Widget { 	// 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 @@ public class Text : Widget { 			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 @@ public class Text : Widget { 		} 		 		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 class Text : Widget { 	}  	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 @@ public class Text : Widget { 			 			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 class Text : Widget { 	}  	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 @@ public class Text : Widget { 		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 @@ public class Text : Widget { 		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 class Text : Widget { 		} 	} -	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; 	}diff --git a/libbirdfont/Renderer/TextArea.vala b/libbirdfont/Renderer/TextArea.valaindex 8eabcf8..3a0fd9e 100644--- a/libbirdfont/Renderer/TextArea.vala+++ b/libbirdfont/Renderer/TextArea.vala@@ -829,7 +829,7 @@ public class TextArea : Widget { 										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 @@ public class TextArea : Widget { 		 		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 @@ public class TextArea : Widget { 						 						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 @@ public class TextArea : Widget { 									|| (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 @@ public class TextArea : Widget {  			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 @@ public class TextArea : Widget { 				} 			} 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 @@ public class TextArea : Widget { 					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) {diff --git a/libbirdfont/Tool.vala b/libbirdfont/Tool.valaindex c7bf2f3..5ed886e 100644--- a/libbirdfont/Tool.vala+++ b/libbirdfont/Tool.vala@@ -354,7 +354,7 @@ public class Tool : Widget { 		 		icon_font.widget_x = iconx; 		icon_font.widget_y = icony;-+		 		icon_font.draw (cr); 		 		cr.restore ();

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112