The Birdfont Source Code


All Repositories / birdfont.git / commitdiff – RSS feed

Add contextual ligatures to the GUI and fix directory privileges

These changes was commited to the Birdfont repository Mon, 13 Oct 2014 17:25:46 +0000.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
[Mon, 13 Oct 2014 17:25:46 +0000]

Updated Files

libbirdfont/BackgroundImage.vala
libbirdfont/BirdFont.vala
libbirdfont/BirdFontFile.vala
libbirdfont/BirdFontPart.vala
libbirdfont/CutBackgroundTool.vala
libbirdfont/LigatureList.vala
libbirdfont/Ligatures.vala
libbirdfont/OpenFontFormat/ContextualLigature.vala
libbirdfont/OpenFontFormat/GsubTable.vala
libbirdfont/OpenFontFormat/Ligature.vala
libbirdfont/Row.vala
--- a/libbirdfont/BackgroundImage.vala +++ b/libbirdfont/BackgroundImage.vala @@ -225,17 +225,17 @@ dir = BirdFont.get_settings_directory (); if (!dir.query_exists ()) { - DirUtils.create ((!) dir.get_path (), 0xFFFFFF); + DirUtils.create ((!) dir.get_path (), 0755); } dir = font.get_backgrounds_folder (); if (!dir.query_exists ()) { - DirUtils.create ((!) dir.get_path (), 0xFFFFFF); + DirUtils.create ((!) dir.get_path (), 0755); } dir = font.get_backgrounds_folder ().get_child ("parts"); if (!dir.query_exists ()) { - DirUtils.create ((!) dir.get_path (), 0xFFFFFF); + DirUtils.create ((!) dir.get_path (), 0755); } }
--- a/libbirdfont/BirdFont.vala +++ b/libbirdfont/BirdFont.vala @@ -535,7 +535,7 @@ File backup = settings.get_child ("preview"); if (!backup.query_exists ()) { - DirUtils.create ((!) backup.get_path (), 0xFFFFFF); + DirUtils.create ((!) backup.get_path (), 0755); } return backup; @@ -545,7 +545,7 @@ File thumbnails = get_settings_directory ().get_child ("thumbnails"); if (!thumbnails.query_exists ()) { - DirUtils.create ((!) thumbnails.get_path (), 0xFFFFFF); + DirUtils.create ((!) thumbnails.get_path (), 0755); } return thumbnails; @@ -562,12 +562,12 @@ if (!home.query_exists ()) { printd ("Create settings directory."); - DirUtils.create ((!) home.get_path (), 0xFFFFFF); + DirUtils.create ((!) home.get_path (),0755); } #else home_path = (settings_directory != null) - ? (!) settings_directory : Environment.get_home_dir (); - + ? (!) settings_directory : Environment.get_user_config_dir (); + if (is_null (home_path)) { warning ("No home directory set."); home_path = "."; @@ -575,10 +575,10 @@ home = File.new_for_path (home_path); #endif - settings = home.get_child (".birdfont"); + settings = home.get_child ("birdfont"); if (!settings.query_exists ()) { - DirUtils.create ((!) settings.get_path (), 0xFFFFFF); + DirUtils.create ((!) settings.get_path (), 0755); } return settings; @@ -589,7 +589,7 @@ File backup = settings.get_child ("backup"); if (!backup.query_exists ()) { - DirUtils.create ((!) backup.get_path (), 0xFFFFFF); + DirUtils.create ((!) backup.get_path (), 0755); } return backup;
--- a/libbirdfont/BirdFontFile.vala +++ b/libbirdfont/BirdFontFile.vala @@ -793,13 +793,13 @@ } if (!font.get_backgrounds_folder ().query_exists ()) { - DirUtils.create ((!) font.get_backgrounds_folder ().get_path (), 0xFFFFFF); + DirUtils.create ((!) font.get_backgrounds_folder ().get_path (), 0755); } img_dir = font.get_backgrounds_folder ().get_child ("parts"); if (!img_dir.query_exists ()) { - DirUtils.create ((!) img_dir.get_path (), 0xFFFFFF); + DirUtils.create ((!) img_dir.get_path (), 0755); } img_file = img_dir.get_child (@"$(file).png"); @@ -1359,16 +1359,16 @@ public void write_ligatures (DataOutputStream os) { Ligatures ligatures = font.get_ligatures (); - - try { - ligatures.get_ligatures ((subst, liga) => { + + ligatures.get_ligatures ((subst, liga) => { + try { string lig = serialize_attribute (liga); string sequence = serialize_attribute (subst); os.put_string (@"<ligature sequence=\"$(sequence)\" replacement=\"$(lig)\"/>\n"); - }); - } catch (GLib.IOError e) { - warning (e.message); - } + } catch (GLib.IOError e) { + warning (e.message); + } + }); } public void parse_ligature (Tag t) {
--- a/libbirdfont/BirdFontPart.vala +++ b/libbirdfont/BirdFontPart.vala @@ -386,11 +386,11 @@ } if (!dir.query_exists ()) { - DirUtils.create ((!) dir.get_path (), 0xFFFFFF); + DirUtils.create ((!) dir.get_path (), 0755); } root_directory = (!) bfp_dir.get_path (); - DirUtils.create (root_directory, 0xFFFFFF); + DirUtils.create (root_directory, 0755); } private void find_all_parts (string bfp_file) throws GLib.Error { @@ -473,7 +473,7 @@ dir = dir.get_child (subdir); if (!dir.query_exists ()) { - DirUtils.create ((!) dir.get_path (), 0xFFFFFF); + DirUtils.create ((!) dir.get_path (), 0755); } else { info = dir.query_info (FILE_ATTRIBUTES, FileQueryInfoFlags.NONE); if (info.get_file_type () != FileType.DIRECTORY) {
--- a/libbirdfont/CutBackgroundTool.vala +++ b/libbirdfont/CutBackgroundTool.vala @@ -220,7 +220,7 @@ img_dir = f.get_backgrounds_folder ().get_child ("parts"); if (!img_dir.query_exists ()) { - if (DirUtils.create_with_parents ((!) img_dir.get_path (), 0xFFFFFF) != 0) { + if (DirUtils.create_with_parents ((!) img_dir.get_path (), 755) != 0) { warning (@"Can not create directory $((!) img_dir.get_path ())"); } }
--- a/libbirdfont/LigatureList.vala +++ b/libbirdfont/LigatureList.vala @@ -29,6 +29,12 @@ return rows; } + void add_contextual_ligature (string backtrack, string input, string lookahead) { + Font font = BirdFont.get_current_font (); + Ligatures ligatures = font.get_ligatures (); + ligatures.add_contextual_ligature (backtrack, input, lookahead); + } + void add_ligature (string subst, string liga) { Font font = BirdFont.get_current_font (); Ligatures ligatures = font.get_ligatures (); @@ -38,27 +44,59 @@ public override void selected_row (Row row, int column, bool delete_button) { Font font = BirdFont.get_current_font (); Ligatures ligatures = font.get_ligatures (); + int i; + ContextualLigature cl; - if (row.get_index () == NEW_LIGATURE) { + if (row.get_index () == NEW_LIGATURE && column == 0) { add_ligature (t_("character sequence"), t_("ligature")); MainWindow.native_window.hide_text_input (); - } else if (ligatures.count () != 0) { + } else if (row.get_index () == NEW_LIGATURE && column == 1) { + add_contextual_ligature (t_("beginning"), t_("middle"), t_("end")); + MainWindow.native_window.hide_text_input (); + } else if (row.has_row_data ()) { + i = row.get_index (); + cl = (ContextualLigature) ((!) row.get_row_data ()); + if (delete_button) { - return_if_fail (0 <= row.get_index () < ligatures.count ()); - ligatures.remove_at (row.get_index ()); - MainWindow.native_window.hide_text_input (); + cl.remove_ligature_at (i); } else if (column == 0) { - if (!(0 <= row.get_index () < ligatures.count ())) { - warning (@"Index: $(row.get_index ()) ligatures.count (): $(ligatures.count ())"); - return; - } - ligatures.set_ligature (row.get_index ()); + cl.set_ligature (i); } else if (column == 2) { - return_if_fail (0 <= row.get_index () < ligatures.count ()); - ligatures.set_substitution (row.get_index ()); + cl.set_substitution (i); + } + } else if (row.get_index () < ligatures.count ()) { + if (ligatures.count () != 0) { + if (delete_button) { + return_if_fail (0 <= row.get_index () < ligatures.count ()); + ligatures.remove_at (row.get_index ()); + MainWindow.native_window.hide_text_input (); + } else if (column == 0) { + return_if_fail (0 <= row.get_index () < ligatures.count ()); + ligatures.set_ligature (row.get_index ()); + } else if (column == 2) { + return_if_fail (0 <= row.get_index () < ligatures.count ()); + ligatures.set_substitution (row.get_index ()); + } + } + } else { + i = row.get_index () - ligatures.count (); + if (i < ligatures.count_contextual_ligatures ()) { + return_if_fail (0 <= i < ligatures.count_contextual_ligatures ()); + if (delete_button) { + ligatures.remove_contextual_ligatures_at (i); + MainWindow.native_window.hide_text_input (); + } else if (column == 0) { + ligatures.set_beginning (i); + } else if (column == 1) { + ligatures.set_middle (i); + } else if (column == 2) { + ligatures.set_end (i); + } else if (column == 3) { + ligatures.add_substitution_at (i); + } } } - + update_rows (); update_scrollbar (); font.touch (); @@ -71,16 +109,34 @@ Row row; rows.clear (); - row = new Row (t_("New Ligature"), NEW_LIGATURE, false); + row = new Row.columns_2 (t_("New Ligature"), t_("New Contextual Substitution"), NEW_LIGATURE, false); rows.add (row); i = 0; ligatures.get_ligatures ((subst, liga) => { - row = new Row.columns_3 (@"$liga", "", @"$subst", i); + row = new Row.columns_3 (liga, "", subst, i); rows.add (row); i++; }); - + + ligatures.get_contextual_ligatures ((liga) => { + int j; + + row = new Row.columns_4 (liga.backtrack, liga.input, liga.lookahead, + t_("Add Ligature"), i); + rows.add (row); + + j = 0; + foreach (Ligature l in liga.ligatures) { + row = new Row.columns_3 (l.ligature, "", l.substitution, j); + row.set_row_data (liga); + rows.add (row); + j++; + } + + i++; + }); + GlyphCanvas.redraw (); }
--- a/libbirdfont/Ligatures.vala +++ b/libbirdfont/Ligatures.vala @@ -20,9 +20,12 @@ public class Ligatures : GLib.Object { Gee.ArrayList<Ligature> ligatures = new Gee.ArrayList<Ligature> (); + Gee.ArrayList<ContextualLigature> contextual_ligatures = new Gee.ArrayList<ContextualLigature> (); public delegate void LigatureIterator (string substitution, string ligature); public delegate void SingleLigatureIterator (GlyphSequence substitution, GlyphCollection ligature); + + public delegate void ContextualLigatureIterator (ContextualLigature lig); public Ligatures () { } @@ -30,6 +33,12 @@ public void get_ligatures (LigatureIterator iter) { foreach (Ligature l in ligatures) { iter (l.substitution, l.ligature); + } + } + + public void get_contextual_ligatures (ContextualLigatureIterator iter) { + foreach (ContextualLigature l in contextual_ligatures) { + iter (l); } } @@ -66,24 +75,39 @@ public int count () { return ligatures.size; + } + + public int count_contextual_ligatures () { + return contextual_ligatures.size; } public void remove_at (int i) { return_if_fail (0 <= i < ligatures.size); ligatures.remove_at (i); + } + + public void remove_contextual_ligatures_at (int i) { + return_if_fail (0 <= i < contextual_ligatures.size); + contextual_ligatures.remove_at (i); } - public void set_ligature (int index) { - Ligature lig; + /** Add ligaure for a chained substitution. */ + public void add_substitution_at (int index) { + return_if_fail (0 <= index < contextual_ligatures.size); + contextual_ligatures.get (index).add_ligature (); + } + + public void set_beginning (int index) { + ContextualLigature lig; TextListener listener; - return_if_fail (0 <= index < ligatures.size); - - lig = ligatures.get (index); - listener = new TextListener (t_("Ligature"), "", t_("Set")); + return_if_fail (0 <= index < contextual_ligatures.size); + + lig = contextual_ligatures.get (index); + listener = new TextListener (t_("Beginning"), lig.backtrack, t_("Set")); listener.signal_text_input.connect ((text) => { - lig.ligature = text; + lig.backtrack = text; }); listener.signal_submit.connect (() => { @@ -91,21 +115,20 @@ MainWindow.get_ligature_display ().update_rows (); }); - MainWindow.native_window.set_text_listener (listener); + MainWindow.native_window.set_text_listener (listener); } - public void set_substitution (int index) { - Ligature lig; + public void set_middle (int index) { + ContextualLigature lig; TextListener listener; - return_if_fail (0 <= index < ligatures.size); - - lig = ligatures.get (index); - listener = new TextListener (t_("Text"), "", t_("Set")); + return_if_fail (0 <= index < contextual_ligatures.size); + + lig = contextual_ligatures.get (index); + listener = new TextListener (t_("Middle"), lig.input, t_("Set")); listener.signal_text_input.connect ((text) => { - lig.substitution = text; - sort_ligatures (); + lig.input = text; }); listener.signal_submit.connect (() => { @@ -113,19 +136,64 @@ MainWindow.get_ligature_display ().update_rows (); }); - MainWindow.native_window.set_text_listener (listener); - } + MainWindow.native_window.set_text_listener (listener); + } + public void set_end (int index) { + ContextualLigature lig; + TextListener listener; + + return_if_fail (0 <= index < contextual_ligatures.size); + + lig = contextual_ligatures.get (index); + listener = new TextListener (t_("End"), lig.lookahead, t_("Set")); + + listener.signal_text_input.connect ((text) => { + lig.lookahead = text; + }); + + listener.signal_submit.connect (() => { + MainWindow.native_window.hide_text_input (); + MainWindow.get_ligature_display ().update_rows (); + }); + + MainWindow.native_window.set_text_listener (listener); + } + + public void set_ligature (int index) { + Ligature lig; + TextListener listener; + + return_if_fail (0 <= index < ligatures.size); + + lig = ligatures.get (index); + lig.set_ligature (); + } + + public void set_substitution (int index) { + Ligature lig; + TextListener listener; + + return_if_fail (0 <= index < ligatures.size); + + lig = ligatures.get (index); + lig.set_substitution (); + } + public void add_ligature (string subst, string liga) { ligatures.insert (0, new Ligature (liga, subst)); + sort_ligatures (); + } + + public void add_contextual_ligature (string backtrack, string input, string lookahead) { + ContextualLigature l = new ContextualLigature (backtrack, input, lookahead); + contextual_ligatures.insert (0, l); sort_ligatures (); } - void sort_ligatures () { - print (@"\n"); + public void sort_ligatures () { ligatures.sort ((a, b) => { Ligature first, next; - bool r; int chars_first, chars_next; first = (Ligature) a; @@ -135,9 +203,31 @@ chars_next = next.substitution.split (" ").length; return chars_next - chars_first; - }); + }); + + contextual_ligatures.sort ((a, b) => { + ContextualLigature first, next; + int chars_first, chars_next; + + first = (ContextualLigature) a; + next = (ContextualLigature) b; + + chars_first = first.backtrack.split (" ").length; + chars_first += first.input.split (" ").length; + chars_first += first.lookahead.split (" ").length; + + chars_next = next.backtrack.split (" ").length; + chars_next += next.input.split (" ").length; + chars_next += next.lookahead.split (" ").length; + + return chars_next - chars_first; + }); + + foreach (ContextualLigature c in contextual_ligatures) { + c.sort (); + } } } }
--- /dev/null +++ b/libbirdfont/OpenFontFormat/ContextualLigature.vala @@ -1,1 +1,70 @@ + /* + Copyright (C) 2014 Johan Mattsson + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + */ + + namespace BirdFont { + + public class ContextualLigature : GLib.Object { + + public string backtrack = ""; + public string input = ""; + public string lookahead = ""; + + public Gee.ArrayList<Ligature> ligatures; + + public ContextualLigature (string backtrack, string input, string lookahead) { + this.backtrack = backtrack; + this.input = input; + this.lookahead = lookahead; + + ligatures = new Gee.ArrayList<Ligature> (); + } + + public void remove_ligature_at (int i) { + return_if_fail (0 <= i < ligatures.size); + ligatures.remove_at (i); + } + + public void add_ligature () { + Ligature l = new Ligature (t_("ligature"), t_("glyph sequence")); + ligatures.add (l); + } + + public void set_ligature (int i) { + return_if_fail (0 <= i < ligatures.size); + ligatures.get (i).set_ligature (); + } + + public void set_substitution (int i) { + return_if_fail (0 <= i < ligatures.size); + ligatures.get (i).set_substitution (this); + } + + public void sort () { + ligatures.sort ((a, b) => { + Ligature first, next; + int chars_first, chars_next; + + first = (Ligature) a; + next = (Ligature) b; + + chars_first = first.substitution.split (" ").length; + chars_next = next.substitution.split (" ").length; + + return chars_next - chars_first; + }); + } + } + + }
--- a/libbirdfont/OpenFontFormat/GsubTable.vala +++ b/libbirdfont/OpenFontFormat/GsubTable.vala @@ -24,7 +24,7 @@ id = "GSUB"; } - public override void parse (FontData dis) throws Error { + public override void parse (FontData dis) throws GLib.Error { } public void process () throws GLib.Error { @@ -110,7 +110,7 @@ this.font_data = fd; } - FontData get_ligature_subtable (LigatureSetList liga_list) { + FontData get_ligature_subtable (LigatureSetList liga_list) throws GLib.Error { FontData set_data; Gee.ArrayList<LigatureSet> liga_sets; uint16 ligature_pos;
--- a/libbirdfont/OpenFontFormat/Ligature.vala +++ b/libbirdfont/OpenFontFormat/Ligature.vala @@ -17,7 +17,7 @@ public class Ligature : GLib.Object { public string ligature = ""; public string substitution = ""; - + public Ligature (string ligature, string substitution) { this.ligature = ligature; this.substitution = substitution; @@ -25,8 +25,50 @@ public unichar get_first_char () { return substitution.get (0); + } + + public void set_ligature () { + TextListener listener; + + listener = new TextListener (t_("Ligature"), ligature, t_("Set")); + + listener.signal_text_input.connect ((text) => { + ligature = text; + }); + + listener.signal_submit.connect (() => { + MainWindow.native_window.hide_text_input (); + MainWindow.get_ligature_display ().update_rows (); + }); + + MainWindow.native_window.set_text_listener (listener); + } + + public void set_substitution (ContextualLigature? clig = null) { + TextListener listener; + ContextualLigature? cl = clig; + + listener = new TextListener (t_("Text"), substitution, t_("Set")); + + listener.signal_text_input.connect ((text) => { + Font f = BirdFont.get_current_font (); + Ligatures l = f.get_ligatures (); + substitution = text; + l.sort_ligatures (); + + if (cl != null) { + ((!) cl).sort (); + } + }); + + listener.signal_submit.connect (() => { + MainWindow.native_window.hide_text_input (); + MainWindow.get_ligature_display ().update_rows (); + }); + + MainWindow.native_window.set_text_listener (listener); } } }
--- a/libbirdfont/Row.vala +++ b/libbirdfont/Row.vala @@ -20,8 +20,8 @@ int index = 0; bool delete_button = true; - Gee.ArrayList<string> columns_labels = new Gee.ArrayList<string> (); + GLib.Object? row_data = null; public int columns { get { @@ -32,14 +32,61 @@ public Row (string label, int index, bool delete_button = true) { this.index = index; columns_labels.add (label); + this.delete_button = delete_button; + } + + public Row.columns_2 (string label0, string label1, int index, + bool delete_button = true) { + + columns_labels.add (label0); + columns_labels.add (label1); + this.index = index; + this.delete_button = delete_button; + } + + public Row.columns_3 (string label0, string label1, string label2, + int index, bool delete_button = true) { + + columns_labels.add (label0); + columns_labels.add (label1); + columns_labels.add (label2); + this.index = index; + this.delete_button = delete_button; + } + + public Row.columns_4 (string label0, string label1, string label2, + string label3, int index, bool delete_button = true) { + + columns_labels.add (label0); + columns_labels.add (label1); + columns_labels.add (label2); + columns_labels.add (label3); + this.index = index; this.delete_button = delete_button; } - public Row.columns_3 (string label0, string label1, string label2, int index) { + public Row.columns_5 (string label0, string label1, string label2, + string label3, string label4, int index, bool delete_button = true) { + columns_labels.add (label0); columns_labels.add (label1); columns_labels.add (label2); + columns_labels.add (label3); + columns_labels.add (label4); this.index = index; + this.delete_button = delete_button; + } + + public bool has_row_data () { + return row_data != null; + } + + public GLib.Object? get_row_data () { + return row_data; + } + + public void set_row_data (GLib.Object o) { + row_data = o; } public bool has_delete_button () {