/* Copyright (C) 2012 2014 2015 Johan Mattsson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. */ using Cairo; using Math; namespace BirdFont { public class GlyphCollection : GLib.Object { unichar unicode_character; string name; bool unassigned; public Gee.ArrayList glyph_masters; int current_master = 0; public GlyphCollection (unichar unicode_character, string name) { this.unicode_character = unicode_character; this.name = name; glyph_masters = new Gee.ArrayList (); unassigned = false; } public GlyphCollection.with_glyph (unichar unicode_character, string name) { Glyph g; GlyphMaster master; glyph_masters = new Gee.ArrayList (); master = new GlyphMaster (); glyph_masters.add (master); unassigned = false; this.unicode_character = unicode_character; this.name = name; g = new Glyph (name, unicode_character); master.glyphs.add (g); master.set_selected (g); } public bool has_masters () { return glyph_masters.size > 0; } /** This method returns the current master, it has global state. */ public GlyphMaster get_current_master () { int i = current_master; GlyphMaster m; if (unlikely (glyph_masters.size == 0)) { warning("No master is set for glyph."); m = new GlyphMaster (); add_master (m); return m; } else if (unlikely (i >= glyph_masters.size)) { warning(@"No master at index $i. ($(glyph_masters.size)) in $(name)"); i = glyph_masters.size - 1; } if (unlikely (!(0 <= i < glyph_masters.size))) { warning(@"index out of bounds $i"); return new GlyphMaster (); } return glyph_masters.get (i); } public bool has_master (string id) { foreach (GlyphMaster m in glyph_masters) { if (m.get_id () == id) { return true; } } return false; } public GlyphMaster get_master (string id) { GlyphMaster? found = null; foreach (GlyphMaster m in glyph_masters) { if (m.get_id () == id) { found = m; } } if (unlikely (found == null)) { warning ("Master not found for id $(id)."); return new GlyphMaster (); } return (!) found; } public bool is_multimaster() { return glyph_masters.size > 1; } public void remove (int index) { get_current_master ().remove (index); } public void set_selected (Glyph g) { get_current_master ().set_selected (g); } public void set_unassigned (bool a) { unassigned = a; } public bool is_unassigned () { return unassigned; } public void add_master (GlyphMaster master) { glyph_masters.add (master); } public void set_selected_master (GlyphMaster m) { current_master = glyph_masters.index_of (m); if (unlikely (current_master == -1)) { warning ("Master does not exits"); current_master = 0; } } public Glyph get_current () { Glyph? g = get_current_master ().get_current (); if (likely (g != null)) { return (!) g; } warning (@"No glyph selected for $(name)"); return new Glyph ("", '\0'); } public Glyph get_interpolated (double weight) { if (weight == 0) { // FIXME: compare to master weight return get_current (); } if (glyph_masters.size == 1) { return get_current ().self_interpolate (weight); } else { warning("Not implemented."); } return get_current (); } public Glyph get_interpolated_fast (double weight) { if (weight == 0) { // FIXME: compare to master weight return get_current (); } if (glyph_masters.size == 1) { //return get_current ().self_interpolate_fast (weight); return get_current (); } else { warning("Not implemented."); } return get_current (); } public void insert_glyph (Glyph g, bool selected_glyph) { get_current_master ().insert_glyph (g, selected_glyph); } public uint length () { if (!has_masters ()) { return 0; } return get_current_master ().glyphs.size; } public string get_unicode () { StringBuilder unicode = new StringBuilder (); unicode.append_unichar (unicode_character); return unicode.str; } public void set_unicode_character (unichar c) { unicode_character = c; } public unichar get_unicode_character () { return unicode_character; } public string get_name () { return name; } public void set_name (string n) { name = n; } /** Create a copy of this list. This method will copy the list data but * keep pointers to the original glyphs. * @return a new list with copies of pointers to the glyphs */ public GlyphCollection copy () { GlyphCollection n = new GlyphCollection (unicode_character, name); foreach (GlyphMaster g in glyph_masters) { n.glyph_masters.add (g.copy ()); } n.unassigned = unassigned; return n; } public GlyphCollection copy_deep () { GlyphCollection n = new GlyphCollection (unicode_character, name); foreach (GlyphMaster g in glyph_masters) { n.glyph_masters.add (g.copy_deep ()); } n.unassigned = unassigned; return n; } public int get_last_id () { return get_current_master ().get_last_id (); } /** @return all versions of all masters */ public Gee.ArrayList get_all_glyph_masters () { Gee.ArrayList glyphs = new Gee.ArrayList (); foreach (GlyphMaster master in glyph_masters) { foreach (Glyph g in master.glyphs) { glyphs.add (g); } } return glyphs; } } }