The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

Cmap.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
Circle boundaries heads/master
1 /* 2 Copyright (C) 2012, 2013, 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 Gee; 15 16 namespace BirdFont { 17 18 public class CmapTable : OtfTable { 19 20 GlyfTable glyf_table; 21 CmapSubtableFormat4 cmap_format4 = new CmapSubtableFormat4 (); 22 23 public CmapTable(GlyfTable gt) { 24 glyf_table = gt; 25 id = "cmap"; 26 } 27 28 public unichar get_char (uint32 i) { 29 return get_prefered_table ().get_char (i) ; 30 } 31 32 CmapSubtableFormat4 get_prefered_table () { 33 return cmap_format4; 34 } 35 36 public override string get_id () { 37 return "cmap"; 38 } 39 40 public override void parse (FontData dis) throws GLib.Error { 41 uint16 version; 42 uint16 nsubtables; 43 44 uint16 platform; 45 uint16 encoding; 46 uint32 sub_offset; 47 48 return_if_fail (offset > 0 && length > 0); 49 50 dis.seek (offset); 51 52 version = dis.read_ushort (); 53 nsubtables = dis.read_ushort (); 54 55 printd (@"cmap version: $version\n"); 56 printd (@"cmap subtables: $nsubtables\n"); 57 58 if (version != 0) { 59 warning (@"Bad version for cmap table: $version expecting 0. Number of subtables: $nsubtables"); 60 return; 61 } 62 63 for (uint i = 0; i < nsubtables; i++) { 64 platform = dis.read_ushort (); 65 encoding = dis.read_ushort (); 66 sub_offset = dis.read_ulong (); 67 68 if (platform == 3 && encoding == 1) { 69 printd (@"Parsing Unicode BMP (UCS-2) Platform: $platform Encoding: $encoding\n"); 70 cmap_format4.offset = offset + sub_offset; 71 } else { 72 stderr.printf (@"Unknown cmap format. Platform: $platform Encoding: $encoding.\n"); 73 } 74 75 if (encoding == 3) { 76 stderr.printf ("Font contains a cmap table with the obsolete encoding 3.\n"); 77 } 78 } 79 80 if (cmap_format4.offset > 0) { 81 cmap_format4.parse (dis); 82 } else { 83 warning ("No cmap subtable4 found."); 84 } 85 } 86 87 /** Character to glyph mapping */ 88 public void process (GlyfTable glyf_table) throws GLib.Error { 89 FontData fd = new FontData (); 90 CmapSubtableFormat0 cmap0 = new CmapSubtableFormat0 (); 91 CmapSubtableFormat4 cmap4 = new CmapSubtableFormat4 (); 92 CmapSubtableFormat12 cmap12 = new CmapSubtableFormat12 (); 93 uint16 n_encoding_tables; 94 ArrayList<CmapSubtable> cmap_tables = new ArrayList<CmapSubtable> (); 95 96 cmap0.generate_cmap_data (glyf_table); 97 cmap4.generate_cmap_data (glyf_table); 98 cmap12.generate_cmap_data (glyf_table); 99 100 cmap_tables.add(cmap0); 101 cmap_tables.add(cmap4); 102 cmap_tables.add(cmap12); 103 104 n_encoding_tables = (uint16) cmap_tables.size; 105 106 fd.add_u16 (0); // table version 107 fd.add_u16 (n_encoding_tables); 108 109 uint subtable_offset = 4 + 8 * cmap_tables.size; 110 foreach (CmapSubtable subtable in cmap_tables) { 111 fd.add_u16 (subtable.get_platform ()); 112 fd.add_u16 (subtable.get_encoding ()); 113 fd.add_ulong (subtable_offset); 114 subtable_offset += subtable.get_cmap_data ().length (); 115 } 116 117 foreach (CmapSubtable subtable in cmap_tables) { 118 fd.append (subtable.get_cmap_data ()); 119 } 120 121 fd.pad (); 122 123 this.font_data = fd; 124 } 125 } 126 127 /** Largest power of two less than max. */ 128 internal static uint16 largest_pow2 (uint16 max) { 129 uint16 x = 1; 130 uint16 l = 0; 131 132 while (x <= max) { 133 l = x; 134 x = x << 1; 135 } 136 137 return l; 138 } 139 140 /** Largest exponent for a power of two less than max. */ 141 internal static uint16 largest_pow2_exponent (uint16 max) { 142 uint16 exp = 0; 143 uint16 l = 0; 144 uint16 x = 0; 145 146 while (x <= max) { 147 l = exp; 148 exp++; 149 x = 1 << exp; 150 } 151 152 return l; 153 } 154 155 } 156