The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

SpacingTab.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/SpacingTab.vala.
Ignore case in key bindings
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 /** Kerning context. */ 20 public class SpacingTab : KerningDisplay { 21 22 double box_size = 122 * MainWindow.units; 23 double height = 44 * MainWindow.units; 24 double character_height = 20 * MainWindow.units; 25 26 WidgetAllocation allocation; 27 28 Glyph text_input_glyph; 29 30 public SpacingTab () { 31 allocation = new WidgetAllocation (); 32 adjust_side_bearings = true; 33 } 34 35 public override string get_label () { 36 return t_("Spacing"); 37 } 38 39 public override string get_name () { 40 return "Spacing"; 41 } 42 43 public override void draw (WidgetAllocation allocation, Context cr) { 44 base.draw (allocation, cr); 45 draw_spacing_metrix (allocation, cr); 46 } 47 48 void draw_spacing_metrix (WidgetAllocation allocation, Context cr) { 49 GlyphSequence row; 50 int index; 51 Font font = BirdFont.get_current_font (); 52 53 // background 54 cr.save (); 55 Theme.color (cr, "Background 1"); 56 cr.rectangle (0, allocation.height - height, allocation.width, height); 57 cr.fill (); 58 cr.restore (); 59 60 // character bar 61 cr.save (); 62 Theme.color (cr, "Table Border"); 63 cr.set_line_width (0.8); 64 cr.move_to (0, allocation.height - height); 65 cr.line_to (allocation.width, allocation.height - height); 66 cr.stroke (); 67 68 cr.move_to (0, allocation.height - height + character_height); 69 cr.line_to (allocation.width, allocation.height - height + character_height); 70 cr.stroke (); 71 cr.restore (); 72 73 // TODO: add button for processing ligatures 74 row = get_first_row ().process_ligatures (font); 75 index = 0; 76 foreach (Glyph? g in row.glyph) { 77 draw_glyph_spacing (allocation, cr, g, index); 78 index++; 79 } 80 } 81 82 void draw_glyph_spacing (WidgetAllocation allocation, Context cr, Glyph? glyph, int index) { 83 Glyph g; 84 double end, middle; 85 double l, r; 86 Text left, right, cap; 87 unichar c; 88 89 this.allocation = allocation; 90 91 // end mark 92 end = (index + 1) * box_size; 93 cr.save (); 94 cr.set_source_rgba (0.5, 0.5, 0.5, 1); 95 cr.set_line_width (2); 96 cr.move_to (end, allocation.height - height); 97 cr.line_to (end, allocation.height); 98 cr.stroke (); 99 cr.restore (); 100 101 // boxes 102 middle = end - box_size / 2.0; 103 cr.save (); 104 cr.set_source_rgba (0.5, 0.5, 0.5, 1); 105 cr.set_line_width (0.8); 106 cr.move_to (middle, allocation.height - height + character_height); 107 cr.line_to (middle, allocation.height); 108 cr.stroke (); 109 cr.restore (); 110 111 if (glyph != null) { 112 g = (!) glyph; 113 114 c = g.get_unichar (); 115 cap = new Text ((!) c.to_string (), 17); 116 Theme.text_color (cap, "Table Border"); 117 cap.widget_x = middle - cap.get_extent () / 2.0; 118 cap.widget_y = allocation.height - height + character_height - 4 * MainWindow.units; 119 cap.draw_at_baseline (cr, cap.widget_x, cap.widget_y); 120 121 l = g.get_left_side_bearing (); 122 123 if (Math.fabs (l) < 0.001) { 124 l = 0; 125 } 126 127 left = new Text (truncate (l, 5), 17); 128 Theme.text_color (left, "Foreground 1"); 129 left.widget_x = middle - box_size / 2.0 + (box_size / 2.0 - left.get_extent ()) / 2.0; 130 left.widget_y = allocation.height - 7 * MainWindow.units; 131 left.draw_at_baseline (cr, left.widget_x, left.widget_y); 132 133 r = g.get_right_side_bearing (); 134 135 if (Math.fabs (r) < 0.001) { 136 r = 0; 137 } 138 139 right = new Text (truncate (r, 5), 17); 140 Theme.text_color (right, "Table Border"); 141 right.widget_x = end - (box_size / 2.0 - right.get_extent ()) / 2.0 - right.get_extent (); 142 right.widget_y = allocation.height - 7 * MainWindow.units; 143 right.draw_at_baseline (cr, right.widget_x, right.widget_y); 144 } 145 } 146 147 public string truncate (double f, int digits) { 148 string t = @"$f"; 149 string s = ""; 150 151 int d = digits; 152 int i; 153 unichar c; 154 155 if (t.index_of ("-") != -1) { 156 d++; 157 } 158 159 if (t.index_of (".") != -1) { 160 d++; 161 } 162 163 i = 0; 164 while (t.get_next_char (ref i, out c)) { 165 s = s + (!) c.to_string (); 166 167 if (i >= d) { 168 break; 169 } 170 } 171 172 return s; 173 } 174 175 public override void button_press (uint button, double ex, double ey) { 176 if (button == 3) { 177 return; 178 } 179 180 if (!(ey >= allocation.height - height)) { 181 base.button_press (button, ex, ey); 182 } 183 } 184 185 public override void button_release (int button, double ex, double ey) { 186 GlyphSequence row; 187 double p; 188 Font font = BirdFont.get_current_font (); 189 190 if (button == 3) { 191 return; 192 } 193 194 if (ey >= allocation.height - height) { 195 196 TabContent.hide_text_input (); 197 198 // TODO: add button for processing ligatures 199 row = get_first_row ().process_ligatures (font); 200 p = 0; 201 foreach (Glyph? g in row.glyph) { 202 if (p < ex < p + box_size / 2.0) { 203 update_lsb (g); 204 } 205 206 if (p + box_size / 2.0 < ex < p + box_size) { 207 update_rsb (g); 208 } 209 210 p += box_size; 211 } 212 } else { 213 base.button_release (button, ex, ey); 214 } 215 } 216 217 void update_lsb (Glyph? g) { 218 TextListener listener; 219 string submitted_value = ""; 220 double l; 221 222 if (g == null) { 223 return; 224 } 225 226 text_input_glyph = (!) g; 227 l = text_input_glyph.get_left_side_bearing (); 228 229 if (Math.fabs (l) < 0.001) { 230 l = 0; 231 } 232 233 listener = new TextListener (t_("Left"), @"$(l)", t_("Set")); 234 235 listener.signal_text_input.connect ((text) => { 236 submitted_value = text; 237 238 if (MenuTab.suppress_event) { 239 return; 240 } 241 242 GlyphCanvas.redraw (); 243 }); 244 245 listener.signal_submit.connect (() => { 246 double v; 247 TabContent.hide_text_input (); 248 249 text_input = false; 250 suppress_input = false; 251 252 v = double.parse (submitted_value); 253 text_input_glyph.left_limit -= v - text_input_glyph.get_left_side_bearing (); 254 }); 255 256 suppress_input = true; 257 text_input = true; 258 TabContent.show_text_input (listener); 259 } 260 261 void update_rsb (Glyph? g) { 262 TextListener listener; 263 string submitted_value = ""; 264 double r; 265 266 if (g == null) { 267 return; 268 } 269 270 text_input_glyph = (!) g; 271 r = text_input_glyph.get_right_side_bearing (); 272 273 if (Math.fabs (r) < 0.001) { 274 r = 0; 275 } 276 277 listener = new TextListener (t_("Right"), @"$(r)", t_("Set")); 278 279 listener.signal_text_input.connect ((text) => { 280 submitted_value = text; 281 282 if (MenuTab.suppress_event) { 283 return; 284 } 285 286 GlyphCanvas.redraw (); 287 }); 288 289 listener.signal_submit.connect (() => { 290 double v; 291 TabContent.hide_text_input (); 292 293 text_input = false; 294 suppress_input = false; 295 296 v = double.parse (submitted_value); 297 text_input_glyph.right_limit += v - text_input_glyph.get_right_side_bearing (); 298 }); 299 300 suppress_input = true; 301 text_input = true; 302 TabContent.show_text_input (listener); 303 } 304 305 public override bool needs_modifier () { 306 return true; 307 } 308 309 } 310 311 } 312