From 25b213ce648ba00918e97d94ce3e022d90f38c46 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 9 May 2004 18:42:16 +0000 Subject: [PATCH] * lily/paper-outputter.cc (output_stencil): use interpret_stencil_expr * lily/stencil.cc (LY_DEFINE): ly_stencil_fonts: new function. (interpret_stencil_expr): new function. Generic stencil interpretation. --- ChangeLog | 7 +++ lily/afm.cc | 1 - lily/font-metric.cc | 2 +- lily/include/paper-outputter.hh | 2 +- lily/include/stencil.hh | 16 ++++-- lily/paper-outputter.cc | 57 ++++--------------- lily/stencil.cc | 98 +++++++++++++++++++++++++++++++++ scm/output-ps.scm | 21 ------- 8 files changed, 130 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4020592ac7..c9d5bc1961 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2004-05-09 Han-Wen Nienhuys + * lily/paper-outputter.cc (output_stencil): use + interpret_stencil_expr + + * lily/stencil.cc (LY_DEFINE): ly_stencil_fonts: new function. + (interpret_stencil_expr): new function. Generic stencil + interpretation. + * lily/paper-def.cc (find_scaled_font): divide lookup magnification by outpuscale for non-virtual fontmetrics. This fixes ludicrously long font definitions for text diff --git a/lily/afm.cc b/lily/afm.cc index ab7e707811..c92433bd1a 100644 --- a/lily/afm.cc +++ b/lily/afm.cc @@ -12,7 +12,6 @@ #include "warn.hh" #include "libc-extension.hh" #include "afm.hh" -#include "stencil.hh" #include "dimensions.hh" Adobe_font_metric::Adobe_font_metric (AFM_Font_info *fi) diff --git a/lily/font-metric.cc b/lily/font-metric.cc index 49462f8789..509daa608d 100644 --- a/lily/font-metric.cc +++ b/lily/font-metric.cc @@ -91,7 +91,7 @@ Font_metric::name_to_index (String) const } Offset -Font_metric::get_indexed_wxwy (int )const +Font_metric::get_indexed_wxwy (int) const { return Offset (0, 0); } diff --git a/lily/include/paper-outputter.hh b/lily/include/paper-outputter.hh index c6531ef8c1..4d36d67a1f 100644 --- a/lily/include/paper-outputter.hh +++ b/lily/include/paper-outputter.hh @@ -41,7 +41,7 @@ public: void dump_scheme (SCM); void output_scheme (SCM scm); - void output_stencil (Stencil*); + void output_stencil (Stencil); void output_header (Paper_def*, SCM, int, bool); void output_line (SCM, Offset*, bool); void output_page (Page*, bool); diff --git a/lily/include/stencil.hh b/lily/include/stencil.hh index 311b6eff18..c403ff8201 100644 --- a/lily/include/stencil.hh +++ b/lily/include/stencil.hh @@ -21,9 +21,11 @@ It is implemented as a "tree" of scheme expressions, as in Expr = combine Expr Expr - | translate Offset Expr - | SCHEME - ; + | translate Offset Expr + | origin (ORIGIN) Expr + | no-origin Expr + | (SCHEME) + ; SCHEME is a Scheme expression that --when eval'd-- produces the desired output. @@ -34,7 +36,8 @@ efficient to add "fresh" stencils to what you're going to build. * Do not create Stencil objects on the heap. That includes passing - around Stencil* which are produced by unsmob_stencil(). + around Stencil* which are produced by unsmob_stencil(). Either + copy Stencil objects, or use SCM references. * Empty stencils have empty dimensions. If add_at_edge is used to init the stencil, we assume that @@ -88,6 +91,11 @@ public: DECLARE_UNSMOB(Stencil,stencil); SCM fontify_atom (Font_metric const*, SCM atom); +void interpret_stencil_expr (SCM expr, + void (*func) (void*, SCM), + void *func_arg, + Offset o); + Stencil create_stencil (SCM print); diff --git a/lily/paper-outputter.cc b/lily/paper-outputter.cc index 94bff9eaed..7b93840f12 100644 --- a/lily/paper-outputter.cc +++ b/lily/paper-outputter.cc @@ -124,7 +124,7 @@ Paper_outputter::output_line (SCM line, Offset *origin, bool is_last) ly_quote_scm (ly_offset2scm (*origin)), ly_quote_scm (ly_offset2scm (dim)))); - output_stencil (unsmob_stencil (p->to_stencil ())); + output_stencil (*unsmob_stencil (p->to_stencil ())); (*origin)[Y_AXIS] += dim[Y_AXIS]; output_scheme (scm_list_2 (ly_symbol2scm ("stop-system"), @@ -140,7 +140,7 @@ Paper_outputter::output_page (Page *p, bool is_last) ly_quote_scm (ly_offset2scm (Offset (0, 0))), ly_quote_scm (ly_offset2scm (Offset (0, 0))))); - output_stencil (unsmob_stencil (p->to_stencil ())); + output_stencil (*unsmob_stencil (p->to_stencil ())); output_scheme (scm_list_2 (ly_symbol2scm ("stop-system"), SCM_BOOL_T)); output_scheme (scm_list_2 (ly_symbol2scm ("stop-page"), @@ -155,54 +155,19 @@ Paper_outputter::output_music_output_def (Music_output_def *odef) odef->self_scm ())); } + void -Paper_outputter::output_stencil (Stencil *stil) +paper_outputter_dump (void * po, SCM x) { - output_expr (stil->expr (), stil->origin ()); + Paper_outputter * me = (Paper_outputter*) po; + me->output_scheme (x); } -/* TODO: replaceme/rewriteme, see output-ps.scm: output-stencil */ + void -Paper_outputter::output_expr (SCM expr, Offset o) +Paper_outputter::output_stencil (Stencil stil) { - while (1) - { - if (!ly_c_pair_p (expr)) - return; - - SCM head =ly_car (expr); - if (unsmob_input (head)) - { - Input *ip = unsmob_input (head); - output_scheme (scm_list_4 (ly_symbol2scm ("define-origin"), - scm_makfrom0str (ip->file_string () - .to_str0 ()), - scm_int2num (ip->line_number ()), - scm_int2num (ip->column_number ()))); - expr = ly_cadr (expr); - } - else if (head == ly_symbol2scm ("no-origin")) - { - output_scheme (scm_list_1 (head)); - expr = ly_cadr (expr); - } - else if (head == ly_symbol2scm ("translate-stencil")) - { - o += ly_scm2offset (ly_cadr (expr)); - expr = ly_caddr (expr); - } - else if (head == ly_symbol2scm ("combine-stencil")) - { - output_expr (ly_cadr (expr), o); - expr = ly_caddr (expr); - } - else - { - output_scheme (scm_list_4 (ly_symbol2scm ("placebox"), - scm_make_real (o[X_AXIS]), - scm_make_real (o[Y_AXIS]), - expr)); - return; - } - } + interpret_stencil_expr (stil.expr (), paper_outputter_dump, + (void*) this, Offset (0,0)); } + diff --git a/lily/stencil.cc b/lily/stencil.cc index 5f0e04f3a8..e109152582 100644 --- a/lily/stencil.cc +++ b/lily/stencil.cc @@ -9,6 +9,7 @@ #include #include // isinf +#include "input.hh" #include "font-metric.hh" #include "dimensions.hh" #include "interval.hh" @@ -182,3 +183,100 @@ Stencil::add_at_edge (Axis a, Direction d, Stencil const &s, Real padding, { add_stencil (moved_to_edge (a, d, s, padding, minimum)); } + + +/****************************************************************/ + +void +interpret_stencil_expr (SCM expr, + void (*func) (void*, SCM), + void *func_arg, + Offset o) +{ + while (1) + { + if (!ly_c_pair_p (expr)) + return; + + SCM head =ly_car (expr); + if (unsmob_input (head)) + { + Input *ip = unsmob_input (head); + (*func)(func_arg, + scm_list_4 (ly_symbol2scm ("define-origin"), + scm_makfrom0str (ip->file_string () + .to_str0 ()), + scm_int2num (ip->line_number ()), + scm_int2num (ip->column_number ()))); + + expr = ly_cadr (expr); + } + else if (head == ly_symbol2scm ("no-origin")) + { + (*func) (func_arg, scm_list_1 (head)); + expr = ly_cadr (expr); + } + else if (head == ly_symbol2scm ("translate-stencil")) + { + o += ly_scm2offset (ly_cadr (expr)); + expr = ly_caddr (expr); + } + else if (head == ly_symbol2scm ("combine-stencil")) + { + interpret_stencil_expr (ly_cadr (expr), func, func_arg, o); + expr = ly_caddr (expr); + } + else + { + (*func) (func_arg, + scm_list_4 (ly_symbol2scm ("placebox"), + scm_make_real (o[X_AXIS]), + scm_make_real (o[Y_AXIS]), + expr)); + return; + } + } +} + + +struct Font_list +{ + SCM list_; +}; + +static void +find_font_function (void * fs, SCM x) +{ + Font_struct * me = (Font_struct*)fs; + + if (ly_car (x) == ly_symbol2scm ("placebox")) + { + SCM args = ly_cdr (x); + SCM what = ly_caddr (x); + + if (ly_c_pair_p (what)) + { + SCM head = ly_car (what); + if (ly_symbol2scm ("text") == head) + me->fonts_ = scm_cons (ly_cadr (what), me->fonts_); + else if (head == ly_symbol2scm ("char")) + me->fonts_ = scm_cons (ly_cadr (what), me->fonts_); + } + } +} + +LY_DEFINE(ly_stencil_fonts, "ly:stencil-fonts", + 1,0,0, (s), + "Analyse @var{s}, and return a list of fonts used in @var{s}." +{ + Stencil *stil =unsmob_stencil (s); + SCM_ASSERT_TYPE (stil, s, SCM_ARG1, __FUNCTION__, "Stencil"); + Font_list fl; + + fl.list_ = SCM_EOL; + + interpret_stencil_expr (stil.expr (), &find_font_function, + (void*) &fl, Offset (0,0)); + + return fl.list_; +} diff --git a/scm/output-ps.scm b/scm/output-ps.scm index 1e6fec5ce0..22cce8d52b 100644 --- a/scm/output-ps.scm +++ b/scm/output-ps.scm @@ -342,27 +342,6 @@ (string-append (apply string-append (map output-scope scopes))))) -;; hmm, looks like recursing call is always last statement, does guile -;; think so too? -(define (output-stencil port expr offset) - (if (pair? expr) - (let ((head (car expr))) - (cond - ((ly:input-location? head) - (display (apply define-origin (ly:input-location head)) port) - (output-stencil port (cadr expr) offset)) - ((eq? head 'no-origin) - (display (expression->string head) port) - (output-stencil port (cadr expr) offset)) - ((eq? head 'translate-stencil) - (output-stencil port (caddr expr) (offset-add offset (cadr expr)))) - ((eq? head 'combine-stencil) - (output-stencil port (cadr expr) offset) - (output-stencil port (caddr expr) offset)) - (else - (display (placebox (car offset) (cdr offset) - (expression->string expr)) port)))))) - (define (placebox x y s) (string-append (ly:number->string x) " " (ly:number->string y) " { " s " } place-box\n")) -- 2.39.2