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
Circle boundaries heads/master
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 if (unlikely (!(0 <= i < glyph_masters.size))) { 72 warning(@"index out of bounds $i"); 73 return new GlyphMaster (); 74 } 75 76 return glyph_masters.get (i); 77 } 78 79 public bool has_master (string id) { 80 foreach (GlyphMaster m in glyph_masters) { 81 if (m.get_id () == id) { 82 return true; 83 } 84 } 85 86 return false; 87 } 88 89 public GlyphMaster get_master (string id) { 90 GlyphMaster? found = null; 91 92 foreach (GlyphMaster m in glyph_masters) { 93 if (m.get_id () == id) { 94 found = m; 95 } 96 } 97 98 if (unlikely (found == null)) { 99 warning ("Master not found for id $(id)."); 100 return new GlyphMaster (); 101 } 102 103 return (!) found; 104 } 105 106 public bool is_multimaster() { 107 return glyph_masters.size > 1; 108 } 109 110 public void remove (int index) { 111 get_current_master ().remove (index); 112 } 113 114 public void set_selected (Glyph g) { 115 get_current_master ().set_selected (g); 116 } 117 118 public void set_unassigned (bool a) { 119 unassigned = a; 120 } 121 122 public bool is_unassigned () { 123 return unassigned; 124 } 125 126 public void add_master (GlyphMaster master) { 127 glyph_masters.add (master); 128 } 129 130 public void set_selected_master (GlyphMaster m) { 131 current_master = glyph_masters.index_of (m); 132 133 if (unlikely (current_master == -1)) { 134 warning ("Master does not exits"); 135 current_master = 0; 136 } 137 } 138 139 public Glyph get_current () { 140 Glyph? g = get_current_master ().get_current (); 141 142 if (likely (g != null)) { 143 return (!) g; 144 } 145 146 warning (@"No glyph selected for $(name)"); 147 return new Glyph ("", '\0'); 148 } 149 150 public Glyph get_interpolated (double weight) { 151 if (weight == 0) { // FIXME: compare to master weight 152 return get_current (); 153 } 154 155 if (glyph_masters.size == 1) { 156 return get_current ().self_interpolate (weight); 157 } else { 158 warning("Not implemented."); 159 } 160 161 return get_current (); 162 } 163 164 public Glyph get_interpolated_fast (double weight) { 165 if (weight == 0) { // FIXME: compare to master weight 166 return get_current (); 167 } 168 169 if (glyph_masters.size == 1) { 170 //return get_current ().self_interpolate_fast (weight); 171 return get_current (); 172 } else { 173 warning("Not implemented."); 174 } 175 176 return get_current (); 177 } 178 179 public void insert_glyph (Glyph g, bool selected_glyph) { 180 get_current_master ().insert_glyph (g, selected_glyph); 181 } 182 183 public uint length () { 184 if (!has_masters ()) { 185 return 0; 186 } 187 188 return get_current_master ().glyphs.size; 189 } 190 191 public string get_unicode () { 192 StringBuilder unicode = new StringBuilder (); 193 unicode.append_unichar (unicode_character); 194 return unicode.str; 195 } 196 197 public void set_unicode_character (unichar c) { 198 unicode_character = c; 199 } 200 201 public unichar get_unicode_character () { 202 return unicode_character; 203 } 204 205 public string get_name () { 206 return name; 207 } 208 209 public void set_name (string n) { 210 name = n; 211 } 212 213 /** Create a copy of this list. This method will copy the list data but 214 * keep pointers to the original glyphs. 215 * @return a new list with copies of pointers to the glyphs 216 */ 217 public GlyphCollection copy () { 218 GlyphCollection n = new GlyphCollection (unicode_character, name); 219 220 foreach (GlyphMaster g in glyph_masters) { 221 n.glyph_masters.add (g.copy ()); 222 } 223 224 n.unassigned = unassigned; 225 226 return n; 227 } 228 229 public GlyphCollection copy_deep () { 230 GlyphCollection n = new GlyphCollection (unicode_character, name); 231 232 foreach (GlyphMaster g in glyph_masters) { 233 n.glyph_masters.add (g.copy_deep ()); 234 } 235 236 n.unassigned = unassigned; 237 238 return n; 239 } 240 241 public int get_last_id () { 242 return get_current_master ().get_last_id (); 243 } 244 245 /** @return all versions of all masters */ 246 public Gee.ArrayList<Glyph> get_all_glyph_masters () { 247 Gee.ArrayList<Glyph> glyphs = new Gee.ArrayList<Glyph> (); 248 249 foreach (GlyphMaster master in glyph_masters) { 250 foreach (Glyph g in master.glyphs) { 251 glyphs.add (g); 252 } 253 } 254 255 return glyphs; 256 } 257 } 258 259 } 260