The Birdfont Source Code


All Repositories / birdfont.git / commit – RSS feed

Add ligatures

These changes was commited to the Birdfont repository Mon, 29 Sep 2014 12:18: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>
Mon, 29 Sep 2014 12:18:58 +0000 (14:18 +0200)
committer Johan Mattsson <johan.mattsson.m@gmail.com>
Tue, 30 Sep 2014 10:44:34 +0000 (12:44 +0200)
commit dd8009322109f8c8b1b91219f2032441e47f124f
tree 3074ec9d7a907f2e1f5b468779a51ca8f804d9a3
parent 27219392990fed10e32f95ab75b07271bd97d3bf
Add ligatures

12 files changed:
birdfont/GtkWindow.vala
libbirdfont/BirdFontFile.vala
libbirdfont/ClipTool.vala
libbirdfont/Font.vala
libbirdfont/GlyphCollection.vala
libbirdfont/MenuTab.vala
libbirdfont/OpenFontFormat/Gsub.vala
libbirdfont/OverView.vala
libbirdfont/OverViewItem.vala
libbirdfont/PenTool.vala
libbirdfont/SvgParser.vala
--- a/birdfont/GtkWindow.vala +++ b/birdfont/GtkWindow.vala @@ -731,6 +731,12 @@ show_ligatures.activate.connect (() => { MenuTab.show_ligature_tab (); }); + + Gtk.MenuItem add_ligature = new Gtk.MenuItem.with_mnemonic (t_("_Add Ligature")); + ligature_menu.append (add_ligature); + add_ligature.activate.connect (() => { + MenuTab.add_ligature (); + }); // Add menus Gtk.MenuItem file_launcher = new Gtk.MenuItem.with_mnemonic (t_("_File"));
--- a/libbirdfont/BirdFontFile.vala +++ b/libbirdfont/BirdFontFile.vala @@ -33,27 +33,35 @@ public bool load (string path) { string xml_data; XmlParser parser; - bool ok; + bool ok = false; - FileUtils.get_contents(path, out xml_data); - - font.background_images.clear (); - font.font_file = path; - - parser = new XmlParser (xml_data); - ok = load_xml (parser); - + try { + FileUtils.get_contents(path, out xml_data); + + font.background_images.clear (); + font.font_file = path; + + parser = new XmlParser (xml_data); + ok = load_xml (parser); + } catch (GLib.FileError e) { + warning (e.message); + } + return ok; } public bool load_part (string bfp_file) { string xml_data; XmlParser parser; - bool ok; + bool ok = false; - FileUtils.get_contents(bfp_file, out xml_data); - parser = new XmlParser (xml_data); - ok = load_xml (parser); + try { + FileUtils.get_contents(bfp_file, out xml_data); + parser = new XmlParser (xml_data); + ok = load_xml (parser); + } catch (GLib.FileError e) { + warning (e.message); + } return ok; } @@ -195,6 +203,7 @@ os.put_string ("""<?xml version="1.0" encoding="utf-8" standalone="yes"?>"""); os.put_string ("\n"); os.put_string ("<font>\n"); + os.put_string ("<format>1.0</format>\n"); } public void write_closing_root_tag (DataOutputStream os) throws GLib.Error { @@ -302,7 +311,15 @@ } public void write_glyph_collection_start (GlyphCollection gc, DataOutputStream os) throws GLib.Error { - os.put_string (@"<collection unicode=\"$(Font.to_hex (gc.get_current ().unichar_code))\">\n"); + os.put_string ("<collection "); + + if (gc.get_current ().is_unassigned ()) { + os.put_string (@"name=\"$(gc.get_current ().get_name ())\""); + } else { + os.put_string (@"unicode=\"$(Font.to_hex (gc.get_current ().unichar_code))\""); + } + + os.put_string (">\n"); } public void write_glyph_collection_end (DataOutputStream os) throws GLib.Error { @@ -902,10 +919,12 @@ int selected_id = -1; Attribute attribute; Tag t; + bool unassigned = false; tag.reparse (); while (tag.has_more_attributes ()) { attribute = tag.get_next_attribute (); + if (attribute.get_name () == "unicode") { unicode = Font.to_unichar (attribute.get_content ()); b = new StringBuilder (); @@ -915,6 +934,14 @@ if (name == "") { name = ".null"; } + + unassigned = false; + } + + if (attribute.get_name () == "name") { + unicode = '\0'; + name = attribute.get_content (); + unassigned = true; } } @@ -937,7 +964,7 @@ t = tag.get_next_tag (); if (t.get_name () == "glyph") { - parse_glyph (t, gc, name, unicode, selected_id); + parse_glyph (t, gc, name, unicode, selected_id, unassigned); } } @@ -969,7 +996,8 @@ return id; } - private void parse_glyph (Tag tag, GlyphCollection gc, string name, unichar unicode, int selected_id) { + private void parse_glyph (Tag tag, GlyphCollection gc, string name, + unichar unicode, int selected_id, bool unassigned) { Glyph glyph = new Glyph (name, unicode); Path path; bool selected = false; @@ -1015,7 +1043,8 @@ } } - glyph.version_id = (has_id) ? id : (int) gc.length () + 1; + glyph.version_id = (has_id) ? id : (int) gc.length () + 1; + glyph.set_unassigned (unassigned); gc.insert_glyph (glyph, selected || selected_id == id); }
--- a/libbirdfont/ClipTool.vala +++ b/libbirdfont/ClipTool.vala @@ -157,14 +157,29 @@ if (overview) { o = MainWindow.get_overview (); + unichar last_assigned = '\0'; foreach (GlyphCollection gc in o.selected_items) { s.append ("\n"); s.append ("<!-- BirdFontClipboard\n"); - s.append ("BF glyph: "); - s.append (@"$(Font.to_hex (gc.get_unicode_character ()))"); + if (!gc.is_unassigned ()) { + last_assigned = gc.get_unicode_character (); + + s.append ("BF glyph: "); + s.append (@"$(Font.to_hex (gc.get_unicode_character ()))"); + s.append ("\n"); + } else { + last_assigned++; + + s.append ("BF glyph: "); + s.append (@"$(Font.to_hex (last_assigned))"); + s.append ("\n"); + } + + s.append ("BF unassigned: "); + s.append (@"$(gc.is_unassigned ())"); s.append ("\n"); - + s.append ("BF left: "); s.append (@"$(gc.get_current ().left_limit)"); s.append ("\n"); @@ -191,6 +206,10 @@ s.append (@"$(Font.to_hex (glyph.unichar_code))"); s.append ("\n"); + s.append ("BF unassigned: "); + s.append (@"$(glyph.is_unassigned ())"); + s.append ("\n"); + s.append ("BF left: "); s.append (@"$(glyph.left_limit)"); s.append ("\n"); @@ -272,8 +291,6 @@ Gee.ArrayList<Glyph> glyphs = new Gee.ArrayList<Glyph> (); Glyph glyph = new Glyph ("null", '\0'); string[] items = data.split ("\nBF "); - string d; - int i; unichar c; Glyph destination; GlyphCollection gc; @@ -287,7 +304,13 @@ glyph = new Glyph ((!) c.to_string (), c); glyphs.add (glyph); } - + + if (p.has_prefix ("unassigned:")) { + p = p.replace ("unassigned: ", ""); + p = p.replace ("\n", ""); + glyph.set_unassigned (bool.parse (p)); // FIXME: move to gc + } + if (p.has_prefix ("path:")) { p = p.replace ("path: ", ""); p = p.replace ("\n", "");
--- a/libbirdfont/Font.vala +++ b/libbirdfont/Font.vala @@ -376,7 +376,8 @@ return; } - if (glyph_collection.get_unicode () != "") { + // FIXME: move unassinged + if (glyph_collection.get_unicode () != "" || glyph_collection.get_current ().is_unassigned ()) { glyph_name.insert (glyph_collection.get_name (), glyph_collection); }
--- a/libbirdfont/GlyphCollection.vala +++ b/libbirdfont/GlyphCollection.vala @@ -21,6 +21,7 @@ VersionList versions; unichar unicode_character; string name; + bool unassigned = false; public GlyphCollection (unichar unicode_character, string name) { this.unicode_character = unicode_character; @@ -28,6 +29,14 @@ versions = new VersionList (null, this); } + public void set_unassigned (bool a) { + unassigned = a; + } + + public bool is_unassigned () { + return unassigned; + } + public void add_glyph (Glyph g) { get_version_list ().add_glyph (g); }
--- a/libbirdfont/MenuTab.vala +++ b/libbirdfont/MenuTab.vala @@ -447,8 +447,52 @@ public static void show_spacing_tab () { SpacingClassTab t = MainWindow.get_spacing_class_tab (); MainWindow.get_tab_bar ().add_unique_tab (t); + } + + public static void add_ligature () { + TextListener listener; + string ligature_name = ""; + + if (suppress_event) { + warn_if_test ("Event suppressed"); + return; + } + + listener = new TextListener (t_("Name"), "", t_("Add ligature")); + + listener.signal_text_input.connect ((text) => { + ligature_name = text; + }); + + listener.signal_submit.connect (() => { + Font font = BirdFont.get_current_font (); + GlyphCollection? fg; + Glyph glyph; + GlyphCollection glyph_collection; + OverView o = MainWindow.get_overview (); + + fg = font.get_glyph_collection_by_name (ligature_name); + + if (fg == null) { + glyph_collection = new GlyphCollection ('\0', ligature_name); + + glyph = new Glyph (ligature_name, '\0'); + glyph.set_unassigned (true); + glyph_collection.insert_glyph (glyph, true); + + font.add_glyph_collection (glyph_collection); + } + + o.display_all_available_glyphs (); + o.scroll_to_glyph (ligature_name); + + MainWindow.native_window.hide_text_input (); + Toolbox.select_tool_by_name ("available_characters"); + }); + + MainWindow.native_window.set_text_listener (listener); } } }
--- a/libbirdfont/OpenFontFormat/Gsub.vala +++ b/libbirdfont/OpenFontFormat/Gsub.vala @@ -63,7 +63,7 @@ fd.add_ushort (1); // number of lookups fd.add_ushort (4); // offset to lookup 1 - // ligature substitution + // ligature substitution subtable fd.add_ushort (1); // lookup type, format identifier fd.add_ushort (20); // offset to coverage fd.add_ushort (1); // number of ligature set tables
--- a/libbirdfont/OverView.vala +++ b/libbirdfont/OverView.vala @@ -107,19 +107,24 @@ update_scrollbar (); } - public GlyphCollection add_empty_character_to_font (unichar character) { - return add_character_to_font (character, true); + public GlyphCollection add_empty_character_to_font (unichar character, bool unassigned, string name) { + return add_character_to_font (character, true, unassigned); } - public GlyphCollection add_character_to_font (unichar character, bool empty = false) { + public GlyphCollection add_character_to_font (unichar character, bool empty = false, + bool unassigned = false, string glyph_name = "") { StringBuilder name = new StringBuilder (); Font font = BirdFont.get_current_font (); GlyphCollection? fg; Glyph glyph; GlyphCollection glyph_collection; - name.append_unichar (character); - + if (glyph_name == "") { + name.append_unichar (character); + } else { + name.append (glyph_name); + } + if (all_available) { fg = font.get_glyph_collection_by_name (name.str); } else { @@ -132,12 +137,14 @@ glyph_collection = new GlyphCollection (character, name.str); if (!empty) { - glyph = new Glyph (name.str, character); + glyph = new Glyph (name.str, (!unassigned) ? character : '\0'); glyph_collection.insert_glyph (glyph, true); } font.add_glyph_collection (glyph_collection); } + + glyph_collection.set_unassigned (unassigned); return glyph_collection; } @@ -768,11 +775,11 @@ redo_items.clear (); } - bool select_visible_character (unichar c) { + bool select_visible_glyph (string name) { int i = 0; foreach (OverViewItem o in visible_items) { - if (o.character == c) { + if (o.get_name () == name) { selected = i; selected_item = get_selected_item (); return true; @@ -788,11 +795,27 @@ return false; } - + + bool select_visible_character (unichar c) { + StringBuilder s = new StringBuilder (); + s.append_unichar (c); + return select_visible_glyph (s.str); + } + public void scroll_to_char (unichar c) { + StringBuilder s = new StringBuilder (); + + if (is_modifier_key (c)) { + return; + } + + s.append_unichar (c); + scroll_to_glyph (s.str); + } + + public void scroll_to_glyph (string name) { GlyphRange gr = glyph_range; int i, r, index; - StringBuilder s = new StringBuilder (); string ch; Font font = BirdFont.get_current_font (); GlyphCollection? glyphs = null; @@ -804,16 +827,11 @@ warning ("No items."); return; } - - if (is_modifier_key (c)) { - return; - } - - s.append_unichar (c); - ch = s.str; + + ch = name; // selected char is visible - if (select_visible_character (c)) { + if (select_visible_glyph (ch)) { return; } @@ -842,6 +860,12 @@ } } } else { + + if (ch.char_count () > 1) { + warning ("Can't scroll to ligature in this view"); + return; + } + for (r = 0; r < gr.length (); r += items_per_row) { for (i = 0; i < items_per_row; i++) { if (gr.get_char (r + i) == ch) { @@ -858,7 +882,7 @@ if (index > -1) { first_visible = r; update_item_list (); - select_visible_character (c); + select_visible_glyph (ch); } } @@ -1125,24 +1149,27 @@ return (int) ((GlyphCollection) a).get_unicode_character () - (int) ((GlyphCollection) b).get_unicode_character (); }); - - // FIXME: copy and paste to unicode character + 1 - + index = (uint32) first_visible + selected; for (i = 0; i < copied_glyphs.size; i++) { if (all_available) { if (f.length () == 0) { - c = add_empty_character_to_font ( - glyps.get (i).get_unicode_character ()); + c = add_empty_character_to_font (glyps.get (i).get_unicode_character (), + glyps.get (i).is_unassigned (), glyps.get (i).get_name ()); } else if (index >= f.length ()) { c = add_empty_character_to_font ( - ((!)f.get_glyph_collection_indice (f.length () - 1)).get_unicode_character () + i); + ((!)f.get_glyph_collection_indice (f.length () - 1)) + .get_unicode_character () + i, + glyps.get (i).is_unassigned (), + glyps.get (i).get_name ()); } else { c = f.get_glyph_collection_indice ((uint32) index); } if (c == null) { - c = add_empty_character_to_font (copied_glyphs.get (i).get_unicode_character ()); + c = add_empty_character_to_font (copied_glyphs.get (i).get_unicode_character (), + glyps.get (i).is_unassigned (), + glyps.get (i).get_name ()); } return_if_fail (c != null); @@ -1159,7 +1186,9 @@ c = f.get_glyph_collection_by_name (character_string); if (c == null) { - gc = add_empty_character_to_font (character_string.get_char ()); + gc = add_empty_character_to_font (character_string.get_char (), + glyps.get (i).is_unassigned (), + glyps.get (i).get_name ()); } else { gc = (!) c; }
--- a/libbirdfont/OverViewItem.vala +++ b/libbirdfont/OverViewItem.vala @@ -18,7 +18,7 @@ namespace BirdFont { public class OverViewItem : GLib.Object { - public unichar character = 'A'; + public unichar character = '\0'; public GlyphCollection? glyphs; public double x; public double y; @@ -39,6 +39,19 @@ this.character = character; this.glyphs = glyphs; this.info = new CharacterInfo (character); + } + + public string get_name () { + StringBuilder s; + + if (glyphs != null) { + return ((!) glyphs).get_name (); + } + + s = new StringBuilder (); + s.append_unichar (character); + + return s.str; } public void set_selected (bool s) {
--- a/libbirdfont/PenTool.vala +++ b/libbirdfont/PenTool.vala @@ -530,9 +530,6 @@ Glyph glyph = MainWindow.get_current_glyph (); double coordinate_x, coordinate_y; double delta_coordinate_x, delta_coordinate_y; - int px = 0; - int py = 0; - EditPoint p; double angle = 0; control_point_event (x, y); @@ -656,16 +653,7 @@ } } } - - private static void tie_pixels (ref int x, ref int y) { - double coordinate_x, coordinate_y; - coordinate_x = Glyph.path_coordinate_x (x); - coordinate_y = Glyph.path_coordinate_y (y); - GridTool.tie_coordinate (ref coordinate_x, ref coordinate_y); - x = Glyph.reverse_path_coordinate_x (coordinate_x); - y = Glyph.reverse_path_coordinate_y (coordinate_y); - } - + public void press (int button, int x, int y, bool double_click) { Glyph? g = MainWindow.get_current_glyph (); Glyph glyph = (!) g; @@ -904,8 +892,7 @@ Path path; bool direction_changed = false; Path union, second_path; - EditPoint last_point, first_point; - EditPointHandle last_rh, fist_lh; + EditPoint first_point; int px, py; if (glyph.path_list.size == 0) {
--- a/libbirdfont/SvgParser.vala +++ b/libbirdfont/SvgParser.vala @@ -55,7 +55,6 @@ Glyph glyph; string[] lines = xml_data.split ("\n"); bool has_format = false; - StringBuilder sb = new StringBuilder (); SvgParser parser = new SvgParser (); XmlParser xmlparser; Tag root; @@ -363,7 +362,6 @@ private void parse_path (Tag tag, PathList pl) { Glyph glyph = MainWindow.get_current_glyph (); PathList path_list = new PathList (); - Tag t; Attribute attr; tag.reparse ();