The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

More speed optimizations in the overview tab

These changes was commited to the Birdfont repository Wed, 16 Dec 2015 01:32:58 +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>
Wed, 16 Dec 2015 01:32:58 +0000 (02:32 +0100)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Wed, 16 Dec 2015 01:32:58 +0000 (02:32 +0100)
commit 4a343aae6b6200f30aaa623ee24718f0aebf042e
tree 58625950148268e5fcd5a53f1ed5b6ce4c7be484
parent 1a7b08e939cb75ac0ef4a3b9d10e4cb1b38d2947
More speed optimizations in the overview tab

libbirdfont/GlyphRange.vala
libbirdfont/OverView.vala
libbirdfont/OverViewItem.vala
--- a/libbirdfont/GlyphRange.vala +++ b/libbirdfont/GlyphRange.vala @@ -28,6 +28,7 @@ bool range_is_class = false; uint32* range_index = null; int index_size = 0; + int index_hint = 0; public GlyphRange () { ranges = new Gee.ArrayList<UniRange> (); @@ -430,8 +431,14 @@ private void get_unirange_index (uint32 index, out UniRange? range, out uint32 range_start_index) { int lower = 0; int upper = index_size - 1; - int i = lower + (upper - lower) / 2; + int i; int end = index_size - 1; + + if (index_hint >= 0 && index_hint < index_size) { + i = index_hint; + } else { + i = (lower + upper) / 2; + } range_start_index = -1; range = null; @@ -444,10 +451,12 @@ if (i == end) { range_start_index = range_index[i]; range = ranges.get (i); + index_hint = i; break; } else if (range_index[i] <= index && range_index[i + 1] > index) { range_start_index = range_index[i]; range = ranges.get (i); + index_hint = i; break; } @@ -461,42 +470,50 @@ upper = i - 1; } - i = lower + (upper - lower) / 2; + i = (lower + upper) / 2; } } public string get_char (uint32 index) { + StringBuilder sb; + + sb = new StringBuilder (); + sb.append_unichar (get_character (index)); + + return sb.str; + } + + public unichar get_character (uint32 index) { int64 ti; string chr; UniRange r; - StringBuilder sb; unichar c; UniRange? range; uint32 range_start_index; if (unlikely (index > len + unassigned.size)) { - return "\0".dup(); + return '\0'; } if (index >= len) { if (unlikely (index - len >= unassigned.size)) { - return "\0".dup(); + return '\0'; } chr = unassigned.get ((int) (index - len)); - return chr; + return chr.get_char (); } get_unirange_index (index, out range, out range_start_index); if (unlikely (range == null)) { warning (@"No range found for index $index"); - return ""; + return '\0'; } if (unlikely (range_start_index > index || range_start_index == -1)) { warning ("Index out of bounds in glyph range."); - return ""; + return '\0'; } r = (!) range; @@ -504,13 +521,10 @@ if (unlikely (!c.validate ())) { warning ("Not a valid unicode character."); - return ""; + return '\0'; } - sb = new StringBuilder (); - sb.append_unichar (c); - - return sb.str; + return c; } public uint32 length () {
--- a/libbirdfont/OverView.vala +++ b/libbirdfont/OverView.vala @@ -20,7 +20,7 @@ public class OverView : FontDisplay { public WidgetAllocation allocation = new WidgetAllocation (); - public OverViewItem selected_item = new OverViewItem (null, '\0', 0, 0); + public OverViewItem selected_item = new OverViewItem (); public Gee.ArrayList<GlyphCollection> copied_glyphs = new Gee.ArrayList<GlyphCollection> (); public Gee.ArrayList<GlyphCollection> selected_items = new Gee.ArrayList<GlyphCollection> (); @@ -490,7 +490,7 @@ OverViewItem get_selected_item () { if (visible_items.size == 0) { - return new OverViewItem (null, '\0', 0, 0); + return new OverViewItem (); } if (!(0 <= selected < visible_items.size)) { @@ -518,7 +518,7 @@ update_scheduled = true; } - public void process_update_item_list () { + public void process_item_list_update () { string character_string; Font f = BirdFont.get_current_font (); GlyphCollection? glyphs = null; @@ -529,80 +529,118 @@ Glyph glyph; double tab_with; int item_list_length; + int visible_size; Test test = new Test.time("update_item_list"); - tab_with = allocation.width - 30; // scrollbar + tab_with = allocation.width - 30; // scrollbar items_per_row = get_items_per_row (); rows = (int) (allocation.height / OverViewItem.full_height ()) + 2; item_list_length = items_per_row * rows; - + foreach (OverViewItem overview_item in visible_items) { overview_item.cancel_thumbnail_rendering (); } - visible_items = new Gee.ArrayList<OverViewItem> (); - - // update item list + visible_items.clear (); + Test test3 = new Test.time("two conditions"); + index = (uint32) first_visible; x = OverViewItem.margin; y = OverViewItem.margin; - for (int i = 0; i < item_list_length; i++) { - if (all_available) { - if (! (0 <= index < f.length ())) { - break; - } - + + if (all_available) { + uint font_length = f.length (); + + for (int i = 0; i < item_list_length && index < font_length; i++) { glyphs = f.get_glyph_collection_index ((uint32) index); return_if_fail (glyphs != null); glyph = ((!) glyphs).get_current (); character_string = glyph.name; character = glyph.unichar_code; - } else { - if (!(0 <= index < glyph_range.get_length ())) { - break; - } - character_string = glyph_range.get_char ((uint32) index); - glyphs = f.get_glyph_collection_by_name (character_string); - character = character_string.get_char (0); + item = new OverViewItem (); + item.set_glyphs (glyphs); + item.set_character (character); + item.x = x; + item.y = y; + visible_items.add (item); + index++; } + } else { + + Test test_mk = new Test.time("mk items"); + uint32 glyph_range_size = glyph_range.get_length (); - x += OverViewItem.full_width (); + for (int i = 0; i < item_list_length && index < glyph_range_size; i++) { + item = new OverViewItem (); + visible_items.add (item); + } + warning (test_mk.get_test_time ()); - if (x + OverViewItem.full_width () >= tab_with) { - x = OverViewItem.margin; - y += OverViewItem.full_height (); + Test test_gl = new Test.time("get_glyph"); + visible_size = visible_items.size; + for (int i = 0; i < visible_size; i++) { + item = visible_items.get (i); + glyphs = f.get_glyph_collection_by_name ((!) item.character.to_string ()); + item.set_glyphs (glyphs); } + warning (test_gl.get_test_time ()); + + Test test_a = new Test.time("get_char"); - bool selected_item = (i == selected); + visible_size = visible_items.size; + for (int i = 0; i < visible_size; i++) { + item = visible_items.get (i); + character = glyph_range.get_character ((uint32) index); + item.set_character (character); + index++; + } + warning (test_a.get_test_time ()); + } + + Test test_b = new Test.time("adjust pos"); + x = OverViewItem.margin; + y = OverViewItem.margin; + + visible_size = visible_items.size; + int selected_index; + bool selected_item; + double full_width = OverViewItem.full_width (); + + for (int i = 0; i < visible_size; i++) { + item = visible_items.get (i); + + selected_item = false; if (glyphs != null) { - selected_item |= selected_items.index_of ((!) glyphs) != -1; + selected_index = selected_items.index_of ((!) glyphs); + selected_item = (selected_index != -1); } - if (i >= visible_items.size) { - item = new OverViewItem (glyphs, character, x, y); - item.adjust_scale (); - item.selected = selected_item; - visible_items.add (item); - } else { - visible_items.get (i).init (glyphs, character, x, y); - } + item.adjust_scale (); - index++; + selected_item |= (i == selected); + item.selected = selected_item; + + item.x = x + view_offset_y; + item.y = y + view_offset_x; + + x += full_width; + + if (x + full_width >= tab_with) { + x = OverViewItem.margin; + y += OverViewItem.full_height (); + } } - foreach (OverViewItem i in visible_items) { - i.y += view_offset_y; - i.x += view_offset_x; - } + warning (test_b.get_test_time ()); + warning (test3.get_test_time ()); warning (test.get_test_time ()); - update_scheduled = false; } @@ -612,7 +650,7 @@ || this.allocation.height != allocation.height || this.allocation.width == 0) { this.allocation = allocation; - process_update_item_list (); + process_item_list_update (); } Test test = new Test.time("Overview.draw");
--- a/libbirdfont/OverViewItem.vala +++ b/libbirdfont/OverViewItem.vala @@ -52,22 +52,25 @@ private bool cancel_thumbnail = false; - public OverViewItem (GlyphCollection? glyphs, unichar character, double x, double y) { - init (glyphs, character, x, y); + public OverViewItem () { } - // this method makes it possible for the overview tab to reuse its items as a speed optimization - public void init (GlyphCollection? glyphs, unichar character, double x, double y) { - this.x = x; - this.y = y; + public void set_character (unichar character) { this.character = character; - this.glyphs = glyphs; - this.info = new CharacterInfo (character, glyphs); - - label = new Text ((!) character.to_string (), 17); - truncate_label (); - - if (glyphs != null) { + info = new CharacterInfo (character, glyphs); + + if (glyphs == null) { + label = new Text (); + } else { + label = new Text ((!) character.to_string (), 17); + truncate_label (); + } + } + + public void set_glyphs (GlyphCollection? gc) { + glyphs = gc; + + if (glyphs != null) { version_menu = new VersionList ((!) glyphs); version_menu.add_glyph_item.connect ((glyph) => { ((!) glyphs).insert_glyph (glyph, true); @@ -79,10 +82,8 @@ v.update_item_list (); GlyphCanvas.redraw (); }); - } else { - version_menu = new VersionList (new GlyphCollection (character, (!) character.to_string ())); - } - + } + thumbnail_mutex.lock (); if (!is_null (thumbnail_queue)) { thumbnail_queue.offer (this); @@ -119,12 +120,7 @@ thumbnail_mutex.unlock (); if (!cancel) { - IdleSource idle = new IdleSource (); - idle.set_callback (() => { - item.draw_background (); - return false; - }); - idle.attach (null); + item.draw_background (); } } else { thumbnail_mutex.lock (); @@ -134,7 +130,11 @@ } } - public void draw_background () { // FIXME: LOCK for Text and thread exit + public void draw_glyph_from_font () { + if (glyphs == null) { + return; + } + Glyph g; Font font; double gx, gy; @@ -154,28 +154,58 @@ s = Screen.create_background_surface ((int) width, (int) height - 20); c = new Context (s); - if (glyphs != null) { - font = BirdFont.get_current_font (); - g = ((!) glyphs).get_current (); - - c.save (); - g.boundaries (out x1, out y1, out x2, out y2); + g = ((!) glyphs).get_current (); - glyph_width = x2 - x1; - glyph_height = y2 - y1; - - c.save (); - c.scale (glyph_scale * Screen.get_scale (), glyph_scale * Screen.get_scale ()); + c.save (); + g.boundaries (out x1, out y1, out x2, out y2); + + glyph_width = x2 - x1; + glyph_height = y2 - y1; + + c.save (); + c.scale (glyph_scale * Screen.get_scale (), glyph_scale * Screen.get_scale ()); - g.add_help_lines (); - - gx = ((w / glyph_scale) - glyph_width) / 2 - g.get_left_side_bearing (); - gy = (h / glyph_scale) - 25 / glyph_scale; - - c.translate (gx - Glyph.xc () - g.get_lsb (), g.get_baseline () + gy - Glyph.yc ()); - - g.draw_paths (c, color); - c.restore (); + g.add_help_lines (); + + gx = ((w / glyph_scale) - glyph_width) / 2 - g.get_left_side_bearing (); + gy = (h / glyph_scale) - 25 / glyph_scale; + + c.translate (gx - Glyph.xc () - g.get_lsb (), g.get_baseline () + gy - Glyph.yc ()); + + g.draw_paths (c, color); + c.restore (); + + cache = s; + GlyphCanvas.redraw (); + } + + public void draw_background () { // FIXME: LOCK for Text and thread exit + Glyph g; + Font font; + double gx, gy; + double x1, x2, y1, y2; + double scale_box; + double w, h; + double glyph_width, glyph_height; + Surface s; + Context c; + Color color = Color.black (); + + w = width; + h = height; + + scale_box = width / DEFAULT_WIDTH; + + s = Screen.create_background_surface ((int) width, (int) height - 20); + c = new Context (s); + + if (glyphs != null) { // FIXME: lock + IdleSource idle_glyph = new IdleSource (); + idle_glyph.set_callback (() => { + draw_glyph_from_font (); + return false; + }); + idle_glyph.attach (null); } else { c.scale (Screen.get_scale (), Screen.get_scale ()); @@ -185,20 +215,21 @@ Theme.text_color (fallback, "Overview Glyph"); fallback.set_text ((!) character.to_string ()); double font_size = height * 0.8; + fallback.set_font_size (font_size); gx = (width - fallback.get_extent ()) / 2.0; gy = height - 30; - fallback.set_font_size (font_size); fallback.draw_at_baseline (c, gx, gy); c.restore (); - } - - IdleSource idle = new IdleSource (); - idle.set_callback (() => { - cache = s; - GlyphCanvas.redraw (); - return false; - }); - idle.attach (null); + + IdleSource idle = new IdleSource (); + idle.set_callback (() => { + cache = s; + GlyphCanvas.redraw (); + return false; + }); + idle.attach (null); + + } } public static void reset_label () {