2 page.cc -- implement Page
4 source file of the GNU LilyPond music typesetter
6 (c) 2004 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "ly-module.hh"
11 #include "paper-def.hh"
12 #include "paper-outputter.hh"
13 #include "paper-line.hh"
19 stencil2line (Stencil* stil, bool is_title = false)
23 z = scm_permanent_object (ly_offset2scm (Offset (0, 0)));
24 Offset dim = Offset (stil->extent (X_AXIS).length (),
25 stil->extent (Y_AXIS).length ());
26 Paper_line *pl = new Paper_line (dim, scm_cons (stil->smobbed_copy (),
28 -10001 * is_title, is_title);
30 return scm_gc_unprotect_object (pl->self_scm ());
33 static Real const MIN_COVERAGE = 0.66;
35 int Page::page_count_ = 0;
37 Page::Page (Paper_def *paper, int number)
53 hsize_ = paper->get_dimension (ly_symbol2scm ("hsize"));
54 vsize_ = paper->get_dimension (ly_symbol2scm ("vsize"));
55 top_margin_ = paper->get_dimension (ly_symbol2scm ("top-margin"));
56 bottom_margin_ = paper->get_dimension (ly_symbol2scm ("bottom-margin"));
57 head_sep_ = paper->get_dimension (ly_symbol2scm ("head-sep"));
58 foot_sep_ = paper->get_dimension (ly_symbol2scm ("foot-sep"));
59 text_width_ = paper->get_dimension (ly_symbol2scm ("linewidth"));
60 left_margin_ = (hsize_ - text_width_) / 2;
62 SCM make_header = ly_scheme_function ("make-header");
63 SCM make_footer = ly_scheme_function ("make-footer");
65 header_ = scm_call_2 (make_header, paper_->self_scm (),
66 scm_int2num (number_));
67 if (unsmob_stencil (header_))
68 unsmob_stencil (header_)->align_to (Y_AXIS, UP);
70 footer_ = scm_call_2 (make_footer, paper_->self_scm (),
71 scm_int2num (number_));
72 if (unsmob_stencil (footer_))
73 unsmob_stencil (footer_)->align_to (Y_AXIS, UP);
82 #include "ly-smobs.icc"
84 IMPLEMENT_DEFAULT_EQUAL_P (Page)
85 IMPLEMENT_SMOBS (Page)
86 IMPLEMENT_TYPE_P (Page, "ly:page?")
89 Page::mark_smob (SCM smob)
91 Page *p = (Page*) SCM_CELL_WORD_1 (smob);
92 scm_gc_mark (p->lines_);
93 scm_gc_mark (p->header_);
94 scm_gc_mark (p->footer_);
95 scm_gc_mark (p->copyright_);
96 scm_gc_mark (p->tagline_);
101 Page::print_smob (SCM smob, SCM port, scm_print_state*)
103 Page *p = (Page*) ly_cdr (smob);
105 scm_puts ("#<", port);
106 scm_puts (classname (p), port);
107 scm_puts (to_string (p->number_).to_str0 (), port);
108 scm_puts (" ", port);
109 scm_puts (">", port);
114 Page::output (Paper_outputter *out, bool is_last)
116 progress_indication ("[" + to_string (number_));
117 out->output_scheme (scm_list_1 (ly_symbol2scm ("start-page")));
118 Offset o (left_margin_, top_margin_);
119 Real vfill = line_count_ > 1 ? (text_height () - height_) / (line_count_ - 1)
122 Real coverage = height_ / text_height ();
123 if (coverage < MIN_COVERAGE)
124 /* Do not space out a badly filled page. This is too simplistic
125 (ie broken), because this should not vary too much between
126 (subsequent?) pages in a book. */
129 if (unsmob_stencil (header_))
131 out->output_line (stencil2line (unsmob_stencil (header_)), &o, false);
132 o[Y_AXIS] += head_sep_;
134 for (SCM s = lines_; s != SCM_EOL; s = ly_cdr (s))
136 SCM line = ly_car (s);
137 out->output_line (line, &o,
138 is_last && ly_cdr (s) != SCM_EOL && !unsmob_stencil (copyright_)
139 && !unsmob_stencil (tagline_) && !unsmob_stencil (footer_));
141 /* Do not put vfill between title and its music, */
142 if (scm_pair_p (ly_cdr (s))
143 && (!unsmob_paper_line (line)->is_title () || vfill < 0))
145 /* rather put extra just before the title. */
146 if (ly_cdr (s) != SCM_EOL
147 && (unsmob_paper_line (ly_cadr (s))->is_title () && vfill > 0))
151 o[Y_AXIS] = vsize_ - bottom_margin_;
152 if (unsmob_stencil (copyright_))
153 o[Y_AXIS] -= unsmob_stencil (copyright_)->extent (Y_AXIS).length ();
154 if (unsmob_stencil (tagline_))
155 o[Y_AXIS] -= unsmob_stencil (tagline_)->extent (Y_AXIS).length ();
156 if (unsmob_stencil (footer_))
157 o[Y_AXIS] -= unsmob_stencil (footer_)->extent (Y_AXIS).length ();
159 if (unsmob_stencil (copyright_))
160 out->output_line (stencil2line (unsmob_stencil (copyright_)), &o,
161 is_last && !unsmob_stencil (tagline_) && !unsmob_stencil (footer_));
162 if (unsmob_stencil (tagline_))
163 out->output_line (stencil2line (unsmob_stencil (tagline_)), &o,
164 is_last && !unsmob_stencil (footer_));
165 if (unsmob_stencil (footer_))
166 out->output_line (stencil2line (unsmob_stencil (footer_)), &o, is_last);
167 out->output_scheme (scm_list_2 (ly_symbol2scm ("stop-page"),
168 ly_bool2scm (is_last && !unsmob_stencil (footer_))));
169 progress_indication ("]");
175 Real h = vsize_ - top_margin_ - bottom_margin_;
176 if (unsmob_stencil (header_))
177 h -= unsmob_stencil (header_)->extent (Y_AXIS).length () + head_sep_;
178 if (unsmob_stencil (copyright_) || unsmob_stencil (tagline_) || unsmob_stencil (footer_))
180 if (unsmob_stencil (copyright_))
181 h -= unsmob_stencil (copyright_)->extent (Y_AXIS).length ();
182 if (unsmob_stencil (tagline_))
183 h -= unsmob_stencil (tagline_)->extent (Y_AXIS).length ();
184 if (unsmob_stencil (footer_))
185 h -= unsmob_stencil (footer_)->extent (Y_AXIS).length ();