lilypond-1.3.7
[lilypond.git] / lily / afm-reader.cc
blob7663aab22b392f0902ad1ca7041eb9df1f7eba80
1 /*
2 afm-reader.cc -- implement Adobe_font_metric_file
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 */
10 #include "direction.hh"
11 #include "afm.hh"
12 #include "data-file.hh"
13 #include "string-convert.hh"
14 #include <ctype.h>
17 Box
18 parse_box (Array<String> a)
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;
29 String
30 strip_leading_white (String c)
32 int i=0;
33 while (isspace(c[i]))
34 i++;
35 c = c.cut_str (i, INT_MAX);
36 return c;
39 Adobe_font_char_metric
40 read_char_metric (String s, int size)
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++)
47 String c = strip_leading_white (a[i]);
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()));
61 return char_metric;
64 void
65 Adobe_font_metric::read_char_metrics (Data_file &input, int size)
67 while (!input.eof_b ())
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;
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;
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; }
91 Real
92 read_real(Data_file &d)
94 String s = d.get_word ();
95 d.gobble_white ();
96 return s.value_f ();
101 read_box ( Data_file &d)
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;
111 Adobe_font_metric
112 read_afm_file (String fn)
114 Data_file input (fn);
116 assert (!input.eof_b ());
118 int i = fn.index_i(".afm");
119 for (; i>0 && isdigit(fn[--i]); )
121 int font_size = String_convert::dec2_i(fn.cut_str(i+1,INT_MAX));
123 Adobe_font_metric afm;
125 for (i=0; i < 256; i++)
127 afm.ascii_to_metric_idx_.push (-1);
130 while (!input.eof_b ())
132 input.gobble_leading_white ();
133 String w = input.get_word ();
134 if (w == "StartFontMetrics")
135 break;
136 input.get_line ();
139 while (!input.eof_b ())
141 input.gobble_leading_white ();
142 String key = input.get_word ();
143 if (key == "Comment")
144 continue;
146 READSTRING(FontName);
147 READSTRING(FullName);
148 READSTRING(FamilyName);
149 READSTRING(Weight);
150 READSTRING(Version);
151 READSTRING(Notice);
152 READSTRING(EncodingScheme);
153 READREAL(ItalicAngle);
154 READREAL(UnderlineThickness);
155 READREAL(UnderlinePosition);
156 READBOX(FontBBox);
157 if (key == "StartCharMetrics")
159 input.get_line ();
160 afm.read_char_metrics (input, font_size);
162 if (key == "EndFontMetrics")
163 break;
168 read to EOF
170 input.gulp ();
172 return afm;