Commit 454aebb
Debug memory leak
Changed files (17)
modifiedlibbirdfont/BirdFontFile.valamodifiedlibbirdfont/BirdFontPart.valamodifiedlibbirdfont/EditPoint.valamodifiedlibbirdfont/EditPointHandle.valamodifiedlibbirdfont/Expander.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/GlyphCollection.valamodifiedlibbirdfont/KerningClasses.valamodifiedlibbirdfont/Ligatures.valamodifiedlibbirdfont/MenuAction.valamodifiedlibbirdfont/Path.valamodifiedlibbirdfont/Renderer/FallbackFont.valamodifiedlibbirdfont/Renderer/FontCache.valamodifiedlibbirdfont/Renderer/Text.valamodifiedlibbirdfont/Toolbox.valamodifiedlibbirdfont/VersionList.vala
Diff
@@ -1136,12 +1136,16 @@ class BirdFontFile : GLib.Object { foreach (Tag t in tag) { if (t.get_name () == "glyph") { parse_glyph (t, gc, name, unicode, selected_id, unassigned);+ + print (@"g e2: $(gc.get_current ().ref_count)\n"); } } if (new_glyph_collection) { font.add_glyph_collection (gc); }+ + print (@"g 2: $(gc.get_current ().ref_count)\n"); } private int parse_selected (Tag tag) {@@ -1209,7 +1213,11 @@ class BirdFontFile : GLib.Object { glyph.version_id = (has_id) ? id : (int) gc.length () + 1; gc.set_unassigned (unassigned);+ + print (@"i parse_glyph $(glyph.ref_count)\n"); gc.insert_glyph (glyph, selected || selected_id == id);+ glyph = new Glyph.no_lines ("");+ print (@"i2 parse_glyph $(glyph.ref_count)\n"); } private Path parse_path (Tag tag) { @@ -22,7 +22,7 @@ namespace BirdFont { * tells the parser that bfp files in parent directories should be excluded. */ public class BirdFontPart : GLib.Object{- Font font;+ unowned Font font; Gee.ArrayList<string> parts; string root_directory; @@ -164,6 +164,8 @@ public class EditPoint : GLib.Object { public Color? color = null; + static int n_points = 0;+ public EditPoint (double nx = 0, double ny = 0, PointType nt = PointType.NONE) { x = nx; y = ny;@@ -184,8 +186,15 @@ public class EditPoint : GLib.Object { x = 0; y = 0; }+ + n_points++;+ print (@"n_points: $(n_points)\n"); } + ~EditPoint () {+ n_points--;+ }+ public bool is_valid () { return is_valid_position (x, y); }@@ -77,7 +77,9 @@ public class EditPointHandle : GLib.Object { } } }- + + static int n_handles = 0;+ public EditPointHandle.empty() { this.parent = none; this.angle = 0;@@ -85,6 +87,8 @@ public class EditPointHandle : GLib.Object { this.type = PointType.NONE; this.active = false; this.selected = false;+ + n_handles++; } public EditPointHandle (EditPoint parent, double angle, double length) {@@ -94,8 +98,16 @@ public class EditPointHandle : GLib.Object { this.type = PointType.LINE_CUBIC; this.active = false; this.selected = false;+ + n_handles++;+ + print (@"EditPointHandle $(n_handles)\n"); } + ~EditPointHandle () {+ n_handles--;+ }+ public EditPointHandle copy () { EditPointHandle n = new EditPointHandle.empty (); n.angle = angle;@@ -42,11 +42,22 @@ public class Expander : GLib.Object { double content_height = 0; string? headline;- + Text title;+ public bool visible = true; public Expander (string? headline = null) { this.headline = headline;++ title = new Text ();++ if (headline != null) {+ title.set_text ((!) headline);+ title.use_cache (true);+ Theme.text_color (title, "Text Tool Box");+ title.set_font_size (17 * Toolbox.get_scale ());+ }+ tool = new Gee.ArrayList<Tool> (); } @@ -223,15 +234,9 @@ public class Expander : GLib.Object { public void draw (int wd, int hd, Context cr) { double yt = y + scroll + 2;- Text title; if (tool.size > 0) { if (headline != null) {- title = new Text ();- title.set_text ((!) headline);- title.use_cache (true);- Theme.text_color (title, "Text Tool Box");- title.set_font_size (17 * Toolbox.get_scale ()); title.draw_at_baseline (cr, x, yt + HEADLINE_MARGIN + 13 * Toolbox.get_scale ()); } }@@ -91,7 +91,7 @@ public class Font : GLib.Object { bool read_only = false; - /** Save font as many .bfp files instead of one big .bf */+ /** Save font as many small .bfp files instead of one big .bf file */ bool bfp = false; BirdFontPart bfp_file; @@ -437,7 +437,7 @@ public class Font : GLib.Object { warning ("glyph has already been added"); return; }- + glyph_name.insert (glyph_collection.get_name (), glyph_collection); if (glyph_collection.get_unicode () != "") {@@ -484,13 +484,7 @@ public class Font : GLib.Object { } /** Obtain all versions and alterntes for this glyph. */- public GlyphCollection? get_glyph_collection (string glyph) {- GlyphCollection? gc = get_cached_glyph_collection (glyph); - return gc;- }-- /** Get glyph collection by unichar code. */- public GlyphCollection? get_cached_glyph_collection (string unichar_code) {+ public GlyphCollection? get_glyph_collection (string unichar_code) { GlyphCollection? gc = null; gc = glyph_cache.get (unichar_code); return gc;@@ -19,6 +19,7 @@ using Gee; namespace BirdFont { public class Glyph : FontDisplay {+ // Background image BackgroundImage? background_image = null; bool background_image_visible = true;@@ -119,15 +120,32 @@ public class Glyph : FontDisplay { left_limit = -28; right_limit = 28;+ + n_instances++;+ + warning (@"glyphs $name: $(n_instances)"); }- + public Glyph.no_lines (string name, unichar unichar_code = 0) { this.name = name; this.unichar_code = unichar_code; path_list.add (new Path ());+ + n_instances++;+ warning (@"glyphs no lines $name: $(n_instances)"); }+ + static int n_instances = 0; + public int r = 1;+ + ~Glyph () {+ path_list.clear ();+ active_paths.clear ();+ n_instances--;+ }+ public GlyfData get_ttf_data () { if (ttf_data == null) { @@ -18,7 +18,7 @@ using Math; namespace BirdFont { public class GlyphCollection : GLib.Object {- VersionList versions;+ public VersionList versions; unichar unicode_character; string name; bool unassigned = false;@@ -26,7 +26,9 @@ public class GlyphCollection : GLib.Object { public GlyphCollection (unichar unicode_character, string name) { this.unicode_character = unicode_character; this.name = name;+ print (@"GlyphCollection: $(ref_count)\n"); versions = new VersionList (null, this);+ print (@"Afer version list GlyphCollection: $(ref_count)\n"); } public GlyphCollection.with_glyph (unichar unicode_character, string name) {@@ -36,9 +38,16 @@ public class GlyphCollection : GLib.Object { this.name = name; g = new Glyph (name, unicode_character);+ + print (@"GlyphCollection: $(ref_count)\n"); versions = new VersionList (g, this);+ print (@"Afer version list GlyphCollection: $(ref_count)\n"); } + ~GlyphCollection () {+ versions.glyphs.clear ();+ }+ public void set_unassigned (bool a) { unassigned = a; }@@ -60,7 +69,9 @@ public class GlyphCollection : GLib.Object { } public void insert_glyph (Glyph g, bool selected) {- versions.add_glyph (g, selected); + print (@"Before VersionList $(g.ref_count)\n");+ versions.add_glyph (g, selected);+ print (@"After VersionList $(g.ref_count)\n"); assert (versions.glyphs.size > 0); } @@ -37,7 +37,7 @@ public class KerningClasses : GLib.Object { /** Ensure that map iterator is not invalidated because of inserts. */ bool protect_map = false; - public Font font;+ public unowned Font font; public KerningClasses (Font font) { this.font = font;@@ -27,7 +27,7 @@ public class Ligatures : GLib.Object { public delegate void ContextualLigatureIterator (ContextualLigature lig); - Font font;+ unowned Font font; public Ligatures (Font font) { this.font = font;@@ -29,7 +29,6 @@ public class MenuAction : GLib.Object { public MenuAction (string label) { this.label = label;- text = new Text (label); } public void set_selected (bool s) {@@ -58,6 +57,7 @@ public class MenuAction : GLib.Object { cr.restore (); } + text = new Text (label); Theme.text_color (text, "Foreground 1"); text.draw_at_baseline (cr, x, y); }@@ -79,6 +79,8 @@ public class Path { public bool highlight_last_segment = false; public string point_data = "";++ static int n_paths = 0; public Path () { string width;@@ -93,8 +95,16 @@ public class Path { if (stroke_width < 1) { stroke_width = 1; }+ + n_paths++;+ print (@"Paths: $n_paths\n"); } + ~Path () {+ point_data = "";+ n_paths--;+ }+ public bool is_filled () { return fill; }@@ -111,7 +111,9 @@ public class FallbackFont : GLib.Object { } public Font get_single_glyph_font (unichar c) {- return load_glyph_from_ttf (c);+ Font f = load_glyph_from_ttf (c);+ print (@"font e1 : $(f.ref_count)\n");+ return f; } public Font load_glyph_from_ttf (unichar c) {@@ -120,14 +122,25 @@ public class FallbackFont : GLib.Object { FontFace* font; bf_font = new Font ();+ + if (bf_font != null)+ print (@"font e1 a : $(((!)bf_font).ref_count)\n");+ for (int i = fallback_fonts.size - 1; i >= 0; i--) { f = fallback_fonts.get (i); font = open_font ((!) f.get_path ()); bf_font = get_glyph_in_font ((!) font, c);+ + if (bf_font != null)+ print (@"font e1 b : $(((!)bf_font).ref_count)\n");+ close_font (font); if (bf_font != null) {+ if (((!)bf_font).get_glyph_by_name ((!) c.to_string ()) != null)+ print (@"first: $(((!) ((!)bf_font).get_glyph_by_name ((!) c.to_string ())).ref_count)\n");+ return (!) bf_font; } }@@ -141,16 +154,27 @@ public class FallbackFont : GLib.Object { BirdFontFile bf_parser; Font bf_font = new Font (); + print (@"font e1 before load : $(bf_font.ref_count)\n");+ gc = new GlyphCollection (c, (!)c.to_string ()); glyph_data = load_glyph (font, (uint) c);- + if (glyph_data == null) { return null; } + print (@"font e1 before parser : $(bf_font.ref_count)\n"); bf_parser = new BirdFontFile (bf_font);+ print (@"font e2 before parser1 : $(bf_font.ref_count)\n"); bf_parser.load_data (((!) glyph_data).str);- + print (@"font e1 before parser load : $(bf_font.ref_count)\n");++ if (((!)bf_font).get_glyph_by_name ((!) c.to_string ()) != null)+ print (@"after parser: $(((!) ((!)bf_font).get_glyph_by_name ((!) c.to_string ())).ref_count)\n");++ bf_parser = new BirdFontFile (new Font ());+ print (@"font e1 after remove parser : $(bf_font.ref_count)\n");+ return bf_font; } @@ -104,7 +104,7 @@ public class FontCache { } public Glyph? get_glyph_by_name (string name) {- Font f;+ Font f = new Font (); Glyph? g = null; if (font != null) {@@ -112,13 +112,60 @@ public class FontCache { } if (g == null && name.char_count () == 1) {+ return null; //FIXME+ 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; + bottom_limit = f.bottom_limit; + + GlyphCollection? gc = f.get_glyph_collection (name);+ if (gc != null) {+ print (@"GC BEFORE UNREF: $(((!)gc).ref_count)\n");+ }+ + print (@"before bad unref: $(((!)g).ref_count)\n");+ //((!)g).unref (); //FIXME: + f = new Font (); // FIXME DELTE+ print (@"after bad unref: $(((!)g).ref_count)\n");++ if (gc != null) {+ print (@"GC AFTER UNREF: $(((!)gc).ref_count)\n");+ }++ }+ + print (@"font in get_glyph_by_name: $(f.ref_count)\n");++ + if (g != null) {+ print (@"b: $(((!)g).ref_count)\n"); + }+ + + Glyph tg;+ + // FIXME: DELETE+ tg = new Glyph ("");+ print (@"tg: $(tg.ref_count)\n");+ + {+ GlyphCollection tgc = new GlyphCollection ('\0', "");+ tgc.add_glyph (tg);+ + print (@"after add tg: $(tg.ref_count)\n");+ + tgc.versions.glyphs.clear (); } + print (@"DONE tg: $(tg.ref_count)\n");+ return g; } @@ -48,6 +48,8 @@ public class Text : Widget { bool use_cached_glyphs = true; double truncated_width = -1; + static int ntext = 0;+ public Text (string text = "", double size = 17, double margin_bottom = 0) { this.margin_bottom = margin_bottom; font_cache = FontCache.get_default_cache ();@@ -55,8 +57,16 @@ public class Text : Widget { set_font_size (size); set_text (text);+ + warning (@"ntext: $(ntext)");+ ntext++; }-+ + ~Text () {+ ntext--;+ warning (@"remove ntext: $(ntext)");+ }+ public void use_cache (bool cache) { use_cached_glyphs = cache; }@@ -105,7 +115,7 @@ public class Text : Widget { index = 0; while (text.get_next_char (ref index, out c)) { name = (!) c.to_string ();- g = cached_font.get_glyph_by_name (name);+ g = cached_font.get_glyph_by_name (name); gs.glyph.add (g); glyph_names.add (name); }@@ -118,10 +128,10 @@ public class Text : Widget { double w, kern; int wi; Glyph? prev;+ Glyph? g; GlyphSequence word_with_ligatures; GlyphRange? gr_left, gr_right; GlyphSequence word;- Glyph? g; KerningClasses kc; glyph = new Glyph.no_lines ("", '\0');@@ -129,10 +139,10 @@ public class Text : Widget { w = 0; prev = null; kern = 0;- + word = glyph_sequence; wi = 0;- + if (cached_font.font != null) { word_with_ligatures = word.process_ligatures ((!) cached_font.font); } else {@@ -149,7 +159,6 @@ public class Text : Widget { } for (int i = 0; i < word_with_ligatures.glyph.size; i++) {- g = word_with_ligatures.glyph.get (i); if (g == null || prev == null || wi == 0) {@@ -170,8 +179,7 @@ public class Text : Widget { } glyph = (g == null) ? cached_font.get_not_def_character ().get_current () : (!) g;- iter (glyph, kern, i + 1 == word_with_ligatures.glyph.size);- + iter (glyph, kern, i + 1 == word_with_ligatures.glyph.size); prev = g; wi++; }@@ -346,7 +354,7 @@ public class Text : Widget { return; } - draw_chached (cr ,glyph, kerning, last, x, y, cc_y, + draw_chached (cr, glyph, kerning, last, x, y, cc_y, ratio, cacheid); x = end;@@ -298,7 +298,7 @@ public class Toolbox : GLib.Object { warn_if_test ("Don't redraw toolbox when background thread is running."); return; }- + Toolbox t = MainWindow.get_toolbox (); if (!is_null (t)) { t.redraw (0, 0, allocation_width, allocation_height);@@ -19,13 +19,15 @@ namespace BirdFont { public class VersionList : DropMenu { public int current_version_id = -1;- GlyphCollection glyph_collection;+ unowned GlyphCollection glyph_collection; public Gee.ArrayList<Glyph> glyphs; public VersionList (Glyph? g = null, GlyphCollection glyph_collection) { base (); + print (@"VersionList: glyph_collection: $(glyph_collection.ref_count)\n");+ this.glyph_collection = glyph_collection; glyphs = new Gee.ArrayList<Glyph> (); set_direction (MenuDirection.POP_UP);@@ -41,45 +43,51 @@ public class VersionList : DropMenu { add_new_version (); current_version_id = glyphs.get (glyphs.size - 1).version_id; };- + // delete one version signal_delete_item.connect ((index) => {- int current_version;- Font font = BirdFont.get_current_font ();- OverView over_view = MainWindow.get_overview ();- - font.touch ();- - index--; // first item is the add new action- - // delete the entire glyph if the last remaining version is removed- if (glyphs.size == 1) {- over_view.store_undo_state (glyph_collection.copy ());- font.delete_glyph (glyph_collection);- return;- }- - return_if_fail (0 <= index < glyphs.size);- - font.deleted_glyphs.add (glyph_collection.get_current ());- - over_view.store_undo_state (glyph_collection.copy ());- glyphs.remove_at (index);- - recreate_index ();- - current_version = get_current_version_index ();- if (index == current_version) {- set_selected_item (get_action_no2 ()); // select the first glyph if the current glyph is deleted- } else if (index < current_version) {- return_if_fail (0 <= current_version - 1 < glyphs.size);- current_version_id = glyphs.get (current_version - 1).version_id;- }+ delete_item (index); }); if (g != null) { add_glyph ((!) g); }++ }++ private void delete_item (int index) {+ int current_version;+ Font font = BirdFont.get_current_font ();+ OverView over_view = MainWindow.get_overview ();+ + font.touch ();+ + index--; // first item is the add new action+ + // delete the entire glyph if the last remaining version is removed+ if (glyphs.size == 1) {+ over_view.store_undo_state (glyph_collection.copy ());+ font.delete_glyph (glyph_collection);+ return;+ }+ + return_if_fail (0 <= index < glyphs.size);+ + font.deleted_glyphs.add (glyph_collection.get_current ());+ + over_view.store_undo_state (glyph_collection.copy ());+ + glyphs.remove_at (index);+ + recreate_index ();+ + current_version = get_current_version_index ();+ if (index == current_version) {+ set_selected_item (get_action_no2 ()); // select the first glyph if the current glyph is deleted+ } else if (index < current_version) {+ return_if_fail (0 <= current_version - 1 < glyphs.size);+ current_version_id = glyphs.get (current_version - 1).version_id;+ } } private int get_current_version_index () {