;;;; This file is part of LilyPond, the GNU music typesetter.
;;;;
-;;;; Copyright (C) 2004--2010 Han-Wen Nienhuys <hanwen@xs4all.nl>
+;;;; Copyright (C) 2004--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
;;;;
;;;; LilyPond is free software: you can redistribute it and/or modify
;;;; it under the terms of the GNU General Public License as published by
;; lookup-font should be written in C.
;;
+;; We have a tree, where each level of the tree is a qualifier
+;; (eg. encoding, family, shape, series etc.) this defines the levels
+;; in the tree. The first one is encoding, so we can directly select
+;; between text or music in the first step of the selection.
+(define default-qualifier-order
+ '(font-encoding font-family font-shape font-series))
+
(define-class <Font-tree-element>
())
(make <Font-tree-leaf> #:default-size size #:size-vector size-font-vector))
(define (make-font-tree-node
- qualifier default)
+ qualifier default)
(make <Font-tree-node>
#:qualifier qualifier
#:default default
#:children (make-hash-table 11)))
(define-method (display (leaf <Font-tree-leaf>) port)
- (map (lambda (x) (display x port))
- (list
- "#<Font-size-family:\n"
- (slot-ref leaf 'default-size)
- (slot-ref leaf 'size-vector)
- "#>"
- )))
+ (for-each (lambda (x) (display x port))
+ (list
+ "#<Font-size-family:\n"
+ (slot-ref leaf 'default-size)
+ (slot-ref leaf 'size-vector)
+ "#>"
+ )))
(define-method (display (node <Font-tree-node>) port)
- (map
+ (for-each
(lambda (x)
(display x port))
(list
(hash-table->alist (font-children node)))
(display "} }\n"))
-(define default-qualifier-order
- '(font-encoding font-family font-shape font-series))
(define-method (add-font (node <Font-tree-node>) fprops size-family)
(define (assoc-delete key alist)
(define (make-node fprops size-family)
(if (null? fprops)
- (make-font-tree-leaf (car size-family) (cdr size-family))
- (let* ((qual (next-qualifier default-qualifier-order fprops)))
- (make-font-tree-node qual
- (assoc-get qual fprops)))))
+ (make-font-tree-leaf (car size-family) (cdr size-family))
+ (let* ((qual (next-qualifier default-qualifier-order fprops)))
+ (make-font-tree-node qual
+ (assoc-get qual fprops)))))
(define (next-qualifier order props)
(cond
((null? order) (caar props))
(else
(if (assoc-get (car order) props)
- (car order)
- (next-qualifier (cdr order) props)))))
+ (car order)
+ (next-qualifier (cdr order) props)))))
(let* ((q (font-qualifier node))
- (d (font-default node))
- (v (assoc-get q fprops d))
- (new-fprops (assoc-delete q fprops))
- (child (hashq-ref (slot-ref node 'children)
- v #f)))
+ (d (font-default node))
+ (v (assoc-get q fprops d))
+ (new-fprops (assoc-delete q fprops))
+ (child (hashq-ref (slot-ref node 'children)
+ v #f)))
(if (not child)
- (begin
- (set! child (make-node new-fprops size-family))
- (hashq-set! (slot-ref node 'children) v child)))
+ (begin
+ (set! child (make-node new-fprops size-family))
+ (hashq-set! (slot-ref node 'children) v child)))
(if (pair? new-fprops)
- (add-font child new-fprops size-family))))
+ (add-font child new-fprops size-family))))
(define-method (add-font (node <Font-tree-leaf>) fprops size-family)
(throw "must add to node, not leaf"))
(define-method (g-lookup-font (node <Font-tree-node>) alist-chain)
(let* ((qual (font-qualifier node))
- (def (font-default node))
- (val (chain-assoc-get qual alist-chain def))
- (desired-child (hashq-ref (font-children node) val)))
+ (def (font-default node))
+ (val (chain-assoc-get qual alist-chain def))
+ (desired-child (hashq-ref (font-children node) val)))
(if desired-child
- (g-lookup-font desired-child alist-chain)
- (g-lookup-font (hashq-ref (font-children node) def) alist-chain))))
+ (g-lookup-font desired-child alist-chain)
+ (g-lookup-font (hashq-ref (font-children node) def) alist-chain))))
(define-method (g-lookup-font (node <Font-tree-leaf>) alist-chain)
node)
(define (lookup-font node alist-chain)
(g-lookup-font node alist-chain))
-
-;; Ugh. Currently, we load the PFB Feta fonts for `fetaDynamic' with
-;; Pango. This should be changed to load the Emmentaler fonts instead
-;; (with Pango too), but then we need support for a `font-style'
-;; property which isn't implemented yet.
-(define feta-alphabet-size-vector
- (list->vector
- (map (lambda (tup)
- (cons (ly:pt (cdr tup))
- (format "feta-alphabet~a ~a"
- (car tup)
- (ly:pt (cdr tup)))))
- '((11 . 11.22)
- (13 . 12.60)
- (14 . 14.14)
- (16 . 15.87)
- (18 . 17.82)
- (20 . 20)
- (23 . 22.45)
- (26 . 25.20)))))
+;; TODO - we could actually construct this by loading all OTFs and
+;; inspecting their design size fields.
+(define-public feta-design-size-mapping
+ '((11 . 11.22)
+ (13 . 12.60)
+ (14 . 14.14)
+ (16 . 15.87)
+ (18 . 17.82)
+ (20 . 20)
+ (23 . 22.45)
+ (26 . 25.20)))
;; Each size family is a vector of fonts, loaded with a delay. The
;; vector should be sorted according to ascending design size.
-(define-public (add-music-fonts node name family design-size-list factor)
- "Add fonts to NODE. DESIGN-SIZE-LIST is a list of numbers."
+(define-public (add-music-fonts node family name brace design-size-alist factor)
+ "Set up music fonts.
+
+Arguments:
+@itemize
+@item
+@var{node} is the font tree to modify.
+
+@item
+@var{family} is the family name of the music font.
+
+@item
+@var{name} is the basename for the music font.
+@file{@var{name}-<designsize>.otf} should be the music font,
+
+@item
+@var{brace} is the basename for the brace font.
+@file{@var{brace}-brace.otf} should have piano braces.
+
+@item
+@var{design-size-alist} is a list of @code{(rounded . designsize)}.
+@code{rounded} is a suffix for font filenames, while @code{designsize}
+should be the actual design size. The latter is used for text fonts
+loaded through pango/@/fontconfig.
+
+@item
+@var{factor} is a size factor relative to the default size that is being
+used. This is used to select the proper design size for the text fonts.
+@end itemize"
(for-each
(lambda (x)
(add-font node
- (list (cons 'font-encoding (car x))
- (cons 'font-family family))
- (cons (* factor (cadr x))
- (caddr x))))
- `((fetaDynamic ,(ly:pt 20.0) ,feta-alphabet-size-vector)
- (fetaNumber ,(ly:pt 20.0) ,feta-alphabet-size-vector)
+ (list (cons 'font-encoding (car x))
+ (cons 'font-family family))
+ (cons (* factor (cadr x))
+ (caddr x))))
+
+ `((fetaText ,(ly:pt 20.0)
+ ,(list->vector
+ (map (lambda (tup)
+ (cons (ly:pt (cdr tup))
+ (format #f "~a-~a ~a"
+ name
+ (car tup)
+ (ly:pt (cdr tup)))))
+ design-size-alist)))
(fetaMusic ,(ly:pt 20.0)
- ,(list->vector
- (map (lambda (size)
- (delay (ly:system-font-load (format "~a-~a" name size))))
- design-size-list
- )))
+ ,(list->vector
+ (map (lambda (size-tup)
+ (delay (ly:system-font-load
+ (format #f "~a-~a" name (car size-tup)))))
+ design-size-alist
+ )))
(fetaBraces ,(ly:pt 20.0)
- #(,(delay (ly:system-font-load
- ;;; TODO: rename aybabtu to emmentaler-brace
- (if (string=? name "emmentaler")
- "aybabtu"
- (string-append name "-brace"))
- )))))))
+ #(,(delay (ly:system-font-load
+ (format #f "~a-brace" brace)))))
+ )))
(define-public (add-pango-fonts node lily-family family factor)
;; Synchronized with the `text-font-size' variable in
(define (add-node shape series)
(add-font node
- `((font-family . ,lily-family)
- (font-shape . ,shape)
- (font-series . ,series)
- (font-encoding . latin1) ;; ugh.
- )
- `(,text-font-size
- . #(,(cons
- (ly:pt 12)
- (ly:make-pango-description-string
- `(((font-family . ,family)
- (font-series . ,series)
- (font-shape . ,shape)))
- (ly:pt 12)))))))
+ `((font-family . ,lily-family)
+ (font-shape . ,shape)
+ (font-series . ,series)
+ (font-encoding . latin1) ;; ugh.
+ )
+ `(,text-font-size
+ . #(,(cons
+ (ly:pt 12)
+ (ly:make-pango-description-string
+ `(((font-family . ,family)
+ (font-series . ,series)
+ (font-shape . ,shape)))
+ (ly:pt 12)))))))
(add-node 'upright 'normal)
(add-node 'caps 'normal)
(add-node 'italic 'normal)
(add-node 'italic 'bold))
+; This function allows the user to change the specific fonts, leaving others
+; to the default values. This way, "make-pango-font-tree"'s syntax doesn't
+; have to change from the user's perspective.
+;
+; Usage:
+; \paper {
+; #(define fonts
+; (set-global-fonts
+; #:music "gonville" ; (the main notation font)
+; #:roman "FreeSerif" ; (the main/serif text font)
+; ))
+; }
+;
+; Leaving out "#:brace", "#:sans", and "#:typewriter" leave them at
+; "emmentaler", "sans-serif", and "monospace", respectively. All fonts are
+; still accesible through the usual scheme symbols: 'feta, 'roman, 'sans, and
+; 'typewriter.
+;
+; Note that 'LilyPond Serif', 'LilyPond Sans Serif' and 'Lilypond Monospace'
+; are aliases that are defined in mf/00-lilypond-fonts.conf.in (source file)
+; or fonts/00-lilypond-fonts.conf (installed file).
+
+(define*-public (set-global-fonts #:key
+ (music "emmentaler")
+ (brace "emmentaler")
+ (roman (if (eq? (ly:get-option 'backend) 'svg)
+ "serif" "LilyPond Serif"))
+ (sans (if (eq? (ly:get-option 'backend) 'svg)
+ "sans-serif" "LilyPond Sans Serif"))
+ (typewriter (if (eq? (ly:get-option 'backend) 'svg)
+ "monospace" "LilyPond Monospace"))
+ (factor 1))
+ (let ((n (make-font-tree-node 'font-encoding 'fetaMusic)))
+ (add-music-fonts n 'feta music brace feta-design-size-mapping factor)
+ (add-pango-fonts n 'roman roman factor)
+ (add-pango-fonts n 'sans sans factor)
+ (add-pango-fonts n 'typewriter typewriter factor)
+ n))
+
(define-public (make-pango-font-tree roman-str sans-str typewrite-str factor)
(let ((n (make-font-tree-node 'font-encoding 'fetaMusic)))
- (add-music-fonts n "emmentaler" 'feta '(11 13 14 16 18 20 23 26) factor)
-;; Let's not do this [yet], see input/regression/gonville.ly
-;; (add-music-fonts n "gonville" 'gonville factor)
+ (add-music-fonts n 'feta "emmentaler" "emmentaler" feta-design-size-mapping factor)
(add-pango-fonts n 'roman roman-str factor)
(add-pango-fonts n 'sans sans-str factor)
(add-pango-fonts n 'typewriter typewrite-str factor)
n))
-(define-public (make-century-schoolbook-tree factor)
+(define-public (make-default-fonts-tree factor)
(make-pango-font-tree
- "Century Schoolbook L,serif"
- "sans-serif" "monospace" factor))
+ (if (eq? (ly:get-option 'backend) 'svg) "serif" "LilyPond Serif")
+ (if (eq? (ly:get-option 'backend) 'svg) "sans-serif" "LilyPond Sans Serif")
+ (if (eq? (ly:get-option 'backend) 'svg) "monospace" "LilyPond Monospace")
+ factor))
(define-public all-text-font-encodings
'(latin1))
(define-public all-music-font-encodings
'(fetaBraces
- fetaDynamic
fetaMusic
- fetaNumber))
+ fetaText))
(define-public (magstep s)
(exp (* (/ s 6) (log 2))))