The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

OverviewTools.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/OverviewTools.vala.
Redraw moving canvas and keep OTF feature tab open
1 /* 2 Copyright (C) 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 17 namespace BirdFont { 18 19 public enum Transform { 20 SLANT, 21 SIZE 22 } 23 24 public class OverviewTools : ToolCollection { 25 26 static LabelTool all_glyphs; 27 static LabelTool default_glyphs; 28 static LabelTool unicode; 29 30 static Gee.ArrayList<LabelTool> custom_character_sets; 31 32 public static Gee.ArrayList<Expander> expanders; 33 public ZoomBar zoom_bar; 34 35 public static Expander zoom_expander; 36 37 public static SpinButton skew; 38 public static SpinButton resize; 39 40 public static double current_master_size; 41 42 public OverviewTools () { 43 Expander font_name = new Expander (); 44 Expander character_sets = new Expander (t_("Character Sets")); 45 Expander zoom_expander = new Expander (t_("Zoom")); 46 Expander transform_slant_expander = new Expander (t_("Transform")); 47 Expander transform_size_expander = new Expander (); 48 Expander glyph_expander = new Expander (t_("Glyph")); 49 Expander multi_master = new Expander (t_("Multi-Master")); 50 51 expanders = new Gee.ArrayList<Expander> (); 52 custom_character_sets = new Gee.ArrayList<LabelTool> (); 53 54 font_name.add_tool (new FontName ()); 55 56 zoom_bar = new ZoomBar (); 57 zoom_bar.new_zoom.connect ((z) => { 58 get_overview ().set_zoom (z); 59 }); 60 zoom_expander.add_tool (zoom_bar); 61 62 all_glyphs = new LabelTool (t_("All Glyphs")); 63 all_glyphs.has_counter = true; 64 all_glyphs.select_action.connect ((self) => { 65 OverView overview = get_overview (); 66 overview.display_all_available_glyphs (); 67 update_overview_characterset (overview); 68 FontDisplay.dirty_scrollbar = true; 69 }); 70 character_sets.add_tool (all_glyphs); 71 72 default_glyphs = new LabelTool (t_("Default")); 73 default_glyphs.has_counter = true; 74 default_glyphs.select_action.connect ((self) => { 75 OverView overview = get_overview (); 76 GlyphRange gr = new GlyphRange (); 77 DefaultCharacterSet.use_default_range (gr); 78 overview.set_current_glyph_range (gr); 79 update_overview_characterset (overview); 80 FontDisplay.dirty_scrollbar = true; 81 }); 82 character_sets.add_tool (default_glyphs); 83 84 unicode = new LabelTool (t_("Unicode")); 85 unicode.has_counter = true; 86 unicode.select_action.connect ((self) => { 87 OverView overview = get_overview (); 88 GlyphRange gr = new GlyphRange (); 89 DefaultCharacterSet.use_full_unicode_range (gr); 90 overview.set_current_glyph_range (gr); 91 update_overview_characterset (overview); 92 FontDisplay.dirty_scrollbar = true; 93 }); 94 character_sets.add_tool (unicode); 95 96 character_sets.set_persistent (true); 97 character_sets.set_unique (false); 98 99 skew = new SpinButton ("skew_overview", t_("Skew")); 100 skew.set_big_number (true); 101 skew.set_int_value ("0.000"); 102 103 FontSettings settings = BirdFont.get_current_font ().settings; 104 string? skew_value = settings.get_setting ("skew_overview"); 105 106 if (skew_value != null) { 107 skew.set_int_value ((!) skew_value); 108 } 109 110 skew.set_int_step (1); 111 skew.set_min (-100); 112 skew.set_max (100); 113 skew.show_icon (true); 114 skew.set_persistent (false); 115 transform_slant_expander.add_tool (skew); 116 117 Tool transform_slant = new Tool ("transform_slant", t_("Transform")); 118 transform_slant.set_icon ("transform"); 119 transform_slant.select_action.connect ((self) => { 120 FontSettings fs = BirdFont.get_current_font ().settings; 121 fs.set_setting ("skew_overview", @"$(skew.get_value ())"); 122 transform_slant.selected = false; 123 124 process_transform (Transform.SLANT); 125 126 BirdFont.get_current_font ().touch (); 127 }); 128 transform_slant.selected = false; 129 transform_slant.set_persistent (false); 130 transform_slant_expander.add_tool (transform_slant); 131 132 resize = new SpinButton ("resize_overview", t_("Resize")); 133 resize.set_big_number (true); 134 resize.set_int_value ("100.0"); 135 136 string? resize_value = settings.get_setting ("resize_overview"); 137 138 if (resize_value != null) { 139 resize.set_int_value ((!) resize_value); 140 141 if (resize.get_value () <= 0) { 142 resize.set_int_value ("100.0"); 143 } 144 } 145 146 resize.set_int_step (1); 147 resize.set_min (0); 148 resize.set_max (300); 149 resize.show_icon (true); 150 resize.set_persistent (false); 151 transform_size_expander.add_tool (resize); 152 153 Tool transform_size = new Tool ("transform_size", t_("Transform")); 154 transform_size.set_icon ("transform"); 155 transform_size.select_action.connect ((self) => { 156 FontSettings fs = BirdFont.get_current_font ().settings; 157 fs.set_setting ("resize_overview", @"$(resize.get_value ())"); 158 transform_size.selected = false; 159 160 process_transform (Transform.SIZE); 161 162 BirdFont.get_current_font ().touch (); 163 }); 164 transform_size.selected = false; 165 transform_size.set_persistent (false); 166 transform_size_expander.add_tool (transform_size); 167 168 Tool alternate = new Tool ("alternate", t_("Create alternate")); 169 alternate.select_action.connect (add_new_alternate); 170 glyph_expander.add_tool (alternate); 171 172 Tool curve_orientation = new Tool ("curve_orientation", t_("Set curve orientation")); 173 curve_orientation.select_action.connect ((self) => { 174 Task t = new Task (fix_curve_orientation); 175 176 MainWindow.run_blocking_task (t); 177 178 IdleSource idle = new IdleSource (); 179 idle.set_callback (() => { 180 self.set_selected (false); 181 BirdFont.get_current_font ().touch (); 182 return false; 183 }); 184 idle.attach (null); 185 }); 186 glyph_expander.add_tool (curve_orientation); 187 188 Tool search_glyph = new Tool ("search", t_("Search")); 189 search_glyph.select_action.connect (search_for_glyph); 190 glyph_expander.add_tool (search_glyph); 191 192 SpinButton master_size; 193 current_master_size = 0; 194 master_size = new SpinButton ("master_size", t_("Master Size")); /// Master refers to a glyph master in a multi-master font. 195 master_size.set_big_number (false); 196 master_size.set_int_value ("0.000"); 197 master_size.set_int_step (1); 198 master_size.set_min (-1); 199 master_size.set_max (1); 200 master_size.show_icon (true); 201 master_size.set_persistent (false); 202 master_size.new_value_action.connect ((self) => { 203 current_master_size = self.get_value (); 204 MainWindow.get_overview ().update_item_list (); 205 GlyphCanvas.redraw (); 206 }); 207 multi_master.add_tool (master_size); 208 209 Tool create_new_master = new Tool ("new_master", t_("Create new master font")); /// Master is a master in a multi-master font. 210 create_new_master.select_action.connect (create_master); 211 multi_master.add_tool (create_new_master); 212 213 expanders.add (font_name); 214 expanders.add (zoom_expander); 215 expanders.add (character_sets); 216 expanders.add (transform_slant_expander); 217 expanders.add (transform_size_expander); 218 expanders.add (glyph_expander); 219 220 if (BirdFont.has_argument ("--test")) { 221 expanders.add (multi_master); 222 } 223 } 224 225 void create_master () { 226 Font font = BirdFont.get_current_font (); 227 int i = 0; 228 GlyphCollection glyph_collection; 229 GlyphCollection? gc = font.get_glyph_collection_index (i); 230 Glyph g; 231 232 while (gc != null) { 233 glyph_collection = (!) gc; 234 235 // FIXME: MASTER NAME 236 GlyphMaster master = new GlyphMaster.for_id("Master 2"); 237 g = glyph_collection.get_interpolated (current_master_size); 238 master.add_glyph(g); 239 glyph_collection.add_master (master); 240 glyph_collection.set_selected_master (master); 241 242 i++; 243 gc = font.get_glyph_collection_index (i); 244 } 245 246 MainWindow.get_overview ().update_item_list (); 247 GlyphCanvas.redraw (); 248 } 249 250 void fix_curve_orientation () { 251 OverView o; 252 Glyph g; 253 OverView.OverViewUndoItem ui; 254 255 o = get_overview (); 256 ui = new OverView.OverViewUndoItem (); 257 258 Font f = BirdFont.get_current_font (); 259 ui.alternate_sets = f.alternates.copy (); 260 261 foreach (GlyphCollection gc in o.selected_items) { 262 if (gc.length () > 0) { 263 g = gc.get_current (); 264 ui.glyphs.add (gc.copy_deep ()); 265 g.add_help_lines (); 266 g.fix_curve_orientation (); 267 } 268 } 269 270 o.undo_items.add (ui); 271 GlyphCanvas.redraw (); 272 } 273 274 public void search_for_glyph (Tool tool) { 275 tool.set_selected (false); 276 OverView.search (); 277 } 278 279 public void add_new_alternate (Tool tool) { 280 OverView o = MainWindow.get_overview (); 281 OverViewItem oi = o.selected_item; 282 GlyphCollection? gc; 283 284 tool.set_selected (false); 285 286 gc = (!) oi.glyphs; 287 288 if (oi.glyphs != null && ((!) oi.glyphs).is_unassigned ()) { 289 gc = null; 290 } 291 292 MainWindow.tabs.add_tab (new OtfFeatureTable (gc)); 293 } 294 295 public void process_transform (Transform transform) { 296 OverView o; 297 Glyph g; 298 OverView.OverViewUndoItem ui; 299 300 o = get_overview (); 301 ui = new OverView.OverViewUndoItem (); 302 303 Font f = BirdFont.get_current_font (); 304 ui.alternate_sets = f.alternates.copy (); 305 306 foreach (GlyphCollection gc in o.selected_items) { 307 if (gc.length () > 0) { 308 g = gc.get_current (); 309 ui.glyphs.add (gc.copy_deep ()); 310 g.add_help_lines (); 311 312 if (transform == Transform.SLANT) { 313 if (skew.get_value () != 0) { 314 DrawingTools.resize_tool.skew_glyph (g, -skew.get_value (), 0, false); 315 } 316 } 317 318 if (transform == Transform.SIZE) { 319 if (resize.get_value () != 100) { 320 double scale = resize.get_value () / 100; 321 DrawingTools.resize_tool.resize_glyph (g, scale, scale, false); 322 } 323 } 324 } 325 } 326 327 foreach (OverViewItem item in o.visible_items) { 328 item.draw_glyph_from_font (); 329 } 330 331 o.undo_items.add (ui); 332 GlyphCanvas.redraw (); 333 } 334 335 public OverView get_overview () { 336 FontDisplay fd = MainWindow.get_current_display (); 337 338 if (fd is OverView || fd is GlyphSelection) { 339 return (OverView) fd; 340 } 341 342 warning ("Current tab is not overview."); 343 344 return new OverView (); 345 } 346 347 public static void show_all_available_characters () { 348 all_glyphs.select_action (all_glyphs); 349 } 350 351 public static void update_overview_characterset (OverView? tab = null) { 352 GlyphRange gr; 353 uint size; 354 OverView overview; 355 356 // All characters 357 size = BirdFont.get_current_font ().length (); 358 all_glyphs.number = get_display_value (size); 359 360 // Default 361 gr = new GlyphRange (); 362 DefaultCharacterSet.use_default_range (gr); 363 size = gr.get_length (); 364 default_glyphs.number = get_display_value (size); 365 366 // Unicode 367 gr = new GlyphRange (); 368 DefaultCharacterSet.use_full_unicode_range (gr); 369 size = gr.get_length (); 370 unicode.number = get_display_value (size); 371 372 overview = (tab == null) ? MainWindow.get_overview () : (!) tab; 373 374 // set selected item 375 all_glyphs.set_selected (false); 376 default_glyphs.set_selected (false); 377 unicode.set_selected (false); 378 379 if (overview.all_available) { 380 all_glyphs.set_selected (true); 381 } else if (overview.glyph_range.name == "Default") { 382 default_glyphs.set_selected (true); 383 } else if (overview.glyph_range.name == "Unicode") { 384 unicode.set_selected (true); 385 } 386 387 Toolbox.redraw_tool_box (); 388 } 389 390 static string get_display_value (uint size) { 391 double k; 392 string display_size; 393 394 if (size >= 1000) { 395 k = size / 1000.0; 396 size = (uint) Math.rint (k); 397 display_size = @"$(size)k"; 398 } else { 399 display_size = @"$(size)"; 400 } 401 402 return display_size; 403 } 404 405 public override Gee.ArrayList<Expander> get_expanders () { 406 return expanders; 407 } 408 409 public override Gee.ArrayList<string> get_displays () { 410 Gee.ArrayList<string> d = new Gee.ArrayList<string> (); 411 d.add ("Overview"); 412 return d; 413 } 414 } 415 416 } 417