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.
Apply OTF substitution in kerning 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 28 GlyphCollection glyph_collection; 29 GlyphCollection? replacement_glyph = null; 30 string alternate_name = ""; 31 TextListener listener; 32 33 public OtfFeatureTable (GlyphCollection gc) { 34 glyph_collection = gc; 35 } 36 37 public override Gee.ArrayList<Row> get_rows () { 38 return rows; 39 } 40 41 public override void selected_row (Row row, int column, bool delete_button) { 42 int row_index = row.get_index (); 43 44 if (row_index == SOURCE_GLYPH) { 45 GlyphSelection gs = new GlyphSelection (); 46 47 gs.selected_glyph.connect ((gc) => { 48 glyph_collection = gc; 49 MainWindow.get_tab_bar ().select_tab_name (get_name ()); 50 }); 51 52 GlyphCanvas.set_display (gs); 53 } else if (row_index == REPLACEMENT_GLYPH) { 54 GlyphSelection gs = new GlyphSelection (); 55 56 gs.selected_glyph.connect ((gc) => { 57 replacement_glyph = gc; 58 MainWindow.get_tab_bar ().select_tab_name (get_name ()); 59 }); 60 61 GlyphCanvas.set_display (gs); 62 } else if (row_index == OTF_FEATURE) { 63 String s = (String) row.get_row_data (); 64 add_new_alternate (s.data); 65 } 66 } 67 68 public override void update_rows () { 69 Row row; 70 71 rows.clear (); 72 73 row = new Row.headline (t_("Glyph Substitutions")); 74 rows.add (row); 75 76 row = new Row.columns_1 (t_("Glyph") + ": " + glyph_collection.get_name (), SOURCE_GLYPH, false); 77 rows.add (row); 78 79 string replacement = t_("New glyph"); 80 81 if (replacement_glyph != null) { 82 GlyphCollection gc = (!) replacement_glyph; 83 replacement = gc.get_name (); 84 } 85 86 row = new Row.columns_1 (t_("Replacement") + ": " + replacement, REPLACEMENT_GLYPH, false); 87 rows.add (row); 88 89 // FIXME: reuse parts of this for fractions etc. 90 91 row = new Row.headline (t_("Tag")); 92 rows.add (row); 93 94 row = new Row.columns_1 (OtfLabel.get_string ("salt"), OTF_FEATURE, false); 95 row.set_row_data (new String ("salt")); 96 rows.add (row); 97 98 row = new Row.columns_1 (OtfLabel.get_string ("smcp"), OTF_FEATURE, false); 99 row.set_row_data (new String ("smcp")); 100 rows.add (row); 101 102 row = new Row.columns_1 (OtfLabel.get_string ("c2sc"), OTF_FEATURE, false); 103 row.set_row_data (new String ("c2sc")); 104 rows.add (row); 105 106 row = new Row.columns_1 (OtfLabel.get_string ("swsh"), OTF_FEATURE, false); 107 row.set_row_data (new String ("swsh")); 108 rows.add (row); 109 110 GlyphCanvas.redraw (); 111 } 112 113 public override string get_label () { 114 return t_("Glyph Substitutions"); 115 } 116 117 public override string get_name () { 118 return "Glyph Substitutions"; 119 } 120 121 public override void draw (WidgetAllocation allocation, Context cr) { 122 base.draw (allocation, cr); 123 } 124 125 public void add_new_alternate (string tag) { 126 GlyphCollection gc = glyph_collection; 127 128 listener = new TextListener (t_("Glyph name"), "", t_("Add")); 129 130 listener.signal_text_input.connect ((text) => { 131 alternate_name = text; 132 }); 133 134 listener.signal_submit.connect (() => { 135 GlyphCollection alt; 136 Font font; 137 OverView overview = MainWindow.get_overview (); 138 139 font = BirdFont.get_current_font (); 140 141 if (alternate_name == "" || gc.is_unassigned ()) { 142 MainWindow.tabs.close_display (this); 143 return; 144 } 145 146 if (font.glyph_name.has_key (alternate_name)) { 147 MainWindow.show_message (t_("All glyphs must have unique names.")); 148 } else { 149 alt = new GlyphCollection.with_glyph ('\0', alternate_name); 150 alt.set_unassigned (true); 151 font.add_new_alternate (gc, alt, tag); 152 MainWindow.tabs.close_display (this); 153 MainWindow.get_overview ().update_item_list (); 154 overview.open_glyph_signal (alt); 155 } 156 }); 157 158 if (replacement_glyph != null) { 159 GlyphCollection replacement = (!) replacement_glyph; 160 Font f = BirdFont.get_current_font (); 161 f.add_alternate (gc.get_name (), replacement.get_name (), tag); 162 MainWindow.tabs.close_display (this); 163 } else { 164 TabContent.show_text_input (listener); 165 } 166 167 } 168 } 169 170 } 171