1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3 
4   Copyright (C) 2004--2021 Han-Wen Nienhuys <hanwen@xs4all.nl>
5 
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10 
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15 
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "international.hh"
21 #include "program-option.hh"
22 #include "source-file.hh"
23 #include "open-type-font.hh"
24 #include "warn.hh"
25 
26 #include <cstdio>
27 #include <cstdlib>
28 #include <cstring>
29 #include <iomanip>
30 #include <sstream>
31 
32 using std::string;
33 using std::stringstream;
34 using std::vector;
35 
36 string
pfb2pfa(const string & pfb)37 pfb2pfa (const string &pfb)
38 {
39   string out;
40 
41   string::const_iterator p = pfb.begin ();
42   while (p < pfb.end ())
43     {
44       if (static_cast<Byte> (*p++) != 128)
45         {
46           error (_ ("Segment header of the Type 1 (PFB) font is broken."));
47           break;
48         }
49 
50       Byte type = static_cast<Byte> (*p++);
51       if (type == 3)
52         break;
53 
54       size_t seglen = static_cast<Byte> (*p++);
55       seglen |= (static_cast<Byte> (*p++) << 8);
56       seglen |= (static_cast<Byte> (*p++) << 16);
57       seglen |= (static_cast<Byte> (*p++) << 24);
58       if ((p + seglen) > pfb.end ())
59         {
60           error (_ ("Segment length of the Type 1 (PFB) font is too long."));
61           break;
62         }
63 
64       if (type == 1)
65         {
66           copy (p, p + seglen, back_inserter (out));
67           p += seglen;
68         }
69       else if (type == 2)
70         {
71           stringstream ss;
72 
73           ss << std::hex << std::setfill ('0');
74 
75           for (size_t i = seglen; i > 0; --i)
76             {
77               ss << std::setw (2) << static_cast<int> (static_cast<Byte> (*p++));
78               if (! (i % 32))
79                 ss << '\n';
80             }
81 
82           string str = ss.str ();
83           copy (str.begin (), str.end (), back_inserter (out));
84         }
85       else
86         {
87           error (_ ("Segment type of the Type 1 (PFB) font is unknown."));
88           break;
89         }
90     }
91 
92   return out;
93 }
94