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.
Merge branch 'master' of https://github.com/johanmattssonm/birdfont into HEAD
1 /* 2 Copyright (C) 2013 2014 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 KerningTools () { 29 init (); 30 } 31 32 public static void init () { 33 Expander kerning_tools = new Expander (t_("Kerning Tools")); 34 classes = new Expander (); 35 expanders = new Gee.ArrayList<Expander> (); 36 37 Expander font_name = new Expander (); 38 font_name.add_tool (new FontName ()); 39 font_name.draw_separator = false; 40 41 Expander zoom_expander = new Expander (t_("Font Size")); 42 43 zoom_bar = new ZoomBar (); 44 zoom_bar.new_zoom.connect ((z) => { 45 font_size = 3 * z; 46 47 if (font_size < 0.1) { 48 font_size = 0.1; 49 } 50 51 GlyphCanvas.redraw (); 52 }); 53 zoom_expander.add_tool (zoom_bar); 54 55 Tool new_kerning_class = new Tool ("kerning_class", t_("Create new kerning class.")); 56 new_kerning_class.select_action.connect ((self) => { 57 Font font = BirdFont.get_current_font (); 58 string label = t_("Kerning class"); 59 KerningRange kr = new KerningRange (font, @"$label $(++next_class)"); 60 classes.add_tool (kr); 61 Toolbox.redraw_tool_box (); 62 }); 63 kerning_tools.add_tool (new_kerning_class); 64 65 Tool text_kerning = new Tool ("kerning_text_input", t_("Use text input to enter kerning values.")); 66 text_kerning.select_action.connect ((self) => { 67 KerningDisplay d = MainWindow.get_kerning_display (); 68 d.set_kerning_by_text (); 69 }); 70 kerning_tools.add_tool (text_kerning); 71 72 Tool insert_last = new Tool ("insert_glyph_from_overview", t_("Insert glyph from overview")); 73 insert_last.select_action.connect ((self) => { 74 KerningDisplay d = MainWindow.get_kerning_display (); 75 GlyphSelection gs = new GlyphSelection (); 76 77 gs.selected_glyph.connect ((gc) => { 78 d.inser_glyph (gc.get_current ()); 79 MainWindow.get_tab_bar ().select_tab_name ("Kerning"); 80 }); 81 82 GlyphCanvas.set_display (gs); 83 }); 84 kerning_tools.add_tool (insert_last); 85 86 Tool insert_unicode = new Tool ("insert_unichar", t_("Insert character by unicode value")); 87 insert_unicode.select_action.connect ((self) => { 88 KerningDisplay d = MainWindow.get_kerning_display (); 89 d.insert_unichar (); 90 }); 91 kerning_tools.add_tool (insert_unicode); 92 93 kerning_tools.set_persistent (false); 94 kerning_tools.set_unique (false); 95 96 classes.set_persistent (true); 97 classes.set_unique (true); 98 99 expanders.add (font_name); 100 expanders.add (zoom_expander); 101 expanders.add (kerning_tools); 102 expanders.add (classes); 103 } 104 105 public static void add_unique_class (KerningRange kerning_class) { 106 KerningRange k; 107 108 if (is_null (classes)) { // FIXME: export without tools 109 init (); 110 } 111 112 foreach (Tool t in classes.tool) { 113 if (!(t is KerningRange)) { 114 warning ("Tool is not kerning range"); 115 return; 116 } 117 118 k = (KerningRange) t; 119 if (k.glyph_range.get_all_ranges () == kerning_class.glyph_range.get_all_ranges ()) { 120 return; 121 } 122 } 123 124 classes.add_tool (kerning_class); 125 } 126 127 public static GlyphRange get_kerning_class (int index) { 128 if (likely (0 <= index < classes.tool.size)) { 129 return ((KerningRange) classes.tool.get (index)).glyph_range; 130 } else { 131 warning ("Index out of bounds."); 132 return new GlyphRange (); 133 } 134 } 135 136 public static void update_kerning_classes () { 137 Font font = BirdFont.get_current_font (); 138 KerningClasses k = font.get_kerning_classes (); 139 KerningRange kr; 140 GlyphRange r; 141 int i; 142 143 remove_all_kerning_classes (); 144 145 for (i = 0; i < k.classes_first.size; i++) { 146 r = k.classes_first.get (i); 147 if (r.is_class ()) { 148 kr = new KerningRange (font); 149 kr.set_ranges (r.get_all_ranges ()); 150 add_unique_class (kr); 151 } 152 153 r = k.classes_last.get (i); 154 if (r.is_class ()) { 155 kr = new KerningRange (font); 156 kr.set_ranges (r.get_all_ranges ()); 157 add_unique_class (kr); 158 } 159 } 160 } 161 162 private static void remove_all_kerning_classes () { 163 if (is_null (classes)) { // FIXME: export without tools 164 init (); 165 } 166 167 classes.tool.clear (); 168 169 if (!is_null (MainWindow.get_toolbox ())) { 170 MainWindow.get_toolbox ().update_expanders (); 171 } 172 } 173 174 public static void remove_empty_classes () { 175 KerningRange kr; 176 int i; 177 178 if (classes.tool.size == 0) { 179 return; 180 } 181 182 i = 0; 183 foreach (Tool t in classes.tool) { 184 return_if_fail (t is KerningRange); 185 186 kr = (KerningRange) t; 187 if (kr.glyph_range.is_empty ()) { 188 classes.tool.remove_at (i); 189 remove_empty_classes (); 190 Toolbox.redraw_tool_box (); 191 return; 192 } 193 194 i++; 195 } 196 } 197 198 public override Gee.ArrayList<Expander> get_expanders () { 199 return expanders; 200 } 201 202 public static void update_spacing_classes () { 203 KerningRange kr; 204 205 if (classes.tool.size == 0) { 206 return; 207 } 208 209 foreach (Tool t in classes.tool) { 210 return_if_fail (t is KerningRange); 211 212 kr = (KerningRange) t; 213 kr.update_spacing_class (); 214 } 215 } 216 } 217 218 } 219