2004-06-13 Han-Wen Nienhuys <hanwen@xs4all.nl>
+ * input/mutopia/W.A.Mozart/mozart-hrn3-rondo.ly (rondo):
+ octavation compatibility fixes. Backportme.
+
+ * scm/page-breaking.scm (ly:optimal-page-breaks): allow overfull
+ pages.
+ (ly:optimal-page-breaks): combine-penalties: no shortcut for
+ negative. Now we handle negative penalties (ie. \pageBreak)
+ correctly.
+
* lily/system.cc (get_line): extract page-penalty from the left
bound.
piece = "Piece"
}
+pattern = { a b c d \break }
\score {
\context Staff \notes \relative c' {
%% 16: ideally cramped
%% 17: very bad without density
- \repeat unfold 17 { a b c d \break }
+% \repeat unfold 17 { a b c d \break }
+
+ \pattern
+ \pattern
+ % \noPageBreak
+ \pattern
+
+ % the following changes the location of the break.
+ %
+ % \pageBreak
+
+ \pattern
+ \pattern
+ \pattern
+ \pattern
+ \repeat unfold 10 \pattern
}
\paper {
#(set-default-paper-size "a6")
;;; This is not optimal page breaking, this is optimal distribution of
;;; lines over pages; line breaks are a given.
-;;; TODO:
-;;; - user tweaking:
-;;; + \pagebreak, \nopagebreak
-;;; + #pages?
-;;; - short circut SCORE=-1 (dismiss path)
-;;; - density scoring
-
+; TODO:
+;
+; - density scoring
+;
(define-class <optimally-broken-page-node> ()
(prev #:init-value '() #:accessor node-prev #:init-keyword #:prev)
;; FIXME, simplistic
(let* ((left (- available used))
;; scale-independent
- (relative-empty (/ left available)))
+ (relative (abs (/ left available))))
(if (negative? left)
- ;; too full
- MAXPENALTY
+
+ ;; too full, penalise more
+ (* 10 (1+ relative) relative)
+
;; Convexity: two half-empty pages is better than 1 completely
;; empty page
- (* (1+ relative-empty) relative-empty))))
+ (* (1+ relative) relative))))
(define (page-height page-number last?)
(let ((h text-height))
(get-path (node-prev node) (cons node done))
done))
- (define (add-penalties . lst)
- (if (find negative? lst) ;; todo: rm support for this
- -1
- (apply + lst)))
+ (define (combine-penalties user page prev)
+ (+ prev page user))
(define (walk-paths done-lines best-paths current-lines last? current-best)
"Return the best optimal-page-break-node that contains
(space-used (cumulative-height current-lines))
(this-page-penalty (height-penalty page-height space-used))
(user-penalty (ly:paper-line-break-penalty (car current-lines)))
- (total-penalty (add-penalties
+ (total-penalty (combine-penalties
user-penalty this-page-penalty prev-penalty))
(better? (or
(not current-best)
(let* ((best-break-node (walk-lines '() '() lines))
(break-nodes (get-path best-break-node '()))
- (break-lines (map node-lines break-nodes))
- (break-numbers (map line-number break-nodes)))
+ (break-lines (map node-lines break-nodes)))
(if (ly:get-option 'verbose)
(begin
- (format (current-error-port) "breaks: ~S\n" break-numbers)
+ (format (current-error-port) "breaks: ~S\n" (map line-number break-nodes))
(force-output (current-error-port))))
- ;; TODO: if solution is bad return no breaks and revert to
- ;; ragged bottom
break-lines))