2 ttf.cc -- implement ttf -> pfa routine.
4 source file of the GNU LilyPond music typesetter
6 (c) 2005--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
11 #include <freetype/tttables.h>
13 #include "lily-proto.hh"
14 #include "memory-stream.hh"
16 #include "lily-guile.hh"
20 Based on ttfps by Juliusz Chroboczek
23 print_header (void *out, FT_Face face)
25 lily_cookie_fprintf (out, "%%!PS-TrueTypeFont\n");
28 = (TT_Postscript *) FT_Get_Sfnt_Table (face, ft_sfnt_post);
31 lily_cookie_fprintf (out, "%%%%VMUsage: %ld %ld\n", 0, 0);
33 lily_cookie_fprintf (out, "%d dict begin\n", 11);
34 lily_cookie_fprintf (out, "/FontName /%s def\n",
35 FT_Get_Postscript_Name (face));
37 lily_cookie_fprintf (out, "/Encoding StandardEncoding def\n");
38 lily_cookie_fprintf (out, "/PaintType 0 def\n");
39 lily_cookie_fprintf (out, "/FontMatrix [1 0 0 1 0 0] def\n");
42 = (TT_Header *)FT_Get_Sfnt_Table (face, ft_sfnt_head);
44 lily_cookie_fprintf (out, "/FontBBox [%ld %ld %ld %ld] def\n",
45 ht->xMin *1000L / ht->Units_Per_EM,
46 ht->yMin *1000L / ht->Units_Per_EM,
47 ht->xMax *1000L / ht->Units_Per_EM,
48 ht->yMax *1000L / ht->Units_Per_EM);
50 lily_cookie_fprintf (out, "/FontType 42 def\n");
51 lily_cookie_fprintf (out, "/FontInfo 8 dict dup begin\n");
52 lily_cookie_fprintf (out, "/version (%d.%d) def\n",
53 (ht->Font_Revision >> 16),
54 (ht->Font_Revision &((1 << 16) -1)));
59 lily_cookie_fprintf (out, "/Notice (");
60 fputpss (strings[0], out);
61 lily_cookie_fprintf (out, ") def\n");
65 lily_cookie_fprintf (out, "/FullName (");
66 fputpss (strings[4], out);
67 lily_cookie_fprintf (out, ") def\n");
71 lily_cookie_fprintf (out, "/FamilyName (");
72 fputpss (strings[1], out);
73 lily_cookie_fprintf (out, ") def\n");
77 lily_cookie_fprintf (out, "/isFixedPitch %s def\n",
78 pt->isFixedPitch ? "true" : "false");
79 lily_cookie_fprintf (out, "/UnderlinePosition %ld def\n",
80 pt->underlinePosition *1000L / ht->Units_Per_EM);
81 lily_cookie_fprintf (out, "/UnderlineThickness %ld def\n",
82 pt->underlineThickness *1000L / ht->Units_Per_EM);
83 lily_cookie_fprintf (out, "end readonly def\n");
86 #define CHUNKSIZE 65534
89 print_body (void *out, String name)
91 FILE *fd = fopen (name.to_str0 (), "rb");
93 static char xdigits[] = "0123456789ABCDEF";
95 unsigned char *buffer;
98 buffer = new unsigned char[CHUNKSIZE];
99 lily_cookie_fprintf (out, "/sfnts [");
102 i = fread (buffer, 1, CHUNKSIZE, fd);
105 lily_cookie_fprintf (out, "\n<");
106 for (j = 0; j < i; j++)
108 if (j != 0 && j % 36 == 0)
109 lily_cookie_putc ('\n', out);
110 /* lily_cookie_fprintf (out,"%02X",(int)buffer[j]) is too slow */
111 lily_cookie_putc (xdigits[ (buffer[j] & 0xF0) >> 4], out);
112 lily_cookie_putc (xdigits[buffer[j] & 0x0F], out);
114 lily_cookie_fprintf (out, "00>"); /* Adobe bug? */
118 lily_cookie_fprintf (out, "\n] def\n");
124 print_trailer (void *out,
127 const int GLYPH_NAME_LEN = 256;
128 char glyph_name[GLYPH_NAME_LEN];
131 = (TT_MaxProfile *)FT_Get_Sfnt_Table (face, ft_sfnt_maxp);
133 lily_cookie_fprintf (out, "/CharStrings %d dict dup begin\n", mp->numGlyphs);
136 if (face->face_flags & FT_FACE_FLAG_GLYPH_NAMES)
137 for (int i = 0; i < mp->numGlyphs; i++)
139 FT_Error error = FT_Get_Glyph_Name (face, i, glyph_name,
142 programming_error ("print_trailer(): FT_Get_Glyph_Name() returned error");
144 lily_cookie_fprintf (out, "/%s %d def ", glyph_name, i);
147 lily_cookie_fprintf (out, "\n");
150 lily_cookie_fprintf (out, "end readonly def\n");
151 lily_cookie_fprintf (out, "FontName currentdict end definefont pop\n");
155 create_type42_font (void *out, String name)
157 FT_Face face = open_ft_face (name);
159 print_header (out, face);
160 print_body (out, name);
161 print_trailer (out, face);
166 LY_DEFINE (ly_font_glyph_list, "ly:font-glyph-list",
167 1, 0, 0, (SCM font_file_name),
168 "Return a list of glyphnames for @var{font-file-name}.")
170 SCM_ASSERT_TYPE (scm_is_string (font_file_name), font_file_name,
171 SCM_ARG1, __FUNCTION__, "string");
173 String file_name = ly_scm2string (font_file_name);
174 if (be_verbose_global)
175 progress_indication ("[" + file_name);
177 SCM retval = SCM_EOL;
180 FT_Face face = open_ft_face (file_name);
181 for (int i = 0; i < face->num_glyphs; i++)
185 int code = FT_Get_Glyph_Name (face, i, name, len);
187 warning (_f ("FT_Get_Glyph_Name() returned error: %d", code));
189 *tail = scm_cons (scm_makfrom0str (name), SCM_EOL);
190 tail = SCM_CDRLOC (*tail);
197 LY_DEFINE (ly_ttf_ps_name, "ly:ttf-ps-name",
198 1, 0, 0, (SCM ttf_file_name),
199 "Extract the PostScript name from a TrueType font.")
201 SCM_ASSERT_TYPE (scm_is_string (ttf_file_name), ttf_file_name,
202 SCM_ARG1, __FUNCTION__, "string");
203 String file_name = ly_scm2string (ttf_file_name);
204 if (be_verbose_global)
205 progress_indication ("[" + file_name);
207 FT_Face face = open_ft_face (file_name);
208 char const *ps_name_str0 = FT_Get_Postscript_Name (face);
210 if (be_verbose_global)
211 progress_indication ("]");
214 return scm_makfrom0str (ps_name_str0 ? ps_name_str0 : "");
219 LY_DEFINE (ly_ttf_to_pfa, "ly:ttf->pfa",
220 1, 0, 0, (SCM ttf_file_name),
221 "Convert the contents of a TTF file to Type42 PFA, returning it as "
224 SCM_ASSERT_TYPE (scm_is_string (ttf_file_name), ttf_file_name,
225 SCM_ARG1, __FUNCTION__, "string");
227 String file_name = ly_scm2string (ttf_file_name);
228 if (be_verbose_global)
229 progress_indication ("[" + file_name);
231 Memory_out_stream stream;
233 create_type42_font (&stream, file_name);
234 SCM asscm = scm_from_locale_stringn (stream.get_string (),
235 stream.get_length ());
237 if (be_verbose_global)
238 progress_indication ("]");