]> git.donarmstrong.com Git - lilypond.git/blob - lily/afm.cc
($(outdir)/%.pdf): add DVIPS_FLAGS. This will
[lilypond.git] / lily / afm.cc
1 /*   
2   afm.cc --  implement Adobe_font_metric
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include <string.h>
11
12 #include "warn.hh"              // error()
13 #include "libc-extension.hh"
14 #include "afm.hh"
15 #include "stencil.hh"
16 #include "dimensions.hh"
17
18 Adobe_font_metric::Adobe_font_metric (AFM_Font_info * fi)
19 {
20   checksum_ = 0;
21   font_inf_ = fi;
22
23   for (int i= 256  >? fi->numOfChars; i--;)
24     ascii_to_metric_idx_.push (-1);
25   
26   for (int i=0; i < fi->numOfChars; i++)
27     {
28       AFM_CharMetricInfo * c = fi->cmi + i;
29
30       /*
31         Some TeX afm files contain code = -1. We don't know why, let's
32         ignore it.
33         
34        */
35       if (c->code >= 0)
36         ascii_to_metric_idx_[c->code] = i;
37       name_to_metric_dict_[c->name] = i;
38     }
39 }
40
41
42 SCM
43 Adobe_font_metric::make_afm (AFM_Font_info *fi, unsigned int checksum)
44 {
45   Adobe_font_metric * fm = new Adobe_font_metric (fi);
46   fm->checksum_ = checksum;
47   return fm->self_scm ();    
48 }
49
50
51 AFM_CharMetricInfo const *
52 Adobe_font_metric::find_ascii_metric (int a) const
53 {
54   if (ascii_to_metric_idx_[a] >=0)
55     {
56       int code = ascii_to_metric_idx_[a];
57       if (code>=0)
58         {
59           return font_inf_->cmi + code;
60         }
61     }
62
63   return 0;
64 }
65
66
67
68 AFM_CharMetricInfo const *
69 Adobe_font_metric::find_char_metric (String nm) const
70 {
71   int idx = name_to_index (nm);
72   if (idx >= 0)
73     return font_inf_->cmi+ idx;
74   else
75     return 0;
76 }
77
78 int
79 Adobe_font_metric::name_to_index (String nm)const 
80 {
81   std::map<String,int>::const_iterator ai = name_to_metric_dict_.find (nm);
82   
83   if (ai == name_to_metric_dict_.end ())
84     return -1;
85   else
86     return (*ai).second; 
87 }
88
89 int
90 Adobe_font_metric::count () const
91 {
92   return font_inf_->numOfChars ;
93 }
94
95 Box
96 Adobe_font_metric::get_ascii_char (int code) const
97 {
98   AFM_CharMetricInfo const
99     * c =  find_ascii_metric (code);
100   Box b (Interval (0,0),Interval (0,0));
101   if (c)
102     b = afm_bbox_to_box (c->charBBox);                  
103
104   return b;
105 }
106
107
108 Box
109 Adobe_font_metric::get_indexed_char (int code) const
110 {
111   if (code>= 0)
112     return afm_bbox_to_box (font_inf_->cmi[code].charBBox);
113   else
114     return   Box (Interval (0,0),Interval (0,0));
115 }
116
117 SCM
118 read_afm_file (String nm)
119 {
120   FILE *f = fopen (nm.to_str0 () , "r");
121   char s[2048];
122   char *check_key = "Comment TfmCheckSum";
123
124   unsigned int cs = 0;
125
126   s[0] = 0;
127   /* Assume check_key in first 10 lines */
128   for (int i = 0; i < 10; i++)
129     {
130       fgets (s, sizeof (s), f);
131       if (strncmp (s, check_key, strlen (check_key)) == 0)
132         {
133           sscanf (s + strlen (check_key), "%ud", &cs);
134           break;
135         }
136     }
137   
138   rewind (f);
139     
140   AFM_Font_info * fi;
141   int ok = AFM_parseFile (f, &fi, ~1);
142
143   if (ok)
144     {
145       error (_f ("Error parsing AFM file: `%s'", nm.to_str0 ()));
146       exit (2);
147     }
148   fclose (f);
149
150   return Adobe_font_metric::make_afm (fi, cs);
151 }
152
153
154 /*
155   actually, AFMs will be printers point, usually, but our .py script dumps
156   real points.
157  */
158 Box
159 afm_bbox_to_box (AFM_BBox bb)
160 {
161   return Box (Interval (bb.llx, bb.urx)* (1/1000.0) PT,
162               Interval (bb.lly, bb.ury)* (1/1000.0) PT);
163
164 }
165
166 Offset
167 Adobe_font_metric::get_indexed_wxwy (int k)const
168 {
169   AFM_CharMetricInfo const *mi = font_inf_->cmi+ k;
170   return 1/1000.0 PT * Offset (mi->wx, mi->wy); 
171 }
172
173
174
175 Adobe_font_metric::~Adobe_font_metric ()
176 {
177   AFM_free (font_inf_);
178 }
179
180 /*
181   return a stencil, without fontification 
182  */
183 Stencil
184 Adobe_font_metric::find_by_name (String s) const
185 {
186   AFM_CharMetricInfo const *cm = find_char_metric (s);
187
188   if (!cm)
189     {
190       /*
191         Why don't we return empty?
192        */
193       
194       Stencil m;
195       m.set_empty (false);
196       return m;
197     }
198   
199   SCM at = (scm_list_n (ly_symbol2scm ("char"),
200                       scm_int2num (cm->code),
201                       SCM_UNDEFINED));
202   
203   //  at= fontify_atom ((Font_metric*)this, at);
204   Box b = afm_bbox_to_box (cm->charBBox);
205
206   return Stencil (b, at);
207 }