2 ttf.cc -- implement ttf -> pfa routine.
4 source file of the GNU LilyPond music typesetter
6 (c) 2005 Han-Wen Nienhuys <hanwen@xs4all.nl>
10 #include "freetype.hh"
13 #include <freetype/tttables.h>
15 #include "lily-proto.hh"
16 #include "memory-stream.hh"
18 #include "lily-guile.hh"
22 print_header (void *out, FT_Face face)
24 lily_cookie_fprintf (out, "%%!PS-TrueTypeFont\n");
27 (TT_Postscript*) FT_Get_Sfnt_Table(face, ft_sfnt_post);
30 lily_cookie_fprintf (out, "%%%%VMUsage: %ld %ld\n", 0, 0);
32 lily_cookie_fprintf (out, "%d dict begin\n", 11);
33 lily_cookie_fprintf (out, "/FontName /%s def\n",
34 FT_Get_Postscript_Name (face));
36 lily_cookie_fprintf (out, "/Encoding StandardEncoding def\n");
37 lily_cookie_fprintf (out, "/PaintType 0 def\n");
38 lily_cookie_fprintf (out, "/FontMatrix [1 0 0 1 0 0] def\n");
41 (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head);
43 lily_cookie_fprintf (out, "/FontBBox [%ld %ld %ld %ld] def\n",
44 ht->xMin * 1000L / ht->Units_Per_EM,
45 ht->yMin * 1000L / ht->Units_Per_EM,
46 ht->xMax * 1000L / ht->Units_Per_EM,
47 ht->yMax * 1000L / ht->Units_Per_EM);
49 lily_cookie_fprintf (out, "/FontType 42 def\n");
50 lily_cookie_fprintf (out, "/FontInfo 8 dict dup begin\n");
51 lily_cookie_fprintf (out, "/version (%d.%d) def\n",
52 (ht->Font_Revision >> 16),
53 (ht->Font_Revision & ((1 << 16) -1)));
58 lily_cookie_fprintf (out, "/Notice (");
59 fputpss (strings[0], out);
60 lily_cookie_fprintf (out, ") def\n");
64 lily_cookie_fprintf (out, "/FullName (");
65 fputpss (strings[4], out);
66 lily_cookie_fprintf (out, ") def\n");
70 lily_cookie_fprintf (out, "/FamilyName (");
71 fputpss (strings[1], out);
72 lily_cookie_fprintf (out, ") def\n");
76 lily_cookie_fprintf (out, "/isFixedPitch %s def\n",
77 pt->isFixedPitch ? "true" : "false");
78 lily_cookie_fprintf (out, "/UnderlinePosition %ld def\n",
79 pt->underlinePosition * 1000L / ht->Units_Per_EM);
80 lily_cookie_fprintf (out, "/UnderlineThickness %ld def\n",
81 pt->underlineThickness * 1000L / ht->Units_Per_EM);
82 lily_cookie_fprintf (out, "end readonly def\n");
87 #define CHUNKSIZE 65534
90 print_body (void *out, String name)
92 FILE *fd = fopen (name.to_str0 (), "rb");
94 static char xdigits[] = "0123456789ABCDEF";
96 unsigned char *buffer;
99 buffer = new unsigned char[CHUNKSIZE];
100 lily_cookie_fprintf (out, "/sfnts [");
103 i = fread (buffer, 1, CHUNKSIZE, fd);
106 lily_cookie_fprintf (out, "\n<");
107 for (j = 0; j < i; j++)
109 if (j != 0 && j % 36 == 0)
110 lily_cookie_putc ('\n', out);
111 /* lily_cookie_fprintf (out,"%02X",(int)buffer[j]) is too slow */
112 lily_cookie_putc (xdigits[(buffer[j] & 0xF0) >> 4], out);
113 lily_cookie_putc (xdigits[buffer[j] & 0x0F], out);
115 lily_cookie_fprintf (out, "00>"); /* Adobe bug? */
119 lily_cookie_fprintf (out, "\n] def\n");
125 print_trailer (void *out,
128 const int GLYPH_NAME_LEN = 256;
129 char glyph_name[GLYPH_NAME_LEN];
132 (TT_MaxProfile *)FT_Get_Sfnt_Table(face, ft_sfnt_maxp);
134 lily_cookie_fprintf (out, "/CharStrings %d dict dup begin\n", mp->numGlyphs);
135 for (int i = 0; i < mp->numGlyphs; i++)
137 FT_Error error = FT_Get_Glyph_Name (face, i, glyph_name, GLYPH_NAME_LEN);
140 programming_error ("FT_Get_Glyph_Name() returned error");
142 lily_cookie_fprintf (out, "/%s %d def ", glyph_name, i);
145 lily_cookie_fprintf (out, "\n");
147 lily_cookie_fprintf (out, "end readonly def\n");
148 lily_cookie_fprintf (out, "FontName currentdict end definefont pop\n");
151 void print_ps_font (void *out, String name)
153 FT_Face face = open_ft_face (name);
155 print_header (out, face);
156 print_body (out, name);
157 print_trailer (out, face);
161 LY_DEFINE (ly_ttf_to_pfa, "ly:ttf->pfa",
162 1, 0, 0, (SCM ttf_file_name),
163 "Convert the contents of a TTF file to Type42 PFA, returning it as "
166 SCM_ASSERT_TYPE (scm_is_string (ttf_file_name), ttf_file_name,
167 SCM_ARG1, __FUNCTION__, "string");
169 String file_name = ly_scm2string (ttf_file_name);
170 if (be_verbose_global)
171 progress_indication ("[" + file_name);
173 Memory_out_stream stream;
175 print_ps_font (&stream, file_name);
176 SCM asscm = scm_from_locale_stringn (stream.get_string (),
177 stream.get_length ());
179 if (be_verbose_global)
180 progress_indication ("]");