The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

GlyphCollection.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/GlyphCollection.vala.
Fix a performance issue connected to multimasters
1 /* 2 Copyright (C) 2012 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 GlyphCollection : GLib.Object { 21 unichar unicode_character; 22 string name; 23 bool unassigned; 24 public Gee.ArrayList<GlyphMaster> glyph_masters; 25 int current_master = 0; 26 27 public GlyphCollection (unichar unicode_character, string name) { 28 this.unicode_character = unicode_character; 29 this.name = name; 30 glyph_masters = new Gee.ArrayList<GlyphMaster> (); 31 unassigned = false; 32 } 33 34 public GlyphCollection.with_glyph (unichar unicode_character, string name) { 35 Glyph g; 36 GlyphMaster master; 37 38 glyph_masters = new Gee.ArrayList<GlyphMaster> (); 39 master = new GlyphMaster (); 40 glyph_masters.add (master); 41 42 unassigned = false; 43 44 this.unicode_character = unicode_character; 45 this.name = name; 46 47 g = new Glyph (name, unicode_character); 48 master.glyphs.add (g); 49 master.set_selected (g); 50 } 51 52 public bool has_masters () { 53 return glyph_masters.size > 0; 54 } 55 56 /** This method returns the current master, it has global state. */ 57 public GlyphMaster get_current_master () { 58 int i = current_master; 59 GlyphMaster m; 60 61 if (unlikely (glyph_masters.size == 0)) { 62 warning("No master is set for glyph."); 63 m = new GlyphMaster (); 64 add_master (m); 65 return m; 66 } else if (unlikely (i >= glyph_masters.size)) { 67 warning(@"No master at index $i. ($(glyph_masters.size)) in $(name)"); 68 i = glyph_masters.size - 1; 69 } 70 71 return_val_if_fail (0 <= i < glyph_masters.size, new GlyphMaster ()); 72 73 return glyph_masters.get (i); 74 } 75 76 public bool has_master (string id) { 77 foreach (GlyphMaster m in glyph_masters) { 78 if (m.get_id () == id) { 79 return true; 80 } 81 } 82 83 return false; 84 } 85 86 public GlyphMaster get_master (string id) { 87 foreach (GlyphMaster m in glyph_masters) { 88 if (m.get_id () == id) { 89 return m; 90 } 91 } 92 93 warning ("Master not found for id $(id)."); 94 return new GlyphMaster (); 95 } 96 97 public bool is_multimaster() { 98 return glyph_masters.size > 1; 99 } 100 101 public void remove (int index) { 102 get_current_master ().remove (index); 103 } 104 105 public void set_selected (Glyph g) { 106 get_current_master ().set_selected (g); 107 } 108 109 public void set_unassigned (bool a) { 110 unassigned = a; 111 } 112 113 public bool is_unassigned () { 114 return unassigned; 115 } 116 117 public void add_master (GlyphMaster master) { 118 glyph_masters.add (master); 119 } 120 121 public void set_selected_master (GlyphMaster m) { 122 current_master = glyph_masters.index_of (m); 123 124 if (current_master == -1) { 125 warning ("Master does not exits"); 126 current_master = 0; 127 } 128 } 129 130 public Glyph get_current () { 131 Glyph? g = get_current_master ().get_current (); 132 133 if (likely (g != null)) { 134 return (!) g; 135 } 136 137 warning (@"No glyph selected for $(name)"); 138 return new Glyph ("", '\0'); 139 } 140 141 public Glyph get_interpolated (double weight) { 142 if (weight == 0) { // FIXME: compare to master weight 143 return get_current (); 144 } 145 146 if (glyph_masters.size == 1) { 147 return get_current ().self_interpolate (weight); 148 } else { 149 warning("Not implemented."); 150 } 151 152 return get_current (); 153 } 154 155 public Glyph get_interpolated_fast (double weight) { 156 if (weight == 0) { // FIXME: compare to master weight 157 return get_current (); 158 } 159 160 if (glyph_masters.size == 1) { 161 //return get_current ().self_interpolate_fast (weight); 162 return get_current (); 163 } else { 164 warning("Not implemented."); 165 } 166 167 return get_current (); 168 } 169 170 public void insert_glyph (Glyph g, bool selected_glyph) { 171 get_current_master ().insert_glyph (g, selected_glyph); 172 } 173 174 public uint length () { 175 if (!has_masters ()) { 176 return 0; 177 } 178 179 return get_current_master ().glyphs.size; 180 } 181 182 public string get_unicode () { 183 StringBuilder unicode = new StringBuilder (); 184 unicode.append_unichar (unicode_character); 185 return unicode.str; 186 } 187 188 public void set_unicode_character (unichar c) { 189 unicode_character = c; 190 } 191 192 public unichar get_unicode_character () { 193 return unicode_character; 194 } 195 196 public string get_name () { 197 return name; 198 } 199 200 public void set_name (string n) { 201 name = n; 202 } 203 204 /** Create a copy of this list. This method will copy the list data but 205 * keep pointers to the original glyphs. 206 * @return a new list with copies of pointers to the glyphs 207 */ 208 public GlyphCollection copy () { 209 GlyphCollection n = new GlyphCollection (unicode_character, name); 210 211 foreach (GlyphMaster g in glyph_masters) { 212 n.glyph_masters.add (g.copy ()); 213 } 214 215 n.unassigned = unassigned; 216 217 return n; 218 } 219 220 public GlyphCollection copy_deep () { 221 GlyphCollection n = new GlyphCollection (unicode_character, name); 222 223 foreach (GlyphMaster g in glyph_masters) { 224 n.glyph_masters.add (g.copy_deep ()); 225 } 226 227 n.unassigned = unassigned; 228 229 return n; 230 } 231 232 public int get_last_id () { 233 return get_current_master ().get_last_id (); 234 } 235 236 /** @return all versions of all masters */ 237 public Gee.ArrayList<Glyph> get_all_glyph_masters () { 238 Gee.ArrayList<Glyph> glyphs = new Gee.ArrayList<Glyph> (); 239 240 foreach (GlyphMaster master in glyph_masters) { 241 foreach (Glyph g in master.glyphs) { 242 glyphs.add (g); 243 } 244 } 245 246 return glyphs; 247 } 248 } 249 250 } 251