]> git.donarmstrong.com Git - lilypond.git/blob - lily/afm-reader.cc
release: 1.3.19
[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--2000 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.size ())
51         continue;
52       if (b[0] == "C")
53         char_metric.C_ = b[1].value_i ();
54       else if (b[0] == "WX")
55         char_metric.WX_ = b[1].value_f ();
56       else if (b[0] == "N")
57         char_metric.N_ = strip_leading_white (b[1]);
58       else if (b[0] == "B")
59         char_metric.B_ = parse_box (b.slice (1, b.size()));
60     }
61   return char_metric;
62 }
63
64 void
65 Adobe_font_metric::read_char_metrics (Data_file &input, int size)
66 {
67   while (!input.eof_b ())
68     {
69       input.gobble_leading_white ();
70       String s= input.get_line ();
71       if (s == "EndCharMetrics")
72         return ;
73       Adobe_font_char_metric afm_char =read_char_metric (s, size);
74       char_metrics_.push (afm_char);
75       int i = char_metrics_.size ()-1;
76
77       // TFM files uses neg.  charcodes to store Space
78       if (afm_char.C_ >= 0)
79         ascii_to_metric_idx_ [afm_char.C_] = i;
80       name_to_metric_dict_ [afm_char.N_] = i;
81     }
82 }
83
84 #define READSTRING(k)  if (key == #k) { \
85   afm->k ## _ = input.get_line (); continue; }
86 #define READBOX(b) if (key == #b) { \
87   afm->b ## _ = read_box (input); continue; }
88 #define READREAL(r) if (key == #r) { \
89   afm->r ## _ = read_real (input); continue; }
90
91 Real
92 read_real(Data_file &d)
93 {
94   String s = d.get_word ();
95   d.gobble_white ();
96   return s.value_f ();
97 }
98
99
100 Box
101 read_box ( Data_file &d)
102 {
103   Box b;
104   b[X_AXIS][SMALLER] = read_real (d);  
105   b[Y_AXIS][SMALLER] = read_real (d);
106   b[X_AXIS][BIGGER] = read_real (d);
107   b[Y_AXIS][BIGGER] = read_real (d);
108   return b;
109 }
110
111 Adobe_font_metric *
112 read_afm_file (String fn)
113 {
114   Data_file input (fn);
115
116   assert (!input.eof_b ());
117   
118   int i = fn.index_i(".afm");
119   for (; i>0 && isdigit(fn[--i]); )
120     {}
121   int font_size = String_convert::dec2_i(fn.cut_str(i+1,INT_MAX));
122
123   Adobe_font_metric *afm = new Adobe_font_metric;
124   for (i=0; i < 256; i++)
125     {
126       afm->ascii_to_metric_idx_.push (-1);
127     }
128
129   while (!input.eof_b ())
130     {
131       input.gobble_leading_white ();
132       String w = input.get_word ();
133       if (w == "StartFontMetrics")
134         break;
135       input.get_line ();
136     }
137   
138   while (!input.eof_b ())
139     {
140       input.gobble_leading_white ();
141       String key = input.get_word ();
142       if (key == "Comment")
143         continue;
144
145       READSTRING(FontName);
146       READSTRING(FullName);
147       READSTRING(FamilyName);
148       READSTRING(Weight);
149       READSTRING(Version);
150       READSTRING(Notice);
151       READSTRING(EncodingScheme);
152       READREAL(ItalicAngle);
153       READREAL(UnderlineThickness);
154       READREAL(UnderlinePosition);
155       READBOX(FontBBox);
156       if (key == "StartCharMetrics")
157         {
158           input.get_line ();
159           afm->read_char_metrics (input, font_size);
160         }
161       if (key == "EndFontMetrics")
162         break;
163
164     }
165
166   /*
167     read to EOF
168   */
169   input.gulp ();
170  
171   return afm;
172 }
173
174