]> git.donarmstrong.com Git - lilypond.git/blob - lily/stencil-interpret.cc
plug small leak.
[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 ("translate-stencil"))
25         {
26           o += ly_scm2offset (scm_cadr (expr));
27           expr = scm_caddr (expr);
28         }
29       else if (head == ly_symbol2scm ("combine-stencil"))
30         {
31
32           for (SCM x = scm_cdr (expr); scm_is_pair (x); x = scm_cdr (x))
33             interpret_stencil_expression (scm_car (x), func, func_arg, o);
34           return;
35         }
36       else if (head == ly_symbol2scm ("grob-cause"))
37         {
38           SCM grob = scm_cadr (expr);
39
40           (*func) (func_arg, scm_list_3 (head,
41                                          ly_quote_scm (ly_offset2scm (o)), grob));
42           interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
43           (*func) (func_arg, scm_list_1 (ly_symbol2scm ("no-origin")));
44           return;
45         }
46       else if (head == ly_symbol2scm ("color"))
47         {
48           SCM color = scm_cadr (expr);
49           SCM r = scm_car (color);
50           SCM g = scm_cadr (color);
51           SCM b = scm_caddr (color);
52
53           (*func) (func_arg, scm_list_4 (ly_symbol2scm ("setcolor"), r, g, b));
54           interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
55           (*func) (func_arg, scm_list_1 (ly_symbol2scm ("resetcolor")));
56
57           return;
58         }
59       else if (head == ly_symbol2scm ("rotate-stencil"))
60         {
61           SCM args = scm_cadr (expr);
62           SCM angle = scm_car (args);
63           Offset tmp = o + robust_scm2offset (scm_cadr (args), Offset (0.0, 0.0));
64
65           SCM offset = ly_offset2scm (tmp);
66           SCM x = scm_car (offset);
67           SCM y = scm_cdr (offset);
68
69           (*func) (func_arg, scm_list_4 (ly_symbol2scm ("setrotation"), angle, x, y));
70           interpret_stencil_expression (scm_caddr (expr), func, func_arg, o);
71           (*func) (func_arg, scm_list_4 (ly_symbol2scm ("resetrotation"), angle, x, y));
72
73           return;
74         }
75       else
76         {
77           (*func) (func_arg,
78                    scm_list_4 (ly_symbol2scm ("placebox"),
79                                scm_from_double (o[X_AXIS]),
80                                scm_from_double (o[Y_AXIS]),
81                                expr));
82           return;
83         }
84     }
85 }
86
87 struct Font_list
88 {
89   SCM fonts_;
90 };
91
92 static void
93 find_font_function (void *fs, SCM x)
94 {
95   Font_list *me = (Font_list *) fs;
96
97   if (scm_car (x) == ly_symbol2scm ("placebox"))
98     {
99       SCM args = scm_cdr (x);
100       SCM what = scm_caddr (args);
101
102       if (scm_is_pair (what))
103         {
104           SCM head = scm_car (what);
105           if (ly_symbol2scm ("text") == head)
106             me->fonts_ = scm_cons (scm_cadr (what), me->fonts_);
107           else if (head == ly_symbol2scm ("char"))
108             me->fonts_ = scm_cons (scm_cadr (what), me->fonts_);
109         }
110     }
111 }
112
113 SCM
114 find_expression_fonts (SCM expr)
115 {
116   Font_list fl;
117
118   fl.fonts_ = SCM_EOL;
119
120   interpret_stencil_expression (expr, &find_font_function,
121                                 (void *) & fl, Offset (0, 0));
122
123   return fl.fonts_;
124 }