]> git.donarmstrong.com Git - lilypond.git/blob - lily/afm-reader.cc
ce69ff0c9b17a25a5988938d4bcedf8cd1d7ba3d
[lilypond.git] / lily / afm-reader.cc
1 /*   
2   afm-reader.cc --  implement Adobe_font_metric_file
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "direction.hh"
11 #include "afm.hh"
12 #include "data-file.hh"
13 #include "string-convert.hh"
14 #include <ctype.h>
15
16
17 Box
18 parse_box (Array<String> a)
19 {
20   Box b;
21   int i=0;
22   b[X_AXIS][SMALLER] = a[i++].value_f ();  
23   b[Y_AXIS][SMALLER] = a[i++].value_f ();
24   b[X_AXIS][BIGGER] = a[i++].value_f ();
25   b[Y_AXIS][BIGGER] = a[i++].value_f ();
26   return b;
27 }
28
29 String
30 strip_leading_white (String c)
31 {
32   int i=0;
33   while (isspace(c[i]))
34     i++;
35   c = c.cut_str (i, INT_MAX);
36   return c;
37 }
38
39 Adobe_font_char_metric
40 read_char_metric (String s, int size)
41 {
42   Adobe_font_char_metric char_metric;
43   char_metric.size_ = size;
44   Array<String> a= String_convert::split_arr (s, ';');
45   for (int i=0; i < a.size (); i++)
46     {
47       String c = strip_leading_white (a[i]);
48
49       Array<String> b = String_convert::split_arr (c, ' ');
50       if (b[0] == "C")
51         char_metric.C_ = b[1].value_i ();
52       else if (b[0] == "WX")
53         char_metric.WX_ = b[1].value_f ();
54       else if (b[0] == "N")
55         char_metric.N_ = strip_leading_white (b[1]);
56       else if (b[0] == "B")
57         char_metric.B_ = parse_box (b.slice (1, b.size()));
58     }
59   return char_metric;
60 }
61
62 void
63 Adobe_font_metric::read_char_metrics (Data_file &input, int size)
64 {
65   while (!input.eof_b ())
66     {
67       input.gobble_leading_white ();
68       String s= input.get_line ();
69       if (s == "EndCharMetrics")
70         return ;
71       Adobe_font_char_metric afm_char =read_char_metric (s, size);
72       char_metrics_.push (afm_char);
73       int i = char_metrics_.size ()-1;
74       ascii_to_metric_idx_ [afm_char.C_] = i;
75       name_to_metric_dict_ [afm_char.N_] = i;
76     }
77 }
78
79 #define READSTRING(k)  if (key == #k) { \
80   afm.k ## _ = input.get_line (); continue; }
81 #define READBOX(b) if (key == #b) { \
82   afm.b ## _ = read_box (input); continue; }
83 #define READREAL(r) if (key == #r) { \
84   afm.r ## _ = read_real (input); continue; }
85
86 Real
87 read_real(Data_file &d)
88 {
89   String s = d.get_word ();
90   d.gobble_white ();
91   return s.value_f ();
92 }
93
94
95 Box
96 read_box ( Data_file &d)
97 {
98   Box b;
99   b[X_AXIS][SMALLER] = read_real (d);  
100   b[Y_AXIS][SMALLER] = read_real (d);
101   b[X_AXIS][BIGGER] = read_real (d);
102   b[Y_AXIS][BIGGER] = read_real (d);
103   return b;
104 }
105
106 Adobe_font_metric
107 read_afm_file (String fn)
108 {
109   Data_file input (fn);
110
111   assert (!input.eof_b ());
112   
113   int i = fn.index_i(".afm");
114   for (; i>0 && isdigit(fn[--i]); )
115     {}
116   int font_size = String_convert::dec2_i(fn.cut_str(i+1,INT_MAX));
117
118   Adobe_font_metric afm;
119
120   for (i=0; i < 256; i++)
121     {
122       afm.ascii_to_metric_idx_.push (-1);
123     }
124
125   while (!input.eof_b ())
126     {
127       input.gobble_leading_white ();
128       String w = input.get_word ();
129       if (w == "StartFontMetrics")
130         break;
131       input.get_line ();
132     }
133   
134   while (!input.eof_b ())
135     {
136       input.gobble_leading_white ();
137       String key = input.get_word ();
138       if (key == "Comment")
139         continue;
140
141       READSTRING(FontName);
142       READSTRING(FullName);
143       READSTRING(FamilyName);
144       READSTRING(Weight);
145       READSTRING(Version);
146       READSTRING(Notice);
147       READSTRING(EncodingScheme);
148       READREAL(ItalicAngle);
149       READREAL(UnderlineThickness);
150       READREAL(UnderlinePosition);
151       READBOX(FontBBox);
152       if (key == "StartCharMetrics")
153         {
154           input.get_line ();
155           afm.read_char_metrics (input, font_size);
156         }
157       if (key == "EndFontMetrics")
158         break;
159
160     }
161
162   /*
163     read to EOF
164   */
165   input.gulp ();
166  
167   return afm;
168 }
169
170