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.
Remove hyphen in the full name field (Name table)
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 static Expander otf_features; 32 33 static OtfTags active_otf_features; 34 35 public KerningTools () { 36 selected (); 37 } 38 39 public override void selected () { 40 init (); 41 } 42 43 public static OtfTags get_otf_tags () { 44 if (is_null (active_otf_features)) { 45 return new OtfTags (); 46 } 47 48 return active_otf_features; 49 } 50 51 public static void init () { 52 Font font = BirdFont.get_current_font (); 53 54 active_otf_features = new OtfTags (); 55 56 Expander kerning_tools = new Expander (t_("Kerning Tools")); 57 58 if (is_null (classes)) { 59 classes = new Expander (); 60 update_kerning_classes (); 61 } 62 63 expanders = new Gee.ArrayList<Expander> (); 64 65 Expander font_name = new Expander (); 66 font_name.add_tool (new FontName ()); 67 68 Expander zoom_expander = new Expander (t_("Font Size")); 69 70 zoom_bar = new ZoomBar (); 71 zoom_bar.new_zoom.connect ((z) => { 72 Font f; 73 74 font_size = 3 * z; 75 76 if (font_size < 0.1) { 77 font_size = 0.1; 78 } 79 80 f = BirdFont.get_current_font (); 81 f.settings.set_setting ("kerning_zoom", @"$z"); 82 83 GlyphCanvas.redraw (); 84 }); 85 zoom_expander.add_tool (zoom_bar); 86 87 Tool new_kerning_class = new Tool ("kerning_class", t_("Create new kerning class.")); 88 new_kerning_class.select_action.connect ((self) => { 89 Font f = BirdFont.get_current_font (); 90 string label = t_("Kerning class"); 91 KerningRange kr = new KerningRange (f, @"$label $(++next_class)"); 92 classes.add_tool (kr); 93 self.set_selected (false); 94 classes.clear_cache (); 95 classes.redraw (); 96 }); 97 kerning_tools.add_tool (new_kerning_class); 98 99 Tool text_kerning = new Tool ("kerning_text_input", t_("Use text input to enter kerning values.")); 100 text_kerning.select_action.connect ((self) => { 101 KerningDisplay d = MainWindow.get_kerning_display (); 102 d.set_kerning_by_text (); 103 self.set_selected (false); 104 }); 105 kerning_tools.add_tool (text_kerning); 106 107 Tool insert_last = new Tool ("insert_glyph_from_overview", t_("Insert glyph from overview")); 108 insert_last.select_action.connect ((self) => { 109 KerningDisplay d = MainWindow.get_kerning_display (); 110 GlyphSelection gs = new GlyphSelection (); 111 112 gs.selected_glyph.connect ((gc) => { 113 d.inser_glyph (gc.get_current ()); 114 MainWindow.get_tab_bar ().select_tab_name ("Kerning"); 115 }); 116 117 GlyphCanvas.set_display (gs); 118 self.set_selected (false); 119 }); 120 kerning_tools.add_tool (insert_last); 121 122 Tool insert_unicode = new Tool ("insert_unichar", t_("Insert character by unicode value")); 123 insert_unicode.select_action.connect ((self) => { 124 KerningDisplay d = MainWindow.get_kerning_display (); 125 d.insert_unichar (); 126 self.set_selected (false); 127 }); 128 kerning_tools.add_tool (insert_unicode); 129 130 Tool right_to_left = new Tool ("right_to_left", t_("Right to left")); 131 right_to_left.select_action.connect ((self) => { 132 KerningDisplay d = MainWindow.get_kerning_display (); 133 d.right_to_left = !d.right_to_left; 134 right_to_left.set_selected (d.right_to_left); 135 GlyphCanvas.redraw (); 136 }); 137 kerning_tools.add_tool (right_to_left); 138 139 string empty_kerning_text = t_("Open a text file with kerning strings first."); 140 141 previous_kerning_string = new Tool ("previous_kerning_string", t_("Previous kerning string")); 142 previous_kerning_string.select_action.connect ((self) => { 143 FontDisplay fd = MainWindow.get_current_display (); 144 KerningDisplay d = (KerningDisplay) fd; 145 Font f = BirdFont.get_current_font (); 146 string w = f.kerning_strings.previous (); 147 148 if (f.kerning_strings.is_empty ()) { 149 MainWindow.show_message (empty_kerning_text); 150 } else if (w == "") { 151 MainWindow.show_message (t_("You have reached the beginning of the list.")); 152 } else { 153 d.new_line (); 154 d.add_text (w); 155 } 156 self.set_selected (false); 157 }); 158 kerning_tools.add_tool (previous_kerning_string); 159 160 next_kerning_string = new Tool ("next_kerning_string", t_("Next kerning string")); 161 next_kerning_string.select_action.connect ((self) => { 162 FontDisplay fd = MainWindow.get_current_display (); 163 KerningDisplay d = (KerningDisplay) fd; 164 Font f = BirdFont.get_current_font (); 165 string w = f.kerning_strings.next (); 166 167 if (f.kerning_strings.is_empty ()) { 168 MainWindow.show_message (empty_kerning_text); 169 } else if (w == "") { 170 MainWindow.show_message (t_("You have reached the end of the list.")); 171 } else { 172 d.new_line (); 173 d.add_text (w); 174 } 175 self.set_selected (false); 176 }); 177 kerning_tools.add_tool (next_kerning_string); 178 179 otf_features = new Expander (t_("Substitutions")); 180 181 foreach (string tag in font.alternates.get_all_tags ()) { 182 add_otf_label (tag); 183 } 184 185 kerning_tools.set_persistent (false); 186 kerning_tools.set_unique (false); 187 188 classes.set_persistent (true); 189 classes.set_unique (true); 190 191 expanders.add (font_name); 192 expanders.add (zoom_expander); 193 expanders.add (kerning_tools); 194 expanders.add (otf_features); 195 expanders.add (classes); 196 } 197 198 public static void add_otf_label (string tag) { 199 OtfLabel otf_label = new OtfLabel (tag); 200 FontSettings fs = BirdFont.get_current_font ().settings; 201 202 otf_features.add_tool (otf_label); 203 otf_label.otf_feature_activity.connect ((enable, tag) => { 204 OtfTags tags = active_otf_features.copy (); 205 KerningDisplay kd = MainWindow.get_kerning_display (); 206 kd.new_segment (); 207 208 // create a new feature set in order to keep the features 209 // for other parts of the text in kerning tab 210 active_otf_features = tags; 211 212 if (enable) { 213 tags.add (tag); 214 fs.set_setting (@"kerning_$(tag)", "true"); 215 } else { 216 tags.remove (tag); 217 fs.set_setting (@"kerning_$(tag)", "false"); 218 } 219 220 kd.get_last_segment ().set_otf_tags (tags); 221 222 GlyphCanvas.redraw (); 223 }); 224 225 bool enable = fs.get_setting (@"kerning_$(tag)") == "true"; 226 otf_label.set_selected_tag (enable); 227 } 228 229 public static void add_unique_class (KerningRange kerning_class) { 230 KerningRange k; 231 232 if (is_null (classes)) { // FIXME: export without tools 233 init (); 234 } 235 236 foreach (Tool t in classes.tool) { 237 if (!(t is KerningRange)) { 238 warning ("Tool is not kerning range"); 239 return; 240 } 241 242 k = (KerningRange) t; 243 if (k.glyph_range.get_all_ranges () == kerning_class.glyph_range.get_all_ranges ()) { 244 return; 245 } 246 } 247 248 kerning_class.h += 50; 249 classes.add_tool (kerning_class); 250 } 251 252 public static GlyphRange get_kerning_class (int index) { 253 if (likely (0 <= index < classes.tool.size)) { 254 return ((KerningRange) classes.tool.get (index)).glyph_range; 255 } else { 256 warning ("Index out of bounds."); 257 return new GlyphRange (); 258 } 259 } 260 261 public static void update_kerning_classes () { 262 Font font = BirdFont.get_current_font (); 263 KerningClasses k = font.get_kerning_classes (); 264 KerningRange kr; 265 GlyphRange r; 266 int i; 267 268 remove_all_kerning_classes (); 269 270 for (i = 0; i < k.classes_first.size; i++) { 271 r = k.classes_first.get (i); 272 if (r.is_class ()) { 273 kr = new KerningRange (font); 274 kr.set_ranges (r.get_all_ranges ()); 275 add_unique_class (kr); 276 } 277 278 r = k.classes_last.get (i); 279 if (r.is_class ()) { 280 kr = new KerningRange (font); 281 kr.set_ranges (r.get_all_ranges ()); 282 add_unique_class (kr); 283 } 284 } 285 286 classes.clear_cache (); 287 classes.redraw (); 288 } 289 290 private static void remove_all_kerning_classes () { 291 if (is_null (classes)) { // FIXME: export without tools 292 init (); 293 } 294 295 classes.tool.clear (); 296 297 if (!is_null (MainWindow.get_toolbox ())) { 298 MainWindow.get_toolbox ().update_expanders (); 299 } 300 } 301 302 public static void remove_empty_classes () { 303 KerningRange kr; 304 int i; 305 306 if (classes.tool.size == 0) { 307 return; 308 } 309 310 i = 0; 311 foreach (Tool t in classes.tool) { 312 return_if_fail (t is KerningRange); 313 314 kr = (KerningRange) t; 315 if (kr.glyph_range.is_empty ()) { 316 classes.tool.remove_at (i); 317 remove_empty_classes (); 318 Toolbox.redraw_tool_box (); 319 return; 320 } 321 322 i++; 323 } 324 } 325 326 public override Gee.ArrayList<Expander> get_expanders () { 327 return expanders; 328 } 329 330 public static void update_spacing_classes () { 331 KerningRange kr; 332 333 if (classes.tool.size == 0) { 334 return; 335 } 336 337 foreach (Tool t in classes.tool) { 338 return_if_fail (t is KerningRange); 339 340 kr = (KerningRange) t; 341 kr.update_spacing_class (); 342 } 343 } 344 345 public override Gee.ArrayList<string> get_displays () { 346 Gee.ArrayList<string> d = new Gee.ArrayList<string> (); 347 d.add ("Kerning"); 348 d.add ("Spacing"); 349 return d; 350 } 351 352 } 353 354 } 355