]> git.donarmstrong.com Git - lilypond.git/blob - lily/virtual-font-metric.cc
* Documentation/user/tutorial.itely: Revised (continued).
[lilypond.git] / lily / virtual-font-metric.cc
1 /*   
2   virtual-font-metric.cc --  implement Virtual_font_metric
3
4 source file of the GNU LilyPond music typesetter
5
6 (c) 2002--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
8  */
9
10 #include "warn.hh"
11 #include "virtual-font-metric.hh"
12 #include "all-font-metrics.hh"
13 #include "stencil.hh"
14 #include "paper-def.hh"
15
16
17 /*
18   passing DEF is ughish. Should move into paperdef?
19   */
20 Virtual_font_metric::Virtual_font_metric (SCM font_list)
21 {
22   font_list_ = SCM_EOL;
23   SCM *tail = &font_list_;
24
25   SCM mag = SCM_EOL;
26   SCM name_list = SCM_EOL;
27   SCM *name_tail = &name_list;
28   
29   for (SCM s = font_list; gh_pair_p (s); s = gh_cdr (s))
30     {
31       if (Font_metric*fm = unsmob_metrics (gh_car (s)))
32         {
33           *tail =  scm_cons (gh_car (s),SCM_EOL);
34           tail = SCM_CDRLOC (*tail);
35
36           if (!gh_number_p (mag))
37             {
38               mag = gh_cdr (fm->description_); // ugh.
39             }
40
41           *name_tail = scm_cons (gh_car (fm->description_), SCM_EOL);
42           name_tail = SCM_CDRLOC (*name_tail);
43         }
44     }
45
46   description_ = scm_cons (name_list, mag);
47 }
48
49 Real 
50 Virtual_font_metric::design_size () const
51 {
52   return unsmob_metrics (gh_car (font_list_))-> design_size ();
53 }
54
55
56 void
57 Virtual_font_metric::derived_mark ()const
58 {
59   scm_gc_mark (font_list_);
60 }
61
62 int
63 Virtual_font_metric::count () const
64 {
65   int k = 0;
66   for (SCM s = font_list_; gh_pair_p (s); s = gh_cdr (s))
67     {
68       k+= unsmob_metrics (gh_car (s))->count ();
69     }
70
71   return k;
72 }
73
74 Stencil
75 Virtual_font_metric::find_by_name (String glyph) const
76 {
77   Stencil m;  
78   for (SCM s = font_list_; m.is_empty () && gh_pair_p (s); s = gh_cdr (s))
79     {
80       m = unsmob_metrics (gh_car (s))->find_by_name (glyph);
81     }
82
83   return m;
84 }
85   
86   
87
88 Box
89 Virtual_font_metric::get_ascii_char (int)  const
90 {
91   programming_error ("Virtual font metric cannot be indexed by ASCII.");
92   return Box ();
93 }
94
95 Stencil
96 Virtual_font_metric::get_ascii_char_stencil (int )  const
97 {
98   programming_error ("Virtual font metric cannot be indexed by ASCII.");
99   return Stencil ();
100 }
101
102
103 Offset
104 Virtual_font_metric::get_indexed_wxwy (int code)  const
105 {
106   int total = 0;
107   for (SCM s = font_list_; gh_pair_p (s); s = gh_cdr (s))
108     {
109       Font_metric* fm = unsmob_metrics (gh_car (s));
110       if (code < total + fm->count ())
111         {
112           return fm->get_indexed_wxwy (code - total);
113         }
114       total += fm->count ();
115     }
116
117   
118   return Offset (0,0);
119 }
120
121 Box
122 Virtual_font_metric::get_indexed_char (int code)  const
123 {
124   int total = 0;
125   for (SCM s = font_list_; gh_pair_p (s); s = gh_cdr (s))
126     {
127       Font_metric* fm = unsmob_metrics (gh_car (s));
128       if (code < total + fm->count ())
129         {
130           return fm->get_indexed_char (code - total);
131         }
132       total += fm->count ();
133     }
134
135   
136   return Box ();
137 }
138
139
140 int 
141 Virtual_font_metric::name_to_index (String glyph) const
142 {
143   Stencil m;
144   int total = 0; 
145   for (SCM s = font_list_; m.is_empty () && gh_pair_p (s); s = gh_cdr (s))
146     {
147       Font_metric *m =unsmob_metrics (gh_car (s));
148       int k = m->name_to_index (glyph);
149       if (k >= 0)
150         return total + k;
151
152       total += m->count ();
153     }
154
155   return -1;
156 }
157
158   
159 Stencil
160 Virtual_font_metric::get_indexed_char_stencil (int code)  const
161 {
162   Stencil  m ;  
163   int total = 0;
164   
165   for (SCM s = font_list_; gh_pair_p (s); s = gh_cdr (s))
166     {
167       Font_metric* fm = unsmob_metrics (gh_car (s));
168       if (code < total + fm->count ())
169         {
170           m = fm->get_indexed_char_stencil (code - total); // ugh.
171           break; 
172         }
173       total += fm->count ();
174     }
175
176   return m;
177 }
178
179
180 SCM
181 Virtual_font_metric::get_font_list () const
182 {
183   return font_list_;
184 }
185
186 LY_DEFINE (ly_make_virtual_font, "ly:make-virtual-font", 0, 0, 1,
187            (SCM args),
188            "Make a virtual font metric from @var{args}, a list of font objects.")
189 {
190   Virtual_font_metric *fm = new  Virtual_font_metric (args);
191
192   return scm_gc_unprotect_object (fm->self_scm ());
193 }