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