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.
Reset replacement glyph in OTF feature tab
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 = null; 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 replacement_glyph = null; 58 MainWindow.get_tab_bar ().select_tab_name (get_name ()); 59 }); 60 61 GlyphCanvas.set_display (gs); 62 } else if (row_index == REPLACEMENT_GLYPH) { 63 GlyphSelection gs = new GlyphSelection (); 64 65 gs.selected_glyph.connect ((gc) => { 66 replacement_glyph = gc; 67 MainWindow.get_tab_bar ().select_tab_name (get_name ()); 68 }); 69 70 GlyphCanvas.set_display (gs); 71 } else if (row_index == OTF_FEATURE) { 72 return_if_fail (row.has_row_data ()); 73 o = (!) row.get_row_data (); 74 return_if_fail (o is String); 75 s = (String) o; 76 add_new_alternate (s.data); 77 } else if (row_index == ALTERNATE_ENTRY) { 78 if (delete_button) { 79 return_if_fail (row.has_row_data ()); 80 o = (!) row.get_row_data (); 81 return_if_fail (o is AlternateItem); 82 a = (AlternateItem) o; 83 84 a.delete_item_from_list (); 85 Font f = BirdFont.get_current_font (); 86 f.alternates.remove_empty_sets (); 87 88 undo_items.add (a); 89 90 update_rows (); 91 GlyphCanvas.redraw (); 92 } 93 } 94 } 95 96 public override void update_rows () { 97 Row row; 98 Font font; 99 100 font = BirdFont.get_current_font (); 101 rows.clear (); 102 103 row = new Row.headline (t_("Glyph Substitutions")); 104 rows.add (row); 105 106 string glyph = ""; 107 108 if (glyph_collection == null) { 109 glyph = t_("New glyph"); 110 } else { 111 glyph = ((!) glyph_collection).get_name (); 112 } 113 114 row = new Row.columns_1 (t_("Glyph") + ": " + glyph, SOURCE_GLYPH, false); 115 rows.add (row); 116 117 string replacement = t_("New glyph"); 118 119 if (replacement_glyph != null) { 120 GlyphCollection gc = (!) replacement_glyph; 121 replacement = gc.get_name (); 122 } 123 124 row = new Row.columns_1 (t_("Replacement") + ": " + replacement, REPLACEMENT_GLYPH, false); 125 rows.add (row); 126 127 // FIXME: reuse parts of this for fractions etc. 128 129 row = new Row.headline (t_("Tag")); 130 rows.add (row); 131 132 row = new Row.columns_1 (OtfLabel.get_string ("salt"), OTF_FEATURE, false); 133 row.set_row_data (new String ("salt")); 134 rows.add (row); 135 136 row = new Row.columns_1 (OtfLabel.get_string ("smcp"), OTF_FEATURE, false); 137 row.set_row_data (new String ("smcp")); 138 rows.add (row); 139 140 row = new Row.columns_1 (OtfLabel.get_string ("c2sc"), OTF_FEATURE, false); 141 row.set_row_data (new String ("c2sc")); 142 rows.add (row); 143 144 row = new Row.columns_1 (OtfLabel.get_string ("swsh"), OTF_FEATURE, false); 145 row.set_row_data (new String ("swsh")); 146 rows.add (row); 147 148 Gee.ArrayList<string> tags = font.alternates.get_all_tags (); 149 foreach (string tag in tags) { 150 row = new Row.headline (OtfLabel.get_string (tag)); 151 rows.add (row); 152 add_alternate_items (tag); 153 } 154 155 GlyphCanvas.redraw (); 156 } 157 158 void add_alternate_items (string tag) { 159 Font font = BirdFont.get_current_font (); 160 foreach (Alternate alt in font.alternates.get_alt (tag)) { 161 add_alternate_rows (alt); 162 } 163 } 164 165 void add_alternate_rows (Alternate alt) { 166 Row row; 167 168 foreach (string a in alt.alternates) { 169 row = new Row.columns_2 (alt.glyph_name, a, ALTERNATE_ENTRY, true); 170 row.set_row_data (new AlternateItem (alt, a)); 171 rows.add (row); 172 } 173 } 174 175 public override string get_label () { 176 return t_("Glyph Substitutions"); 177 } 178 179 public override string get_name () { 180 return "Glyph Substitutions"; 181 } 182 183 public override void draw (WidgetAllocation allocation, Context cr) { 184 base.draw (allocation, cr); 185 } 186 187 public void add_new_alternate (string tag) { 188 GlyphCollection gc; 189 190 if (glyph_collection == null) { 191 MainWindow.show_message (t_("Select a glyph to create an alternate for.")); 192 return; 193 } 194 195 gc = (!) glyph_collection; 196 197 listener = new TextListener (t_("Glyph name"), "", t_("Add")); 198 199 listener.signal_text_input.connect ((text) => { 200 alternate_name = text; 201 }); 202 203 listener.signal_submit.connect (() => { 204 GlyphCollection alt; 205 Font font; 206 OverView overview = MainWindow.get_overview (); 207 208 font = BirdFont.get_current_font (); 209 210 if (font.glyph_name.has_key (alternate_name)) { 211 MainWindow.show_message (t_("All glyphs must have unique names.")); 212 } else { 213 alt = new GlyphCollection.with_glyph ('\0', alternate_name); 214 alt.set_unassigned (true); 215 font.add_new_alternate (gc, alt, tag); 216 update_rows (); 217 GlyphCanvas.redraw (); 218 MainWindow.get_overview ().update_item_list (); 219 overview.open_glyph_signal (alt); 220 } 221 }); 222 223 if (replacement_glyph != null) { 224 GlyphCollection replacement = (!) replacement_glyph; 225 Font f = BirdFont.get_current_font (); 226 f.add_alternate (gc.get_name (), replacement.get_name (), tag); 227 update_rows (); 228 GlyphCanvas.redraw (); 229 } else { 230 TabContent.show_text_input (listener); 231 } 232 } 233 234 public override void undo () { 235 AlternateItem item; 236 Font font; 237 238 font = BirdFont.get_current_font (); 239 240 if (undo_items.size > 0) { 241 item = undo_items.get (undo_items.size - 1); 242 undo_items.remove_at (undo_items.size - 1); 243 244 font.add_alternate (item.alternate_list.glyph_name, 245 item.alternate, 246 item.alternate_list.tag); 247 248 update_rows (); 249 GlyphCanvas.redraw (); 250 } 251 } 252 } 253 254 } 255