The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

OtfFeatureTable.vala in libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/OtfFeatureTable.vala.
Parse more style attributes in SVG files
1 /* 2 Copyright (C) 2015 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using Cairo; 16 17 namespace BirdFont { 18 19 /** A table for managing feature tags in Open Type tables. */ 20 public class OtfFeatureTable : Table { 21 Gee.ArrayList<Row> rows = new Gee.ArrayList<Row> (); 22 23 static const int NONE = 0; 24 static const int OTF_FEATURE = 1; 25 static const int SOURCE_GLYPH = 2; // the glyph to replace 26 static const int REPLACEMENT_GLYPH = 3; 27 static const int ALTERNATE_ENTRY = 4; 28 29 GlyphCollection glyph_collection; 30 GlyphCollection? replacement_glyph = null; 31 string alternate_name = ""; 32 TextListener listener; 33 34 Gee.ArrayList<AlternateItem> undo_items; 35 // FIXME: implement redo 36 37 public OtfFeatureTable (GlyphCollection gc) { 38 glyph_collection = gc; 39 undo_items = new Gee.ArrayList<AlternateItem> (); 40 } 41 42 public override Gee.ArrayList<Row> get_rows () { 43 return rows; 44 } 45 46 public override void selected_row (Row row, int column, bool delete_button) { 47 int row_index = row.get_index (); 48 Object o; 49 String s; 50 AlternateItem a; 51 52 if (row_index == SOURCE_GLYPH) { 53 GlyphSelection gs = new GlyphSelection (); 54 55 gs.selected_glyph.connect ((gc) => { 56 glyph_collection = gc; 57 MainWindow.get_tab_bar ().select_tab_name (get_name ()); 58 }); 59 60 GlyphCanvas.set_display (gs); 61 } else if (row_index == REPLACEMENT_GLYPH) { 62 GlyphSelection gs = new GlyphSelection (); 63 64 gs.selected_glyph.connect ((gc) => { 65 replacement_glyph = gc; 66 MainWindow.get_tab_bar ().select_tab_name (get_name ()); 67 }); 68 69 GlyphCanvas.set_display (gs); 70 } else if (row_index == OTF_FEATURE) { 71 return_if_fail (row.has_row_data ()); 72 o = (!) row.get_row_data (); 73 return_if_fail (o is String); 74 s = (String) o; 75 add_new_alternate (s.data); 76 } else if (row_index == ALTERNATE_ENTRY) { 77 if (delete_button) { 78 return_if_fail (row.has_row_data ()); 79 o = (!) row.get_row_data (); 80 return_if_fail (o is AlternateItem); 81 a = (AlternateItem) o; 82 83 a.delete_item_from_list (); 84 Font f = BirdFont.get_current_font (); 85 f.alternates.remove_empty_sets (); 86 87 undo_items.add (a); 88 89 update_rows (); 90 GlyphCanvas.redraw (); 91 } 92 } 93 } 94 95 public override void update_rows () { 96 Row row; 97 Font font; 98 99 font = BirdFont.get_current_font (); 100 rows.clear (); 101 102 row = new Row.headline (t_("Glyph Substitutions")); 103 rows.add (row); 104 105 row = new Row.columns_1 (t_("Glyph") + ": " + glyph_collection.get_name (), SOURCE_GLYPH, false); 106 rows.add (row); 107 108 string replacement = t_("New glyph"); 109 110 if (replacement_glyph != null) { 111 GlyphCollection gc = (!) replacement_glyph; 112 replacement = gc.get_name (); 113 } 114 115 row = new Row.columns_1 (t_("Replacement") + ": " + replacement, REPLACEMENT_GLYPH, false); 116 rows.add (row); 117 118 // FIXME: reuse parts of this for fractions etc. 119 120 row = new Row.headline (t_("Tag")); 121 rows.add (row); 122 123 row = new Row.columns_1 (OtfLabel.get_string ("salt"), OTF_FEATURE, false); 124 row.set_row_data (new String ("salt")); 125 rows.add (row); 126 127 row = new Row.columns_1 (OtfLabel.get_string ("smcp"), OTF_FEATURE, false); 128 row.set_row_data (new String ("smcp")); 129 rows.add (row); 130 131 row = new Row.columns_1 (OtfLabel.get_string ("c2sc"), OTF_FEATURE, false); 132 row.set_row_data (new String ("c2sc")); 133 rows.add (row); 134 135 row = new Row.columns_1 (OtfLabel.get_string ("swsh"), OTF_FEATURE, false); 136 row.set_row_data (new String ("swsh")); 137 rows.add (row); 138 139 Gee.ArrayList<string> tags = font.alternates.get_all_tags (); 140 foreach (string tag in tags) { 141 row = new Row.headline (OtfLabel.get_string (tag)); 142 rows.add (row); 143 add_alternate_items (tag); 144 } 145 146 GlyphCanvas.redraw (); 147 } 148 149 void add_alternate_items (string tag) { 150 Font font = BirdFont.get_current_font (); 151 foreach (Alternate alt in font.alternates.get_alt (tag)) { 152 add_alternate_rows (alt); 153 } 154 } 155 156 void add_alternate_rows (Alternate alt) { 157 Row row; 158 159 foreach (string a in alt.alternates) { 160 row = new Row.columns_2 (alt.glyph_name, a, ALTERNATE_ENTRY, true); 161 row.set_row_data (new AlternateItem (alt, a)); 162 rows.add (row); 163 } 164 } 165 166 public override string get_label () { 167 return t_("Glyph Substitutions"); 168 } 169 170 public override string get_name () { 171 return "Glyph Substitutions"; 172 } 173 174 public override void draw (WidgetAllocation allocation, Context cr) { 175 base.draw (allocation, cr); 176 } 177 178 public void add_new_alternate (string tag) { 179 GlyphCollection gc = glyph_collection; 180 181 listener = new TextListener (t_("Glyph name"), "", t_("Add")); 182 183 listener.signal_text_input.connect ((text) => { 184 alternate_name = text; 185 }); 186 187 listener.signal_submit.connect (() => { 188 GlyphCollection alt; 189 Font font; 190 OverView overview = MainWindow.get_overview (); 191 192 font = BirdFont.get_current_font (); 193 194 if (alternate_name == "" || gc.is_unassigned ()) { 195 MainWindow.tabs.close_display (this); 196 return; 197 } 198 199 if (font.glyph_name.has_key (alternate_name)) { 200 MainWindow.show_message (t_("All glyphs must have unique names.")); 201 } else { 202 alt = new GlyphCollection.with_glyph ('\0', alternate_name); 203 alt.set_unassigned (true); 204 font.add_new_alternate (gc, alt, tag); 205 MainWindow.tabs.close_display (this); 206 MainWindow.get_overview ().update_item_list (); 207 overview.open_glyph_signal (alt); 208 } 209 }); 210 211 if (replacement_glyph != null) { 212 GlyphCollection replacement = (!) replacement_glyph; 213 Font f = BirdFont.get_current_font (); 214 f.add_alternate (gc.get_name (), replacement.get_name (), tag); 215 MainWindow.tabs.close_display (this); 216 } else { 217 TabContent.show_text_input (listener); 218 } 219 } 220 221 public override void undo () { 222 AlternateItem item; 223 Font font; 224 225 font = BirdFont.get_current_font (); 226 227 if (undo_items.size > 0) { 228 item = undo_items.get (undo_items.size - 1); 229 undo_items.remove_at (undo_items.size - 1); 230 231 font.add_alternate (item.alternate_list.glyph_name, 232 item.alternate, 233 item.alternate_list.tag); 234 235 update_rows (); 236 GlyphCanvas.redraw (); 237 } 238 } 239 } 240 241 } 242