]> git.donarmstrong.com Git - lilypond.git/blob - lily/pfb.cc
Fix some bugs in the dynamic engraver and PostScript backend
[lilypond.git] / lily / pfb.cc
1 /*
2   pfb.cc -- implement pfb conversion.
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2004--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include <cstdlib>
10 #include <cstdio>
11 #include <cstring>
12 using namespace std;
13
14 #include "program-option.hh"
15 #include "source-file.hh"
16 #include "memory-stream.hh"
17 #include "open-type-font.hh"
18 #include "main.hh"
19 #include "warn.hh"
20
21 char *
22 pfb2pfa (Byte const *pfb, int length)
23 {
24   char *out = new char[1];
25   int olen = 0;
26
27   Byte const *p = pfb;
28   while (p < pfb + length)
29     {
30       if (*p++ != 128)
31         break;
32
33       Byte type = *p++;
34       if (type == 3)
35         break;
36
37       unsigned seglen
38         = p[0] | (p[1] << 8)
39         | (p[2] << 16) | (p[3] << 24);
40
41       p += 4;
42       if (type == 1)
43         {
44           out = (char *)realloc (out, olen + seglen + 1);
45           char *outp = out + olen;
46           memcpy (outp, p, seglen);
47           olen += seglen;
48           p += seglen;
49         }
50       else if (type == 2)
51         {
52           unsigned outlength = (seglen * 2) + (seglen / 32) + 2;
53
54           out = (char *)realloc (out, olen + outlength + 1);
55
56           char *outp = out + olen;
57           for (int i = seglen; i--;)
58             {
59               sprintf (outp, "%02x", *p++);
60               outp += 2;
61               if (! (i % 32))
62                 *outp++ = '\n';
63             }
64
65           olen = outp - out;
66         }
67     }
68   out[olen] = 0;
69
70   return out;
71 }
72
73 LY_DEFINE (ly_pfb_to_pfa, "ly:pfb->pfa",
74            1, 0, 0, (SCM pfb_file_name),
75            "Convert the contents of a PFB file to PFA.")
76 {
77   SCM_ASSERT_TYPE (scm_is_string (pfb_file_name), pfb_file_name,
78                    SCM_ARG1, __FUNCTION__, "string");
79
80   string file_name = ly_scm2string (pfb_file_name);
81   int len = -1;
82
83   if (be_verbose_global)
84     progress_indication ("[" + file_name);
85   
86   char *str = gulp_file (file_name, &len);
87   char *pfa = pfb2pfa ((Byte *)str, len);
88
89   SCM pfa_scm = scm_makfrom0str (pfa);
90   free (pfa);
91   delete str;
92   if (be_verbose_global)
93     progress_indication ("]");
94
95   return pfa_scm;
96 }
97
98 LY_DEFINE (ly_otf_to_cff, "ly:otf->cff",
99            1, 0, 0, (SCM otf_file_name),
100            "Convert the contents of a OTF file to CFF file, returning it as "
101            " a string.")
102 {
103   SCM_ASSERT_TYPE (scm_is_string (otf_file_name), otf_file_name,
104                    SCM_ARG1, __FUNCTION__, "string");
105
106   string file_name = ly_scm2string (otf_file_name);
107   if (be_verbose_global)
108     progress_indication ("[" + file_name);
109
110   FT_Face face = open_ft_face (file_name);
111   string table = get_otf_table (face, "CFF ");
112
113   SCM asscm = scm_from_locale_stringn ((char *) table.data (),
114                                        table.length ());
115
116   if (be_verbose_global)
117     progress_indication ("]");
118
119   return asscm;
120 }
121