2 page.cc -- implement Page
4 source file of the GNU LilyPond music typesetter
6 (c) 2004 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "dimensions.hh"
10 #include "ly-module.hh"
12 #include "paper-def.hh"
13 #include "paper-outputter.hh"
14 #include "paper-line.hh"
18 int Page::page_count_ = 0;
19 Real Page::MIN_COVERAGE_ = 0.66;
21 Page::Page (Paper_def *paper, int number)
37 header_ = scm_call_2 (paper_->c_variable ("make-header"),
39 scm_int2num (number_));
40 if (unsmob_stencil (header_))
41 unsmob_stencil (header_)->align_to (Y_AXIS, UP);
43 footer_ = scm_call_2 (paper_->c_variable ("make-footer"),
45 scm_int2num (number_));
46 if (unsmob_stencil (footer_))
47 unsmob_stencil (footer_)->align_to (Y_AXIS, UP);
56 #include "ly-smobs.icc"
58 IMPLEMENT_DEFAULT_EQUAL_P (Page)
59 IMPLEMENT_SMOBS (Page)
60 IMPLEMENT_TYPE_P (Page, "ly:page?")
63 Page::mark_smob (SCM smob)
65 Page *p = (Page*) SCM_CELL_WORD_1 (smob);
66 scm_gc_mark (p->header_);
67 scm_gc_mark (p->footer_);
68 scm_gc_mark (p->copyright_);
69 scm_gc_mark (p->tagline_);
70 //scm_gc_mark (p->lines_);
75 Page::print_smob (SCM smob, SCM port, scm_print_state*)
77 Page *p = (Page*) ly_cdr (smob);
78 scm_puts ("#<", port);
79 scm_puts (classname (p), port);
80 scm_puts (to_string (p->number_).to_str0 (), port);
87 stack_stencils (Stencil &a, Stencil *b, Offset *origin)
89 Real height = b->extent (Y_AXIS).length ();
92 programming_error (to_string ("Improbable stencil height: %f", height));
99 (*origin)[Y_AXIS] += height;
103 Page::to_stencil () const
105 SCM proc = paper_->lookup_variable (ly_symbol2scm ("page-to-stencil"));
106 return scm_call_1 (proc, self_scm ());
111 Page::left_margin () const
113 return (paper_->get_dimension (ly_symbol2scm ("hsize"))
114 - paper_->get_dimension (ly_symbol2scm ("linewidth"))) / 2;
117 LY_DEFINE (ly_page_header_lines_footer_stencil, "ly:page-header-lines-footer-stencil",
119 "Simple header, lines, footer stencil from PAGE.")
121 Page *p = unsmob_page (page);
122 SCM_ASSERT_TYPE (p, page, SCM_ARG1, __FUNCTION__, "page");
125 Offset o (p->left_margin (),
126 p->paper_->get_dimension (ly_symbol2scm ("top-margin")));
128 Real vfill = (p->line_count_ > 1
129 ? (p->text_height () - p->height_) / (p->line_count_ - 1)
132 Real coverage = p->height_ / p->text_height ();
133 if (coverage < p->MIN_COVERAGE_)
134 /* Do not space out a badly filled page. This is too simplistic
135 (ie broken), because this should not vary too much between
136 (subsequent?) pages in a book. */
139 if (Stencil *s = unsmob_stencil (p->header_))
141 stack_stencils (stencil, s, &o);
142 o[Y_AXIS] += p->paper_->get_dimension (ly_symbol2scm ("head-sep"));
145 for (SCM s = p->lines_; s != SCM_EOL; s = ly_cdr (s))
147 Paper_line *p = unsmob_paper_line (ly_car (s));
148 stack_stencils (stencil, unsmob_stencil (p->to_stencil ()), &o);
149 /* Do not put vfill between title and its music, */
150 if (ly_cdr (s) != SCM_EOL
151 && (!p->is_title () || vfill < 0))
153 /* rather put extra just before the title. */
154 if (ly_cdr (s) != SCM_EOL
155 && (unsmob_paper_line (ly_cadr (s))->is_title () && vfill > 0))
159 o[Y_AXIS] = p->paper_->get_dimension (ly_symbol2scm ("vsize"))
160 - p->paper_->get_dimension (ly_symbol2scm ("bottom-margin"));
161 if (unsmob_stencil (p->copyright_))
162 o[Y_AXIS] -= unsmob_stencil (p->copyright_)->extent (Y_AXIS).length ();
163 if (unsmob_stencil (p->tagline_))
164 o[Y_AXIS] -= unsmob_stencil (p->tagline_)->extent (Y_AXIS).length ();
165 if (unsmob_stencil (p->footer_))
166 o[Y_AXIS] -= unsmob_stencil (p->footer_)->extent (Y_AXIS).length ();
168 if (Stencil *s = unsmob_stencil (p->copyright_))
169 stack_stencils (stencil, s, &o);
170 if (Stencil *s = unsmob_stencil (p->tagline_))
171 stack_stencils (stencil, s, &o);
172 if (Stencil *s = unsmob_stencil (p->footer_))
173 stack_stencils (stencil, s, &o);
175 return stencil.smobbed_copy ();
179 Page::text_height () const
181 Real h = paper_->get_dimension (ly_symbol2scm ("vsize"))
182 - paper_->get_dimension (ly_symbol2scm ("top-margin"))
183 - paper_->get_dimension (ly_symbol2scm ("bottom-margin"));
184 if (unsmob_stencil (header_))
185 h -= unsmob_stencil (header_)->extent (Y_AXIS).length ()
186 + paper_->get_dimension (ly_symbol2scm ("head-sep"));
187 if (unsmob_stencil (copyright_)
188 || unsmob_stencil (tagline_)
189 || unsmob_stencil (footer_))
190 h -= paper_->get_dimension (ly_symbol2scm ("foot-sep"));
191 if (unsmob_stencil (copyright_))
192 h -= unsmob_stencil (copyright_)->extent (Y_AXIS).length ();
193 if (unsmob_stencil (tagline_))
194 h -= unsmob_stencil (tagline_)->extent (Y_AXIS).length ();
195 if (unsmob_stencil (footer_))
196 h -= unsmob_stencil (footer_)->extent (Y_AXIS).length ();
200 LY_DEFINE (ly_page_paper_lines, "ly:page-paper-lines",
202 "Return paper-lines from PAGE.")
204 Page *p = unsmob_page (page);
205 SCM_ASSERT_TYPE (p, page, SCM_ARG1, __FUNCTION__, "page");