]> git.donarmstrong.com Git - lilypond.git/blob - lily/stencil-interpret.cc
LSR: update.
[lilypond.git] / lily / stencil-interpret.cc
1 /*
2   stencil-interpret.cc --  implement Stencil expression interpreting
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2005--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "stencil.hh"
10
11 void
12 interpret_stencil_expression (SCM expr,
13                               void (*func) (void *, SCM),
14                               void *func_arg,
15                               Offset o)
16 {
17   while (1)
18     {
19       if (!scm_is_pair (expr))
20         return;
21
22       SCM head = scm_car (expr);
23
24       if (head == ly_symbol2scm ("delay-stencil-evaluation"))
25         {
26           interpret_stencil_expression (scm_force (scm_cadr (expr)), func, func_arg, o);
27           return;
28         }
29       if (head == ly_symbol2scm ("translate-stencil"))
30         {
31           o += ly_scm2offset (scm_cadr (expr));
32           expr = scm_caddr (expr);
33         }
34       else if (head == ly_symbol2scm ("combine-stencil"))
35         {
36
37           for (SCM x = scm_cdr (expr); scm_is_pair (x); x = scm_cdr (x))
38             interpret_stencil_expression (scm_car (x), func, func_arg, o);
39           return;
40         }
41       else if (head == ly_symbol2scm ("grob-cause"))
42         {
43           SCM grob = scm_cadr (expr);
44
45           (*func) (func_arg, scm_list_3 (head,
46                                          ly_quote_scm (ly_offset2scm (o)), grob));
47           interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
48           (*func) (func_arg, scm_list_1 (ly_symbol2scm ("no-origin")));
49           return;
50         }
51       else if (head == ly_symbol2scm ("color"))
52         {
53           SCM color = scm_cadr (expr);
54           SCM r = scm_car (color);
55           SCM g = scm_cadr (color);
56           SCM b = scm_caddr (color);
57
58           (*func) (func_arg, scm_list_4 (ly_symbol2scm ("setcolor"), r, g, b));
59           interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
60           (*func) (func_arg, scm_list_1 (ly_symbol2scm ("resetcolor")));
61
62           return;
63         }
64       else if (head == ly_symbol2scm ("rotate-stencil"))
65         {
66           SCM args = scm_cadr (expr);
67           SCM angle = scm_car (args);
68           Offset tmp = o + robust_scm2offset (scm_cadr (args), Offset (0.0, 0.0));
69
70           SCM offset = ly_offset2scm (tmp);
71           SCM x = scm_car (offset);
72           SCM y = scm_cdr (offset);
73
74           (*func) (func_arg, scm_list_4 (ly_symbol2scm ("setrotation"), angle, x, y));
75           interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
76           (*func) (func_arg, scm_list_4 (ly_symbol2scm ("resetrotation"), angle, x, y));
77
78           return;
79         }
80       else
81         {
82           (*func) (func_arg,
83                    scm_list_4 (ly_symbol2scm ("placebox"),
84                                scm_from_double (o[X_AXIS]),
85                                scm_from_double (o[Y_AXIS]),
86                                expr));
87           return;
88         }
89     }
90 }
91
92 struct Font_list
93 {
94   SCM fonts_;
95 };
96
97 static void
98 find_font_function (void *fs, SCM x)
99 {
100   Font_list *me = (Font_list *) fs;
101
102   if (scm_car (x) == ly_symbol2scm ("placebox"))
103     {
104       SCM args = scm_cdr (x);
105       SCM what = scm_caddr (args);
106
107       if (scm_is_pair (what))
108         {
109           SCM head = scm_car (what);
110           if (ly_symbol2scm ("text") == head)
111             me->fonts_ = scm_cons (scm_cadr (what), me->fonts_);
112           else if (head == ly_symbol2scm ("char"))
113             me->fonts_ = scm_cons (scm_cadr (what), me->fonts_);
114         }
115     }
116 }
117
118 SCM
119 find_expression_fonts (SCM expr)
120 {
121   Font_list fl;
122
123   fl.fonts_ = SCM_EOL;
124
125   interpret_stencil_expression (expr, &find_font_function,
126                                 (void *) & fl, Offset (0, 0));
127
128   return fl.fonts_;
129 }