2 * Copyright © 2007,2008,2009 Red Hat, Inc.
4 * This is part of HarfBuzz, a text shaping library.
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24 * Red Hat Author(s): Behdad Esfahbod
27 #include "hb-mutex-private.hh"
28 #include "hb-open-file-private.hh"
29 #include "hb-ot-layout-gdef-table.hh"
30 #include "hb-ot-layout-gsubgpos-private.hh"
43 main (int argc
, char **argv
)
46 fprintf (stderr
, "usage: %s font-file.ttf\n", argv
[0]);
50 const char *font_data
= NULL
;
54 GMappedFile
*mf
= g_mapped_file_new (argv
[1], false, NULL
);
55 font_data
= g_mapped_file_get_contents (mf
);
56 len
= g_mapped_file_get_length (mf
);
58 FILE *f
= fopen (argv
[1], "rb");
59 fseek (f
, 0, SEEK_END
);
61 fseek (f
, 0, SEEK_SET
);
62 font_data
= (const char *) malloc (len
);
63 len
= fread ((char *) font_data
, 1, len
, f
);
66 printf ("Opened font file %s: %d bytes long\n", argv
[1], len
);
68 const OpenTypeFontFile
&ot
= *CastP
<OpenTypeFontFile
> (font_data
);
70 switch (ot
.get_tag ()) {
71 case OpenTypeFontFile::TrueTypeTag
:
72 printf ("OpenType font with TrueType outlines\n");
74 case OpenTypeFontFile::CFFTag
:
75 printf ("OpenType font with CFF (Type1) outlines\n");
77 case OpenTypeFontFile::TTCTag
:
78 printf ("TrueType Collection of OpenType fonts\n");
80 case OpenTypeFontFile::TrueTag
:
81 printf ("Obsolete Apple TrueType font\n");
83 case OpenTypeFontFile::Typ1Tag
:
84 printf ("Obsolete Apple Type1 font in SFNT container\n");
87 printf ("Unknown font format\n");
91 int num_fonts
= ot
.get_face_count ();
92 printf ("%d font(s) found in file\n", num_fonts
);
93 for (int n_font
= 0; n_font
< num_fonts
; n_font
++) {
94 const OpenTypeFontFace
&font
= ot
.get_face (n_font
);
95 printf ("Font %d of %d:\n", n_font
, num_fonts
);
97 int num_tables
= font
.get_table_count ();
98 printf (" %d table(s) found in font\n", num_tables
);
99 for (int n_table
= 0; n_table
< num_tables
; n_table
++) {
100 const OpenTypeTable
&table
= font
.get_table (n_table
);
101 printf (" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table
, num_tables
,
102 (const char *)table
.tag
,
103 (unsigned int) table
.offset
,
104 (unsigned int) table
.length
);
108 case GSUBGPOS::GSUBTag
:
109 case GSUBGPOS::GPOSTag
:
112 const GSUBGPOS
&g
= *CastP
<GSUBGPOS
> (font_data
+ table
.offset
);
114 int num_scripts
= g
.get_script_count ();
115 printf (" %d script(s) found in table\n", num_scripts
);
116 for (int n_script
= 0; n_script
< num_scripts
; n_script
++) {
117 const Script
&script
= g
.get_script (n_script
);
118 printf (" Script %2d of %2d: %.4s\n", n_script
, num_scripts
,
119 (const char *)g
.get_script_tag(n_script
));
121 if (!script
.has_default_lang_sys())
122 printf (" No default language system\n");
123 int num_langsys
= script
.get_lang_sys_count ();
124 printf (" %d language system(s) found in script\n", num_langsys
);
125 for (int n_langsys
= script
.has_default_lang_sys() ? -1 : 0; n_langsys
< num_langsys
; n_langsys
++) {
126 const LangSys
&langsys
= n_langsys
== -1
127 ? script
.get_default_lang_sys ()
128 : script
.get_lang_sys (n_langsys
);
130 printf (" Default Language System\n");
132 printf (" Language System %2d of %2d: %.4s\n", n_langsys
, num_langsys
,
133 (const char *)script
.get_lang_sys_tag (n_langsys
));
134 if (!langsys
.has_required_feature ())
135 printf (" No required feature\n");
137 printf (" Required feature index: %d\n",
138 langsys
.get_required_feature_index ());
140 int num_features
= langsys
.get_feature_count ();
141 printf (" %d feature(s) found in language system\n", num_features
);
142 for (int n_feature
= 0; n_feature
< num_features
; n_feature
++) {
143 printf (" Feature index %2d of %2d: %d\n", n_feature
, num_features
,
144 langsys
.get_feature_index (n_feature
));
149 int num_features
= g
.get_feature_count ();
150 printf (" %d feature(s) found in table\n", num_features
);
151 for (int n_feature
= 0; n_feature
< num_features
; n_feature
++) {
152 const Feature
&feature
= g
.get_feature (n_feature
);
153 int num_lookups
= feature
.get_lookup_count ();
154 printf (" Feature %2d of %2d: %c%c%c%c\n", n_feature
, num_features
,
155 HB_UNTAG(g
.get_feature_tag(n_feature
)));
157 printf (" %d lookup(s) found in feature\n", num_lookups
);
158 for (int n_lookup
= 0; n_lookup
< num_lookups
; n_lookup
++) {
159 printf (" Lookup index %2d of %2d: %d\n", n_lookup
, num_lookups
,
160 feature
.get_lookup_index (n_lookup
));
164 int num_lookups
= g
.get_lookup_count ();
165 printf (" %d lookup(s) found in table\n", num_lookups
);
166 for (int n_lookup
= 0; n_lookup
< num_lookups
; n_lookup
++) {
167 const Lookup
&lookup
= g
.get_lookup (n_lookup
);
168 printf (" Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup
, num_lookups
,
169 lookup
.get_type(), lookup
.get_props());
178 const GDEF
&gdef
= *CastP
<GDEF
> (font_data
+ table
.offset
);
180 printf (" Has %sglyph classes\n",
181 gdef
.has_glyph_classes () ? "" : "no ");
182 printf (" Has %smark attachment types\n",
183 gdef
.has_mark_attachment_types () ? "" : "no ");
184 printf (" Has %sattach points\n",
185 gdef
.has_attach_points () ? "" : "no ");
186 printf (" Has %slig carets\n",
187 gdef
.has_lig_carets () ? "" : "no ");
188 printf (" Has %smark sets\n",
189 gdef
.has_mark_sets () ? "" : "no ");