The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

ContextualLigature.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/ContextualLigature.vala.
Cache overview items
1 /* 2 Copyright (C) 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 namespace BirdFont { 16 17 public class ContextualLigature : GLib.Object { 18 19 public string backtrack = ""; 20 public string input = ""; 21 public string lookahead = ""; 22 public string ligatures = ""; 23 24 Font font; 25 26 /** All arguments are list of glyph names separated by space. */ 27 public ContextualLigature (Font font, string ligatures, string backtrack, string input, string lookahead) { 28 this.font = font; 29 this.backtrack = backtrack; 30 this.input = input; 31 this.lookahead = lookahead; 32 this.ligatures = ligatures; 33 } 34 35 public Gee.ArrayList<Ligature> get_ligatures () { 36 Gee.ArrayList<Ligature> ligature_list = new Gee.ArrayList<Ligature> (); 37 string[] ligatures = ligatures.split (" "); 38 39 foreach (string ligature_name in ligatures) { 40 ligature_list.add (new Ligature (ligature_name)); 41 } 42 43 return ligature_list; 44 } 45 46 public FontData get_font_data (GlyfTable glyf_table, uint16 ligature_lookup_index) 47 throws GLib.Error { 48 FontData fd = new FontData (); 49 Font font = BirdFont.get_current_font (); 50 51 Gee.ArrayList<string> backtrack = font.get_names_in_reverse_order (backtrack); 52 Gee.ArrayList<string> input = font.get_names (input); 53 Gee.ArrayList<string> lookahead = font.get_names (lookahead); 54 55 uint16 lookahead_offset, input_offset, backtrack_offset; 56 57 fd.add_ushort (3); // format identifier 58 59 backtrack_offset = 14 + (uint16) (lookahead.size * 2) + (uint16) (input.size * 2) + (uint16) (backtrack.size * 2); 60 fd.add_ushort ((uint16) backtrack.size); // backtrack glyph count 61 for (uint16 i = 0; i < backtrack.size; i++) { 62 fd.add_ushort (backtrack_offset + 6 * i); // array of offsets to coverage table 63 } 64 65 input_offset = 14 + (uint16) (lookahead.size * 2) + (uint16) (input.size * 2) + (uint16) (backtrack.size * (2 + 6)); 66 fd.add_ushort ((uint16) input.size); // input glyph count (middle) 67 for (uint16 i = 0; i < input.size; i++) { 68 fd.add_ushort (input_offset + 6 * i); // array of offsets to coverage table 69 } 70 71 lookahead_offset = 14 + (uint16) (lookahead.size * 2) + (uint16) (input.size * (2 + 6)) + (uint16) (backtrack.size * (2 + 6)); 72 fd.add_ushort ((uint16) lookahead.size); // lookahead glyph count 73 for (uint16 i = 0; i < lookahead.size; i++) { 74 fd.add_ushort (lookahead_offset + 6 * i); // array of offsets to coverage table 75 } 76 77 fd.add_ushort (1); // substitute count 78 79 // substitution lookup records 80 fd.add_ushort (0); // glyph sequence index for the character that will be substituted 81 fd.add_ushort (ligature_lookup_index); // go to the ligature substitution via lookup table 82 83 // backtrack coverage table1 84 if (fd.length_with_padding () != backtrack_offset) { 85 warning (@"Wrong backtrack offset: $backtrack_offset != $(fd.length_with_padding ())"); 86 } 87 88 // gid array 89 foreach (string glyph_name in backtrack) { 90 fd.add_ushort (1); // format 91 fd.add_ushort (1); // coverage array length 92 fd.add_ushort ((uint16) glyf_table.get_gid (glyph_name)); 93 } 94 95 // input coverage table1 96 if (fd.length_with_padding () != input_offset) { 97 warning (@"Wrong input offset: $input_offset != $(fd.length_with_padding ())"); 98 } 99 100 // gid array 101 foreach (string glyph_name in input) { 102 fd.add_ushort (1); // format 103 fd.add_ushort (1); // coverage array length 104 fd.add_ushort ((uint16) glyf_table.get_gid (glyph_name)); 105 } 106 107 // lookahead coverage table1 108 if (fd.length_with_padding () != lookahead_offset) { 109 warning (@"Wrong lookahead offset: $lookahead_offset != $(fd.length_with_padding ())"); 110 } 111 112 // gid array 113 foreach (string glyph_name in lookahead) { 114 fd.add_ushort (1); // format 115 fd.add_ushort (1); // coverage array length 116 fd.add_ushort ((uint16) glyf_table.get_gid (glyph_name)); 117 } 118 119 return fd; 120 } 121 122 public GlyphSequence get_backtrack () { 123 return get_sequence (backtrack); 124 } 125 126 public GlyphSequence get_input () { 127 return get_sequence (input); 128 } 129 130 public GlyphSequence get_lookahead () { 131 return get_sequence (lookahead); 132 } 133 134 public GlyphSequence get_ligature_sequence () { 135 return get_sequence (ligatures); 136 } 137 138 public bool is_valid () { 139 foreach (string s in font.get_names (backtrack)) { 140 if (font.get_glyph_collection_by_name (s) == null) { 141 return false; 142 } 143 } 144 145 foreach (string s in font.get_names (input)) { 146 if (font.get_glyph_collection_by_name (s) == null) { 147 return false; 148 } 149 } 150 151 foreach (string s in font.get_names (lookahead)) { 152 if (font.get_glyph_collection_by_name (s) == null) { 153 return false; 154 } 155 } 156 157 foreach (string s in font.get_names (ligatures)) { 158 if (font.get_glyph_collection_by_name (s) == null) { 159 return false; 160 } 161 } 162 163 return true; 164 } 165 166 GlyphSequence get_sequence (string context) { 167 GlyphCollection? gc; 168 GlyphSequence gs; 169 170 gs = new GlyphSequence (); 171 foreach (string s in font.get_names (context)) { 172 gc = font.get_glyph_collection_by_name (s); 173 174 if (gc == null) { 175 warning (@"No glyph found for $s"); 176 return new GlyphSequence (); 177 } 178 179 gs.glyph.add (((!) gc).get_current ()); 180 } 181 182 return gs; 183 } 184 } 185 186 } 187