]> git.donarmstrong.com Git - lilypond.git/blob - lily/stencil-interpret.cc
* The grand 2005-2006 replace.
[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--2006 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
60         {
61           (*func) (func_arg,
62                    scm_list_4 (ly_symbol2scm ("placebox"),
63                                scm_from_double (o[X_AXIS]),
64                                scm_from_double (o[Y_AXIS]),
65                                expr));
66           return;
67         }
68     }
69 }
70
71 struct Font_list
72 {
73   SCM fonts_;
74 };
75
76 static void
77 find_font_function (void *fs, SCM x)
78 {
79   Font_list *me = (Font_list *) fs;
80
81   if (scm_car (x) == ly_symbol2scm ("placebox"))
82     {
83       SCM args = scm_cdr (x);
84       SCM what = scm_caddr (args);
85
86       if (scm_is_pair (what))
87         {
88           SCM head = scm_car (what);
89           if (ly_symbol2scm ("text") == head)
90             me->fonts_ = scm_cons (scm_cadr (what), me->fonts_);
91           else if (head == ly_symbol2scm ("char"))
92             me->fonts_ = scm_cons (scm_cadr (what), me->fonts_);
93         }
94     }
95 }
96
97 SCM
98 find_expression_fonts (SCM expr)
99 {
100   Font_list fl;
101
102   fl.fonts_ = SCM_EOL;
103
104   interpret_stencil_expression (expr, &find_font_function,
105                                 (void *) & fl, Offset (0, 0));
106
107   return fl.fonts_;
108 }