The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

KerningTools.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/KerningTools.vala.
Apply OTF substitution in kerning tab
1 /* 2 Copyright (C) 2013 2014 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 using Math; 17 18 namespace BirdFont { 19 20 public class KerningTools : ToolCollection { 21 public static Gee.ArrayList<Expander> expanders; 22 public static int next_class = 0; 23 public static Expander classes; 24 25 public static double font_size = 1; 26 public static ZoomBar zoom_bar; 27 28 public static Tool previous_kerning_string; 29 public static Tool next_kerning_string; 30 31 public KerningTools () { 32 init (); 33 } 34 35 public static void init () { 36 Expander kerning_tools = new Expander (t_("Kerning Tools")); 37 classes = new Expander (); 38 expanders = new Gee.ArrayList<Expander> (); 39 40 Expander font_name = new Expander (); 41 font_name.add_tool (new FontName ()); 42 43 Expander zoom_expander = new Expander (t_("Font Size")); 44 45 zoom_bar = new ZoomBar (); 46 zoom_bar.new_zoom.connect ((z) => { 47 Font f; 48 49 font_size = 3 * z; 50 51 if (font_size < 0.1) { 52 font_size = 0.1; 53 } 54 55 f = BirdFont.get_current_font (); 56 f.settings.set_setting ("kerning_zoom", @"$z"); 57 58 GlyphCanvas.redraw (); 59 }); 60 zoom_expander.add_tool (zoom_bar); 61 62 Tool new_kerning_class = new Tool ("kerning_class", t_("Create new kerning class.")); 63 new_kerning_class.select_action.connect ((self) => { 64 Font font = BirdFont.get_current_font (); 65 string label = t_("Kerning class"); 66 KerningRange kr = new KerningRange (font, @"$label $(++next_class)"); 67 classes.add_tool (kr); 68 self.set_selected (false); 69 classes.redraw (); 70 }); 71 kerning_tools.add_tool (new_kerning_class); 72 73 Tool text_kerning = new Tool ("kerning_text_input", t_("Use text input to enter kerning values.")); 74 text_kerning.select_action.connect ((self) => { 75 KerningDisplay d = MainWindow.get_kerning_display (); 76 d.set_kerning_by_text (); 77 self.set_selected (false); 78 }); 79 kerning_tools.add_tool (text_kerning); 80 81 Tool insert_last = new Tool ("insert_glyph_from_overview", t_("Insert glyph from overview")); 82 insert_last.select_action.connect ((self) => { 83 KerningDisplay d = MainWindow.get_kerning_display (); 84 GlyphSelection gs = new GlyphSelection (); 85 86 gs.selected_glyph.connect ((gc) => { 87 d.inser_glyph (gc.get_current ()); 88 MainWindow.get_tab_bar ().select_tab_name ("Kerning"); 89 }); 90 91 GlyphCanvas.set_display (gs); 92 self.set_selected (false); 93 }); 94 kerning_tools.add_tool (insert_last); 95 96 Tool insert_unicode = new Tool ("insert_unichar", t_("Insert character by unicode value")); 97 insert_unicode.select_action.connect ((self) => { 98 KerningDisplay d = MainWindow.get_kerning_display (); 99 d.insert_unichar (); 100 self.set_selected (false); 101 }); 102 kerning_tools.add_tool (insert_unicode); 103 104 string empty_kerning_text = t_("Open a text file with kerning strings first."); 105 106 previous_kerning_string = new Tool ("previous_kerning_string", t_("Previous kerning string")); 107 previous_kerning_string.select_action.connect ((self) => { 108 FontDisplay fd = MainWindow.get_current_display (); 109 KerningDisplay d = (KerningDisplay) fd; 110 Font f = BirdFont.get_current_font (); 111 string w = f.kerning_strings.previous (); 112 113 if (f.kerning_strings.is_empty ()) { 114 MainWindow.show_message (empty_kerning_text); 115 } else if (w == "") { 116 MainWindow.show_message (t_("You have reached the beginning of the list.")); 117 } else { 118 d.new_line (); 119 d.add_text (w); 120 } 121 self.set_selected (false); 122 }); 123 kerning_tools.add_tool (previous_kerning_string); 124 125 next_kerning_string = new Tool ("next_kerning_string", t_("Next kerning string")); 126 next_kerning_string.select_action.connect ((self) => { 127 FontDisplay fd = MainWindow.get_current_display (); 128 KerningDisplay d = (KerningDisplay) fd; 129 Font f = BirdFont.get_current_font (); 130 string w = f.kerning_strings.next (); 131 132 if (f.kerning_strings.is_empty ()) { 133 MainWindow.show_message (empty_kerning_text); 134 } else if (w == "") { 135 MainWindow.show_message (t_("You have reached the end of the list.")); 136 } else { 137 d.new_line (); 138 d.add_text (w); 139 } 140 self.set_selected (false); 141 }); 142 kerning_tools.add_tool (next_kerning_string); 143 144 kerning_tools.set_persistent (false); 145 kerning_tools.set_unique (false); 146 147 classes.set_persistent (true); 148 classes.set_unique (true); 149 150 expanders.add (font_name); 151 expanders.add (zoom_expander); 152 expanders.add (kerning_tools); 153 expanders.add (classes); 154 } 155 156 public static void add_unique_class (KerningRange kerning_class) { 157 KerningRange k; 158 159 if (is_null (classes)) { // FIXME: export without tools 160 init (); 161 } 162 163 foreach (Tool t in classes.tool) { 164 if (!(t is KerningRange)) { 165 warning ("Tool is not kerning range"); 166 return; 167 } 168 169 k = (KerningRange) t; 170 if (k.glyph_range.get_all_ranges () == kerning_class.glyph_range.get_all_ranges ()) { 171 return; 172 } 173 } 174 175 classes.add_tool (kerning_class); 176 } 177 178 public static GlyphRange get_kerning_class (int index) { 179 if (likely (0 <= index < classes.tool.size)) { 180 return ((KerningRange) classes.tool.get (index)).glyph_range; 181 } else { 182 warning ("Index out of bounds."); 183 return new GlyphRange (); 184 } 185 } 186 187 public static void update_kerning_classes () { 188 Font font = BirdFont.get_current_font (); 189 KerningClasses k = font.get_kerning_classes (); 190 KerningRange kr; 191 GlyphRange r; 192 int i; 193 194 remove_all_kerning_classes (); 195 196 for (i = 0; i < k.classes_first.size; i++) { 197 r = k.classes_first.get (i); 198 if (r.is_class ()) { 199 kr = new KerningRange (font); 200 kr.set_ranges (r.get_all_ranges ()); 201 add_unique_class (kr); 202 } 203 204 r = k.classes_last.get (i); 205 if (r.is_class ()) { 206 kr = new KerningRange (font); 207 kr.set_ranges (r.get_all_ranges ()); 208 add_unique_class (kr); 209 } 210 } 211 } 212 213 private static void remove_all_kerning_classes () { 214 if (is_null (classes)) { // FIXME: export without tools 215 init (); 216 } 217 218 classes.tool.clear (); 219 220 if (!is_null (MainWindow.get_toolbox ())) { 221 MainWindow.get_toolbox ().update_expanders (); 222 } 223 } 224 225 public static void remove_empty_classes () { 226 KerningRange kr; 227 int i; 228 229 if (classes.tool.size == 0) { 230 return; 231 } 232 233 i = 0; 234 foreach (Tool t in classes.tool) { 235 return_if_fail (t is KerningRange); 236 237 kr = (KerningRange) t; 238 if (kr.glyph_range.is_empty ()) { 239 classes.tool.remove_at (i); 240 remove_empty_classes (); 241 Toolbox.redraw_tool_box (); 242 return; 243 } 244 245 i++; 246 } 247 } 248 249 public override Gee.ArrayList<Expander> get_expanders () { 250 return expanders; 251 } 252 253 public static void update_spacing_classes () { 254 KerningRange kr; 255 256 if (classes.tool.size == 0) { 257 return; 258 } 259 260 foreach (Tool t in classes.tool) { 261 return_if_fail (t is KerningRange); 262 263 kr = (KerningRange) t; 264 kr.update_spacing_class (); 265 } 266 } 267 268 public override Gee.ArrayList<string> get_displays () { 269 Gee.ArrayList<string> d = new Gee.ArrayList<string> (); 270 d.add ("Kerning"); 271 d.add ("Spacing"); 272 return d; 273 } 274 } 275 276 } 277