The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

LigatureCollection.vala in libbirdfont/OpenFontFormat

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/OpenFontFormat/LigatureCollection.vala.
Fix merge bug
1 /* 2 Copyright (C) 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 using Math; 15 16 namespace BirdFont { 17 18 public class LigatureCollection : GLib.Object { 19 20 public Gee.ArrayList<LigatureSet> ligature_sets; 21 22 LigatureSet lig_set; 23 LigatureSet last_set; 24 25 public LigatureCollection.clig (GlyfTable glyf_table) { 26 ligature_sets = new Gee.ArrayList<LigatureSet> (); 27 lig_set = new LigatureSet (glyf_table); 28 last_set = new LigatureSet (glyf_table); 29 30 add_clig_ligatures (glyf_table); 31 } 32 33 public LigatureCollection.contextual (GlyfTable glyf_table, ContextualLigature ligature) { 34 ligature_sets = new Gee.ArrayList<LigatureSet> (); 35 lig_set = new LigatureSet (glyf_table); 36 last_set = new LigatureSet (glyf_table); 37 38 add_contextual_ligatures (glyf_table, ligature); 39 } 40 41 void add_clig_ligatures (GlyfTable glyf_table) { 42 Font font = BirdFont.get_current_font (); 43 Ligatures ligatures = font.get_ligatures (); 44 45 int i = 0; 46 ligatures.get_ligatures ((parts, ligature) => { 47 add_ligatures (glyf_table, parts, ligature); 48 }); 49 } 50 51 void add_contextual_ligatures (GlyfTable glyf_table, ContextualLigature cl) { 52 foreach (string l in cl.ligatures.strip ().split (" ")) { 53 add_ligatures (glyf_table, cl.input, l); 54 } 55 } 56 57 // multiple ligatures in non-contextual substitution 58 public void add_ligatures (GlyfTable glyf_table, string characters, string ligatures) 59 requires (!is_null (lig_set) && !is_null (last_set)) { 60 61 Font font = BirdFont.get_current_font (); 62 string[] parts = characters.strip ().split (" "); 63 string l = ligatures; 64 bool has_set = false; 65 66 if (l.has_prefix ("U+") || l.has_prefix ("u+")) { 67 l = (!) Font.to_unichar (l).to_string (); 68 } 69 70 if (!font.has_glyph (l)) { 71 warning (@"Ligature $l does not correspond to a glyph in this font."); 72 return; 73 } 74 75 foreach (string p in parts) { 76 if (p.has_prefix ("U+") || p.has_prefix ("u+")) { 77 p = (!) Font.to_unichar (p).to_string (); 78 } 79 80 if (!font.has_glyph (p)) { 81 warning (@"Ligature substitution of $p is not possible, the character does have a glyph."); 82 return; 83 } 84 } 85 86 if (parts.length == 0) { 87 warning ("No parts."); 88 return; 89 } 90 91 foreach (LigatureSet s in ligature_sets) { 92 if (s.starts_with (parts[0])) { 93 has_set = true; 94 last_set = s; 95 } 96 } 97 98 if (has_set) { 99 last_set.add (new Ligature (l, characters)); 100 } else { 101 lig_set = new LigatureSet (glyf_table); 102 lig_set.add (new Ligature (l, characters)); 103 ligature_sets.add (lig_set); 104 } 105 } 106 107 public FontData get_font_data (GlyfTable glyf_table) throws GLib.Error { 108 FontData set_data; 109 uint16 ligature_pos; 110 uint16 table_start; 111 FontData fd; 112 113 fd = new FontData (); 114 115 // ligature substitution subtable 116 table_start = (uint16) fd.length_with_padding (); 117 118 fd.add_ushort (1); // format identifier 119 fd.add_ushort (6 + (uint16) 2 * ligature_sets.size); // offset to coverage 120 fd.add_ushort ((uint16) ligature_sets.size); // number of ligature set tables 121 122 // array of offsets to ligature sets 123 uint16 size = 0; 124 foreach (LigatureSet l in ligature_sets) { 125 ligature_pos = 10 + (uint16) ligature_sets.size * 4 + size; 126 fd.add_ushort (ligature_pos); 127 size += (uint16) l.get_set_data ().length_with_padding (); 128 } 129 130 // coverage 131 fd.add_ushort (1); // format 132 fd.add_ushort ((uint16) ligature_sets.size); 133 134 // coverage gid: 135 foreach (LigatureSet l in ligature_sets) { 136 fd.add_ushort ((uint16) glyf_table.get_gid (l.get_coverage_char ())); 137 } 138 139 foreach (LigatureSet l in ligature_sets) { 140 set_data = l.get_set_data (); 141 fd.append (set_data); 142 } 143 144 return fd; 145 } 146 } 147 148 } 149