1 #include "sfnt.h"
2 #include "sfnt_int.h"
3 #include "embed.h"
4 #include "config.h"
5 #include "embed_sfnt_int.h"
6 #include <assert.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 enum { WEIGHT_THIN=100,
11 WEIGHT_EXTRALIGHT=200, WEIGHT_ULTRALIGHT=200,
12 WEIGHT_LIGHT=300,
13 WEIGHT_NORMAL=400, WEIGHT_REGULAR=400,
14 WEIGHT_MEDIUM=500,
15 WEIGHT_SEMIBOLD=600, // DEMI
16 WEIGHT_BOLD=700,
17 WEIGHT_EXTRABOLD=800, WEIGHT_ULTRABOLD=800,
18 WEIGHT_BLACK=900, WEIGHT_HEAVY=900 };
19
show_post(OTF_FILE * otf)20 void show_post(OTF_FILE *otf) // {{{
21 {
22 assert(otf);
23 int len=0;
24 char *buf;
25
26 buf=otf_get_table(otf,OTF_TAG('p','o','s','t'),&len);
27 if (!buf) {
28 assert(len==-1);
29 printf("No post table\n");
30 return;
31 }
32 // TODO: check len
33 printf("POST: (%d bytes)\n"
34 " version: %08x\n"
35 " italicAngle: %d.%d\n"
36 " underlinePosition: %d\n"
37 " underlineThickness: %d\n"
38 " isFixedPitch: %d\n"
39 " vmType42: %d %d\n"
40 " vmType1: %d %d\n",len,
41 get_ULONG(buf),
42 get_LONG(buf+4)>>16,get_ULONG(buf+4)&0xffff,
43 get_SHORT(buf+8),
44 get_SHORT(buf+10),
45 get_ULONG(buf+12),
46 get_ULONG(buf+16),get_ULONG(buf+20),
47 get_ULONG(buf+24),get_ULONG(buf+38));
48 free(buf);
49 }
50 // }}}
51
show_name(OTF_FILE * otf)52 void show_name(OTF_FILE *otf) // {{{
53 {
54 assert(otf);
55 int iA,len=0;
56 char *buf;
57
58 buf=otf_get_table(otf,OTF_TAG('n','a','m','e'),&len);
59 if (!buf) {
60 assert(len==-1);
61 printf("No name table\n");
62 return;
63 }
64 printf("NAME:\n");
65 int name_count=get_USHORT(buf+2);
66 const char *nstore=buf+get_USHORT(buf+4);
67 for (iA=0;iA<name_count;iA++) {
68 const char *nrec=buf+6+12*iA;
69 printf(" { platformID/encodingID/languageID/nameID: %d/%d/%d/%d\n"
70 " length: %d, offset: %d, data :",
71 get_USHORT(nrec),
72 get_USHORT(nrec+2),
73 get_USHORT(nrec+4),
74 get_USHORT(nrec+6),
75 get_USHORT(nrec+8),
76 get_USHORT(nrec+10));
77 if ( (get_USHORT(nrec)==0)||
78 ( (get_USHORT(nrec)==3) ) ) { // WCHAR
79 int nlen=get_USHORT(nrec+8);
80 int npos=get_USHORT(nrec+10);
81 for (;nlen>0;nlen-=2,npos+=2) {
82 if (nstore[npos]!=0x00) {
83 printf("?");
84 } else {
85 printf("%c",nstore[npos+1]);
86 }
87 }
88 printf(" }\n");
89 } else {
90 printf("%.*s }\n",
91 get_USHORT(nrec+8),nstore+get_USHORT(nrec+10));
92 }
93 }
94 free(buf);
95 }
96 // }}}
97
show_cmap(OTF_FILE * otf)98 void show_cmap(OTF_FILE *otf) // {{{
99 {
100 assert(otf);
101 int iA,len=0;
102
103 char *cmap=otf_get_table(otf,OTF_TAG('c','m','a','p'),&len);
104 if (!cmap) {
105 assert(len==-1);
106 printf("No cmap table\n");
107 return;
108 }
109 printf("cmap:\n");
110 assert(get_USHORT(cmap)==0x0000); // version
111 const int numTables=get_USHORT(cmap+2);
112 printf(" numTables: %d\n",numTables);
113 for (iA=0;iA<numTables;iA++) {
114 const char *nrec=cmap+4+8*iA;
115 const char *ndata=cmap+get_ULONG(nrec+4);
116 assert(ndata>=cmap+4+8*numTables);
117 printf(" platformID/encodingID: %d/%d\n"
118 " offset: %d data (format: %d, length: %d, language: %d);\n",
119 get_USHORT(nrec),get_USHORT(nrec+2),
120 get_ULONG(nrec+4),
121 get_USHORT(ndata),get_USHORT(ndata+2),get_USHORT(ndata+4));
122 }
123 free(cmap);
124 }
125 // }}}
126
show_glyf(OTF_FILE * otf,int full)127 void show_glyf(OTF_FILE *otf,int full) // {{{
128 {
129 assert(otf);
130
131 // ensure >glyphOffsets and >gly is there
132 if ( (!otf->gly)||(!otf->glyphOffsets) ) {
133 if (otf_load_glyf(otf)!=0) {
134 assert(0);
135 return;
136 }
137 }
138
139 int iA;
140 int compGlyf=0,zeroGlyf=0;
141
142 // {{{ glyf
143 assert(otf->gly);
144 for (iA=0;iA<otf->numGlyphs;iA++) {
145 int len=otf_get_glyph(otf,iA);
146 if (len==0) {
147 zeroGlyf++;
148 } else if (get_SHORT(otf->gly)==-1) {
149 compGlyf++;
150 }
151 if (full) {
152 printf("%d(%d) ",get_SHORT(otf->gly),len);
153 }
154 }
155 if (full) {
156 printf("\n");
157 }
158 printf("numGlyf(nonnull): %d(%d), composites: %d\n",otf->numGlyphs,otf->numGlyphs-zeroGlyf,compGlyf);
159 // }}}
160 }
161 // }}}
162
show_hmtx(OTF_FILE * otf)163 void show_hmtx(OTF_FILE *otf) // {{{
164 {
165 assert(otf);
166 int iA;
167
168 otf_get_width(otf,0); // load table.
169 if (!otf->hmtx) {
170 printf("NOTE: no hmtx table!\n");
171 return;
172 }
173 printf("hmtx (%d):\n",otf->numberOfHMetrics);
174 for (iA=0;iA<otf->numberOfHMetrics;iA++) {
175 printf("(%d,%d) ",
176 get_USHORT(otf->hmtx+iA*4),
177 get_SHORT(otf->hmtx+iA*4+2));
178 }
179 printf(" (last is repeated for the remaining %d glyphs)\n",otf->numGlyphs-otf->numberOfHMetrics);
180 }
181 // }}}
182
main(int argc,char ** argv)183 int main(int argc,char **argv)
184 {
185 const char *fn=TESTFONT;
186 OTF_FILE *otf=NULL;
187 if (argc==2) {
188 fn=argv[1];
189 }
190 otf=otf_load(fn);
191 if (!otf)
192 {
193 printf("Font %s was not loaded, exiting.\n", TESTFONT);
194 return 1;
195 }
196
197 assert(otf);
198 if (otf->numTTC) {
199 printf("TTC has %d fonts, using %d\n",otf->numTTC,otf->useTTC);
200 }
201 if (otf->version==0x00010000) {
202 printf("Got TTF 1.0\n");
203 } else if (otf->version==OTF_TAG('O','T','T','O')) {
204 printf("Got OTF(CFF)\n");
205 } else if (otf->version==OTF_TAG('t','r','u','e')) {
206 printf("Got TTF (true)\n");
207 } else if (otf->version==OTF_TAG('t','y','p','1')) {
208 printf("Got SFNT(Type1)\n");
209 }
210
211 printf("Has %d tables\n",otf->numTables);
212
213 int iA;
214 for (iA=0;iA<otf->numTables;iA++) {
215 printf("%c%c%c%c %d @%d\n",OTF_UNTAG(otf->tables[iA].tag),otf->tables[iA].length,otf->tables[iA].offset);
216 }
217 printf("unitsPerEm: %d, indexToLocFormat: %d\n",
218 otf->unitsPerEm,otf->indexToLocFormat);
219 printf("num glyphs: %d\n",otf->numGlyphs);
220 otf_get_width(otf,0); // load table.
221 printf("numberOfHMetrics: %d\n",otf->numberOfHMetrics);
222
223 printf("Embedding rights: %x\n",emb_otf_get_rights(otf));
224
225 show_post(otf);
226
227 show_name(otf);
228
229 show_cmap(otf);
230 // printf("%d %d\n",otf_from_unicode(otf,'A'),0);
231
232 if (!(otf->flags&OTF_F_FMT_CFF)) {
233 show_glyf(otf,1);
234 }
235
236 show_hmtx(otf);
237
238 otf_close(otf);
239
240 return 0;
241 }
242