]> git.donarmstrong.com Git - lilypond.git/blob - lily/all-font-metrics.cc
release: 1.3.75
[lilypond.git] / lily / all-font-metrics.cc
1 /*   
2   all-font-metrics.cc --  implement All_font_metrics
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "config.h"
11 #include "main.hh"
12 #include "all-font-metrics.hh"
13 #include "debug.hh"
14 #include "warn.hh"
15 #include "afm.hh"
16 #include "tfm.hh"
17 #include "lily-guile.hh"
18 #include "scm-hash.hh"
19
20
21 #if HAVE_KPATHSEA_KPATHSEA_H
22 extern "C" {
23 #include <kpathsea/kpathsea.h>
24 }
25 #endif
26
27 const char * default_font_sz_ = "cmr10";
28
29 All_font_metrics::All_font_metrics (String path)
30 {
31   afm_p_dict_ = new Scheme_hash_table;
32   tfm_p_dict_ = new Scheme_hash_table;
33   scaled_p_dict_ = new Scheme_hash_table;
34   
35   search_path_.parse_path (path);
36 }
37
38 All_font_metrics::~All_font_metrics ()
39 {
40   scm_unprotect_object (afm_p_dict_->self_scm ());
41   scm_unprotect_object (tfm_p_dict_->self_scm ());
42   scm_unprotect_object (scaled_p_dict_->self_scm ());
43 }
44
45 Adobe_font_metric *
46 All_font_metrics::find_afm (String name)
47 {
48   SCM sname = ly_symbol2scm (name.ch_C ());
49   if (!afm_p_dict_->elem_b (sname))
50     {
51       String path;
52
53 #if KPATHSEA && HAVE_KPSE_FIND_FILE
54       if (path.empty_b ())
55         {
56           char  * p = kpse_find_file (name.ch_C(), kpse_afm_format, true);
57           if (p)
58             path = p;
59         }
60 #endif
61       
62       if (path.empty_b())
63         path = search_path_.find (name  + ".afm");
64       if (path.empty_b())
65         return 0;
66       
67       if (verbose_global_b)
68         progress_indication ("[" + path);
69       SCM  afm = read_afm_file (path);
70
71       unsmob_metrics (afm)->name_ = sname;
72
73       if (verbose_global_b)
74         progress_indication ("]");
75
76        afm_p_dict_->set (sname,afm);
77     }
78   
79   return dynamic_cast<Adobe_font_metric*> (unsmob_metrics (afm_p_dict_->get (sname)));
80 }
81
82 Scaled_font_metric * 
83 All_font_metrics::find_scaled (String nm, int m)
84 {
85   String index =  nm + "@" + to_str (m);
86   SCM sname = ly_symbol2scm (index.ch_C ());
87
88   Font_metric *fm =0;
89   if (!scaled_p_dict_->elem_b (sname))
90     {
91       Font_metric *f = find_font (nm);
92       SCM s =  Scaled_font_metric::make_scaled_font_metric (f, m);
93       scaled_p_dict_->set (sname, s);
94       fm =  unsmob_metrics (s);
95     }
96   else
97     fm = unsmob_metrics (scaled_p_dict_->get (sname));
98
99   return dynamic_cast<Scaled_font_metric*> (fm);
100 }
101
102 Tex_font_metric *
103 All_font_metrics::find_tfm (String name)
104 {
105   SCM sname = ly_symbol2scm (name.ch_C ());  
106   if (!tfm_p_dict_->elem_b (sname))
107     {
108       String path;
109       
110 //#if KPATHSEA && HAVE_KPSE_FIND_TFM  -- urg: a macro
111 #if KPATHSEA && HAVE_KPSE_FIND_FILE
112       if (path.empty_b())
113         {
114           char * p = kpse_find_tfm (name.ch_C());
115           path = p;
116         }
117 #endif
118       if (path.empty_b())
119         path = search_path_.find (name  + ".tfm");
120       if (path.empty_b())
121         return 0;
122
123       if (verbose_global_b)
124         progress_indication ("[" + path);
125       SCM tfm = Tex_font_metric::make_tfm (path);
126       if (verbose_global_b)
127         progress_indication ("]");
128
129       Font_metric *fm = unsmob_metrics (tfm);
130       fm->name_ = sname;
131       tfm_p_dict_->set (sname, tfm);
132     }
133     
134   return
135     dynamic_cast<Tex_font_metric*> (unsmob_metrics (tfm_p_dict_->get(sname)));
136 }
137
138
139 Font_metric *
140 All_font_metrics::find_font (String name)
141 {
142   Font_metric * f=0;
143   f = find_tfm (name);
144   if (f)
145     return f;
146
147   f= find_afm (name);
148   if (f)
149     return f;
150
151   warning (_f ("can't find font: `%s'", name.ch_C ()));
152   warning (_ ("Loading default font"));
153   
154   String def_name = default_font_sz_;
155   SCM l = scm_assoc (ly_str02scm ("default"),
156                      scm_eval (ly_symbol2scm ("cmr-alist")));
157   
158   if (l != SCM_BOOL_F)
159     def_name = ly_scm2string (gh_cdr (l));
160
161   f =  find_tfm (def_name);
162   if (f)
163     return f;
164
165   f= find_afm (def_name);
166   if (f)
167     return f;
168
169   error (_f ("can't find default font: `%s'", def_name.ch_C ()));
170   error (_f ("(search path: `%s')", search_path_.str ()));
171   error (_ ("Giving up"));
172
173   return 0;
174 }
175
176 SCM
177 All_font_metrics::font_descriptions () const
178 {
179   SCM l[] = {0,0,0};
180
181   l[0] = afm_p_dict_->to_alist ();
182   l[1] = tfm_p_dict_->to_alist ();
183   l[2] = scaled_p_dict_->to_alist ();  
184
185   SCM list = SCM_EOL;
186   for (int i=0; i < 3; i++)
187     {
188       for (SCM s = l[i];  gh_pair_p (s); s = gh_cdr (s))
189         {
190           Font_metric * fm = unsmob_metrics (gh_cdar (s));
191
192           list = gh_cons (fm->description (), list);
193         }
194     }
195   return list;
196 }
197
198
199
200 Font_metric*
201 find_font (String name)
202 {
203   return   all_fonts_global_p->find_font (name);
204 }