before each stencil.
* lily/include/paper-book.hh (struct Score_lines): new
struct. Collect info per Paper-score.
* lily/include/page.hh (class Page): to_stencil() returns Stencil
everywhere.
* lily/stencil.cc (find_expression_fonts): new function
* 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.
2004-05-09 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * lily/paper-outputter.cc (output_stencil): dump font definitions
+ before each stencil.
+
+ * lily/include/paper-book.hh (struct Score_lines): new
+ struct. Collect info per Paper-score.
+
+ * lily/include/page.hh (class Page): to_stencil() returns Stencil
+ everywhere.
+
+ * lily/stencil.cc (find_expression_fonts): new function
+
* lily/paper-outputter.cc (output_stencil): use
interpret_stencil_expr
#include <stdio.h>
#include "ly-smobs.icc"
-
+#include "stencil.hh"
#include "book.hh"
#include "global-context.hh"
#include "ly-module.hh"
SCM systems = scores_[i]->book_rendering (outname, default_def, &paper);
if (systems != SCM_UNDEFINED)
{
- if (paper)
- paper_book->papers_.push (paper);
-
- paper_book->scores_.push (systems);
+ Score_lines sc;
+ sc.paper_ = paper;
+ sc.lines_ = systems;
+ sc.header_ =header;
- // fixme.
- //paper_book->global_headers_.push (global_input_file->header_);
- //paper_book->headers_.push (scores_[i]->header_);
- paper_book->headers_.push (header);
+ paper_book->score_lines_.push (sc);
}
}
paper_book->output (outname);
&paper);
if (systems != SCM_UNDEFINED)
{
- if (paper)
- paper_book->papers_.push (paper);
- paper_book->scores_.push (systems);
- paper_book->headers_.push (header);
+ Score_lines sc;
+ sc.paper_ = paper;
+ sc.lines_ = systems;
+ sc.header_ =header;
+
+ paper_book->score_lines_.push (sc);
+
+ // wtf: code dup.
}
}
if (pages != SCM_EOL)
{
progress_indication (_f ("paper output to `%s'...", "<markup>"));
- return (unsmob_page (ly_car (pages)))->to_stencil ();
+ return (unsmob_page (ly_car (pages)))->to_stencil ().smobbed_copy ();
}
return SCM_EOL;
}
/* available area for text. */
Real text_height () const;
Real left_margin () const;
- SCM to_stencil () const;
+ Stencil to_stencil () const;
};
DECLARE_UNSMOB (Page, page);
#include "protected-scm.hh"
#include "smobs.hh"
+struct Score_lines
+{
+ SCM lines_;
+ SCM header_;
+ SCM global_header_;
+ Paper_def *paper_;
+
+ Score_lines () ;
+ void gc_mark ();
+ SCM scopes ();
+};
+
class Paper_book
{
DECLARE_SMOBS (Paper_book, );
SCM tagline_;
public:
- Array<SCM> scores_;
- Array<SCM> headers_;
- Array<SCM> global_headers_;
- Link_array<Paper_def> papers_;
-
+ Array<Score_lines> score_lines_;
+
Paper_book ();
SCM lines ();
Paper_line (Offset, SCM, int penalty = 0, bool = false);
Offset dim () const;
- SCM to_stencil () const;
+ Stencil to_stencil () const;
SCM stencils () const;
bool is_title () const;
int penalty () const;
SCM output_module_;
Protected_scm file_;
String filename_;
-
+ Paper_def * paper_ ; // THIS IS BROKEN.
+
void output_expr (SCM expr, Offset o);
void output_metadata (Paper_def*, SCM);
void output_music_output_def (Music_output_def* odef);
DECLARE_UNSMOB(Stencil,stencil);
SCM fontify_atom (Font_metric const*, SCM atom);
-void interpret_stencil_expr (SCM expr,
+void interpret_stencil_expression (SCM expr,
void (*func) (void*, SCM),
void *func_arg,
Offset o);
Stencil create_stencil (SCM print);
-
-
+SCM find_expression_fonts (SCM expr);
#endif
return 1;
}
-static void
-stack_stencils (Stencil &a, Stencil *b, Offset *origin)
+static Stencil
+stack_stencils (Stencil a, Stencil b, Offset *origin)
{
- Real height = b->extent (Y_AXIS).length ();
+ Real height = b.extent (Y_AXIS).length ();
if (height > 50 CM)
{
programming_error (to_string ("Improbable stencil height: %f", height));
}
Offset o = *origin;
o.mirror (Y_AXIS);
- b->translate (o);
- a.add_stencil (*b);
+ b.translate (o);
+ a.add_stencil (b);
(*origin)[Y_AXIS] += height;
+ return a;
}
-SCM
+Stencil
Page::to_stencil () const
{
SCM proc = paper_->lookup_variable (ly_symbol2scm ("page-to-stencil"));
- return scm_call_1 (proc, self_scm ());
+ return *unsmob_stencil (scm_call_1 (proc, self_scm ()));
}
//urg
if (Stencil *s = unsmob_stencil (p->header_))
{
- stack_stencils (stencil, s, &o);
+ stencil = stack_stencils (stencil, *s, &o);
o[Y_AXIS] += p->paper_->get_dimension (ly_symbol2scm ("head-sep"));
}
for (SCM s = p->lines_; s != SCM_EOL; s = ly_cdr (s))
{
Paper_line *p = unsmob_paper_line (ly_car (s));
- stack_stencils (stencil, unsmob_stencil (p->to_stencil ()), &o);
+ stencil = stack_stencils (stencil, p->to_stencil (), &o);
/* Do not put vfill between title and its music, */
if (ly_cdr (s) != SCM_EOL
&& (!p->is_title () || vfill < 0))
o[Y_AXIS] -= unsmob_stencil (p->footer_)->extent (Y_AXIS).length ();
if (Stencil *s = unsmob_stencil (p->copyright_))
- stack_stencils (stencil, s, &o);
+ stencil = stack_stencils (stencil, *s, &o);
if (Stencil *s = unsmob_stencil (p->tagline_))
- stack_stencils (stencil, s, &o);
+ stencil = stack_stencils (stencil, *s, &o);
if (Stencil *s = unsmob_stencil (p->footer_))
- stack_stencils (stencil, s, &o);
+ stencil = stack_stencils (stencil, *s, &o);
return stencil.smobbed_copy ();
}
Paper_book::mark_smob (SCM smob)
{
Paper_book *b = (Paper_book*) SCM_CELL_WORD_1 (smob);
- for (int i = 0; i < b->headers_.size (); i++)
- scm_gc_mark (b->headers_[i]);
- for (int i = 0; i < b->global_headers_.size (); i++)
- scm_gc_mark (b->global_headers_[i]);
- for (int i = 0; i < b->papers_.size (); i++)
- scm_gc_mark (b->papers_[i]->self_scm ());
- for (int i = 0; i < b->scores_.size (); i++)
- scm_gc_mark (b->scores_[i]);
+ for (int i = 0; i < b->score_lines_.size (); i++)
+ b->score_lines_[i].gc_mark ();
scm_gc_mark (b->copyright_);
-
return b->tagline_;
}
void
Paper_book::output (String outname)
{
- if (!papers_.size ())
+ if (!score_lines_.size ())
// FIXME: no end-output?
return;
/* Generate all stencils to trigger font loads. */
SCM pages = this->pages ();
- Paper_def *paper = papers_[0];
+ Paper_def *paper = score_lines_[0].paper_;
Paper_outputter *out = paper->get_paper_outputter (outname);
int page_count = scm_ilength (pages);
out->output_header (paper, scopes (0), page_count, false);
-#if 0
- /* Ugh; fixme. */
- int paper_count = papers_.size ();
- for (int i = 1; i < paper_count; i ++)
- {
- SCM fonts = papers_[i]->font_descriptions ();
- out->output_scheme (scm_list_3 (ly_symbol2scm ("define-fonts"),
- papers_[i]->self_scm (),
- //FIXME:
- ly_quote_scm (ly_list_qsort_uniq_x (fonts))));
- }
-#endif
-
for (SCM s = pages; s != SCM_EOL; s = ly_cdr (s))
{
Page *p = unsmob_page (ly_car (s));
SCM
Paper_book::scopes (int i)
{
- SCM scopes = SCM_EOL;
- if (headers_[i])
- scopes = scm_cons (headers_[i], scopes);
- if (global_headers_.size ()
- && global_headers_[i] && global_headers_[i] != headers_[i])
- scopes = scm_cons (global_headers_[i], scopes);
- return scopes;
+ return score_lines_[i].scopes ();
}
+
Stencil
Paper_book::title (int i)
{
SCM s = ly_modules_lookup (scopes, field);
if (s != SCM_UNDEFINED && scm_variable_bound_p (s) == SCM_BOOL_T)
title = *unsmob_stencil (scm_call_2 (user_title,
- papers_[0]->self_scm (),
+ score_lines_[0].paper_->self_scm (),
scm_variable_ref (s)));
else
title = *unsmob_stencil (scm_call_2 (i == 0 ? book_title : score_title,
- papers_[0]->self_scm (),
+ score_lines_[0].paper_->self_scm (),
scopes));
if (!title.is_empty ())
title.align_to (Y_AXIS, UP);
void
Paper_book::classic_output (String outname)
{
- int count = scores_.size ();
- Paper_outputter *out = papers_.top ()->get_paper_outputter (outname);
- out->output_header (papers_.top (), scopes (count - 1), 0, true);
+ int count = score_lines_.size ();
+ Paper_def * p = score_lines_.top ().paper_;
+ Paper_outputter *out = p->get_paper_outputter (outname);
+ out->output_header (p, scopes (count - 1), 0, true);
- Paper_line *first = unsmob_paper_line (scm_vector_ref (scores_.top (),
+ SCM top_lines = score_lines_.top ().lines_;
+ Paper_line *first = unsmob_paper_line (scm_vector_ref (top_lines,
scm_int2num (0)));
Offset o (0, -0.5 * first->dim ()[Y_AXIS]);
- int line_count = SCM_VECTOR_LENGTH ((SCM) scores_.top ());
+ int line_count = SCM_VECTOR_LENGTH (top_lines);
for (int i = 0; i < line_count; i++)
{
/* In classic compatibility TeX tracks how large things are, and
if (output_format_global == "tex")
o = Offset (0, 0);
- out->output_line (scm_vector_ref ((SCM) scores_.top (), scm_int2num (i)),
+ out->output_line (scm_vector_ref (top_lines, scm_int2num (i)),
&o, i == line_count - 1);
}
void
Paper_book::init ()
{
- int score_count = scores_.size ();
+ int score_count = score_lines_.size ();
/* Calculate the full book height. Hmm, can't we cache system
heights while making stencils? */
if (!title.is_empty ())
height_ += title.extent (Y_AXIS).length ();
- int line_count = SCM_VECTOR_LENGTH ((SCM) scores_[i]);
+ int line_count = SCM_VECTOR_LENGTH (score_lines_[i].lines_);
for (int j = 0; j < line_count; j++)
{
- SCM s = scm_vector_ref ((SCM) scores_[i], scm_int2num (j));
+ SCM s = scm_vector_ref ((SCM) score_lines_[i].lines_, scm_int2num (j));
height_ += unsmob_paper_line (s)->dim ()[Y_AXIS];
}
}
- Paper_def *paper = papers_[0];
+ Paper_def *paper = score_lines_[0].paper_;
SCM scopes = this->scopes (0);
SCM make_tagline = paper->c_variable ("make-tagline");
SCM
Paper_book::lines ()
{
- int score_count = scores_.size ();
+ int score_count = score_lines_.size ();
SCM lines = SCM_EOL;
for (int i = 0; i < score_count; i++)
{
Stencil title = this->title (i);
if (!title.is_empty ())
lines = ly_snoc (stencil2line (title, true), lines);
- lines = scm_append (scm_list_2 (lines, scm_vector_to_list (scores_[i])));
+ lines = scm_append (scm_list_2 (lines, scm_vector_to_list (score_lines_[i].lines_)));
}
+
//debug helper; ughr
int i = 0;
for (SCM s = lines; s != SCM_EOL; s = ly_cdr (s))
{
init ();
Page::page_count_ = 0;
- Paper_def *paper = papers_[0];
+ Paper_def *paper = score_lines_[0].paper_;
Page *page = new Page (paper, 1);
Real text_height = page->text_height ();
ly_scm2double (book), ly_scm2double (text),
ly_scm2double (first), ly_scm2double (last));
}
+
+/****************************************************************/
+
+Score_lines::Score_lines ()
+{
+ lines_ = SCM_EOL;
+ global_header_ = SCM_EOL;
+ header_ = SCM_EOL;
+ paper_ = 0;
+}
+
+void
+Score_lines::gc_mark ()
+{
+ scm_gc_mark (lines_);
+ scm_gc_mark (global_header_);
+ scm_gc_mark (header_);
+ if (paper_)
+ scm_gc_mark (paper_->self_scm ());
+}
+
+
+SCM
+Score_lines::scopes ()
+{
+ SCM scopes = SCM_EOL;
+ if (header_)
+ scopes = scm_cons (header_, scopes);
+ if (SCM_MODULEP(global_header_)
+ && global_header_ != header_)
+ scopes = scm_cons (global_header_, scopes);
+
+ return scopes;
+}
stencil_.extent (Y_AXIS).length ());
}
-SCM
+Stencil
Paper_line::to_stencil () const
{
- return stencil_.smobbed_copy ();
+ return stencil_;
}
LY_DEFINE (ly_paper_line_height, "ly:paper-line-height",
{
Paper_line *pl = unsmob_paper_line (line);
SCM_ASSERT_TYPE (pl, line, SCM_ARG1, __FUNCTION__, "paper-line");
- return pl->to_stencil ();
+ return pl->to_stencil ().smobbed_copy ();
}
Paper_outputter::Paper_outputter (String filename)
{
filename_ = filename;
+ paper_ = 0;
file_ = scm_open_file (scm_makfrom0str (filename.to_str0 ()),
scm_makfrom0str ("w"));
Paper_outputter::output_header (Paper_def *paper, SCM scopes, int page_count,
bool is_classic)
{
+ paper_ = paper; // BROKEN BROKEN BROKEN.
String creator = gnu_lilypond_version_string ();
creator += " (http://lilypond.org)";
time_t t (time (0));
output_music_output_def (paper);
output_scheme (scm_list_1 (ly_symbol2scm ("header-end")));
-
- /* TODO: maybe have Scheme extract the fonts directly from \paper ?
-
- Alternatively, we could simply load the fonts on demand in the
- output, and do away with this define-fonts step. */
- SCM fonts = paper->font_descriptions ();
- output_scheme (scm_list_3 (ly_symbol2scm ("define-fonts"),
- paper->self_scm (),
- //FIXME:
- ly_quote_scm (ly_list_qsort_uniq_x (fonts))));
}
void
dim[Y_AXIS] = 50 CM;
}
+
output_scheme (scm_list_3 (ly_symbol2scm ("start-system"),
ly_quote_scm (ly_offset2scm (*origin)),
ly_quote_scm (ly_offset2scm (dim))));
- output_stencil (*unsmob_stencil (p->to_stencil ()));
+
+ output_stencil (p->to_stencil ());
(*origin)[Y_AXIS] += dim[Y_AXIS];
output_scheme (scm_list_2 (ly_symbol2scm ("stop-system"),
void
Paper_outputter::output_page (Page *p, bool is_last)
{
+ Stencil page_stencil = p->to_stencil ();
output_scheme (scm_list_1 (ly_symbol2scm ("start-page")));
-
output_scheme (scm_list_3 (ly_symbol2scm ("start-system"),
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 (page_stencil);
output_scheme (scm_list_2 (ly_symbol2scm ("stop-system"), SCM_BOOL_T));
output_scheme (scm_list_2 (ly_symbol2scm ("stop-page"),
void
Paper_outputter::output_stencil (Stencil stil)
{
- interpret_stencil_expr (stil.expr (), paper_outputter_dump,
+ SCM fonts = find_expression_fonts (stil.expr ());
+
+ output_scheme (scm_list_3 (ly_symbol2scm ("define-fonts"),
+ paper_->self_scm (),
+ ly_quote_scm (ly_list_qsort_uniq_x (fonts))));
+
+ interpret_stencil_expression (stil.expr (), paper_outputter_dump,
(void*) this, Offset (0,0));
}
{
Paper_book *paper_book = new Paper_book ();
Paper_score *ps = dynamic_cast<Paper_score*> (output);
- paper_book->papers_.push (ps->paper_);
- paper_book->scores_.push (systems);
- paper_book->headers_.push (header);
+
+ Score_lines sc;
+ sc.paper_ = ps->paper_;
+ sc.lines_ = systems;
+ sc.header_ = header;
+
+ paper_book->score_lines_.push (sc);
paper_book->classic_output (ly_scm2string (outname));
scm_gc_unprotect_object (paper_book->self_scm ());
#include <math.h>
#include <libc-extension.hh> // isinf
-#include "input.hh"
+#include "input-smob.hh"
#include "font-metric.hh"
#include "dimensions.hh"
#include "interval.hh"
/****************************************************************/
void
-interpret_stencil_expr (SCM expr,
+interpret_stencil_expression (SCM expr,
void (*func) (void*, SCM),
void *func_arg,
Offset o)
}
else if (head == ly_symbol2scm ("combine-stencil"))
{
- interpret_stencil_expr (ly_cadr (expr), func, func_arg, o);
+ interpret_stencil_expression (ly_cadr (expr), func, func_arg, o);
expr = ly_caddr (expr);
}
else
struct Font_list
{
- SCM list_;
+ SCM fonts_;
};
static void
find_font_function (void * fs, SCM x)
{
- Font_struct * me = (Font_struct*)fs;
+ Font_list * me = (Font_list*)fs;
if (ly_car (x) == ly_symbol2scm ("placebox"))
{
SCM args = ly_cdr (x);
- SCM what = ly_caddr (x);
+ SCM what = ly_caddr (args);
if (ly_c_pair_p (what))
{
}
}
-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}."
+SCM
+find_expression_fonts (SCM expr)
{
- Stencil *stil =unsmob_stencil (s);
- SCM_ASSERT_TYPE (stil, s, SCM_ARG1, __FUNCTION__, "Stencil");
Font_list fl;
- fl.list_ = SCM_EOL;
+ fl.fonts_ = SCM_EOL;
- interpret_stencil_expr (stil.expr (), &find_font_function,
+ interpret_stencil_expression (expr, &find_font_function,
(void*) &fl, Offset (0,0));
- return fl.list_;
+ return fl.fonts_;
+}
+
+LY_DEFINE(ly_stencil_fonts, "ly:stencil-fonts",
+ 1, 0, 0, (SCM 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");
+ return find_expression_fonts (stil->expr ());
}