consolidate font-size and line-height attributes (addresses #45)

main
Matthew Butterick 4 years ago
parent d72ffdd90d
commit eef839b1ce

@ -0,0 +1,7 @@
#lang quadwriter
'(q ((column-count "2")(font-size "18")(line-height "2em")) "The lines in both columns should be vertically aligned. The column on the left is font size 18pt with line height 2em, or 36pt. The right column is font size 50%, or 9pt, with line height 4em, or 36pt."
(q ((break "column")))
(q ((break "para")))
(q ((font-size "50%")(line-height "4em")) "The lines in both columns should be vertically aligned. The column on the left is font size 18pt with line height 2em, or 36pt. The right column is font size 50%, or 9pt, with line height 4em, or 36pt."))

@ -118,7 +118,7 @@ Next, on the REPL enter this:
You will see the actual input to Quadwriter, which is called a @tech{Q-expression}: You will see the actual input to Quadwriter, which is called a @tech{Q-expression}:
@repl-output{ @repl-output{
'(q () (q ((page-margin-left "120") (page-margin-top "80") (page-margin-bottom "120") (font-family "text") (line-height "17")) (q ((keep-first-lines "2") (keep-last-lines "3") (font-size-adjust "100%") (character-tracking "0") (hyphenate "true") (display "g49598")) "Brennan and Dale like fancy sauce."))) '(q () (q ((page-margin-left "120") (page-margin-top "80") (page-margin-bottom "120") (font-family "text") (line-height "17")) (q ((keep-first-lines "2") (keep-last-lines "3") (font-size "100%") (character-tracking "0") (hyphenate "true") (display "g49598")) "Brennan and Dale like fancy sauce.")))
} }
In the demos that follow, the input language will change slightly. But the PDF will be rendered the same way (by running the source file) and you can always look at @racket[doc] or use @racket[view-output]. In the demos that follow, the input language will change slightly. But the PDF will be rendered the same way (by running the source file) and you can always look at @racket[doc] or use @racket[view-output].
@ -625,9 +625,8 @@ Specify a quad with an image (either @racket{.png} or @racket{.jpeg}). @racket[i
Sets the display type. Value is a string. Supply @racket["block"] as a value of this attribute to make the quad behave as a block-level element. Sets the display type. Value is a string. Supply @racket["block"] as a value of this attribute to make the quad behave as a block-level element.
} }
@deftogether[(@defthing[#:kind "attribute" font-size symbol?] @defthing[#:kind "attribute" font-size symbol?]{
@defthing[#:kind "attribute" font-size-adjust symbol?])]{ Sets the point size for text. Value is a @tech{dimension string}, a string representing a percentage (like @racket["120%"]), or an em size (like @racket["1.2em"]). If a percentage or em size is provided, the font size is the size of the parent multiplied by the percentage (or em).
Two ways of setting the point size for text. @racket[font-size] takes a @tech{dimension string}. @racket[font-size-adjust] takes a string representing a percentage (like @racket["120%"]) and sets the font size to the size of the parent, multiplied by the percentage.
} }
@defthing[#:kind "attribute" font-family symbol?]{ @defthing[#:kind "attribute" font-family symbol?]{
@ -666,9 +665,9 @@ Vertical offset of font baseline (positive values move the baseline up, negative
Case transformation of string. Possibilities are @racket["uppercase"], @racket["lowercase"], or @racket["capitalize"] (= first letter of each word is uppercase, the rest is lowercase). Case transformation of string. Possibilities are @racket["uppercase"], @racket["lowercase"], or @racket["capitalize"] (= first letter of each word is uppercase, the rest is lowercase).
} }
@deftogether[(@defthing[#:kind "attribute" line-height symbol?]
@defthing[#:kind "attribute" line-height-adjust symbol?])]{ @defthing[#:kind "attribute" line-height symbol?]{
Two ways of setting the distance between baselines. @racket[line-height] takes a @tech{dimension string}. @racket[line-height-adjust] takes a string representing a percentage (like @racket["120%"]) and sets the line height to the line height of the parent, multiplied by the percentage. Sets the distance between baselines. Value is a @tech{dimension string}, a string representing a percentage (like @racket["120%"]), or an em size (like @racket["1.2em"]). If a percentage or em size is provided, the line height is the current font size multiplied by the percentage (or em).
} }
TK: OT feature attributes, bullet attributes TK: OT feature attributes, bullet attributes

@ -22,10 +22,11 @@
[#false str] ; a string other than a dimension string, so leave it [#false str] ; a string other than a dimension string, so leave it
[(list _ num-string unit) [(list _ num-string unit)
((match unit ((match unit
[(regexp #rx"(pt|point)(s)?$") values] [(regexp #rx"(pt|point)(s)?$") values] ; points
[(regexp #rx"in(ch(es)?)?$") in->pts] [(regexp #rx"in(ch(es)?)?$") in->pts] ; inches
[(regexp #rx"cm$") (compose1 in->pts cm->in)] [(regexp #rx"cms?$") (compose1 in->pts cm->in)] ; cm
[(regexp #rx"mm$") (compose1 in->pts cm->in mm->cm)] [(regexp #rx"mms?$") (compose1 in->pts cm->in mm->cm)] ; mm
[(regexp #rx"ems?$") (λ (num) (format "~aem" num))] ; em
[_ (raise-argument-error 'parse-dimension "dimension string" str)]) (string->number num-string))])])) [_ (raise-argument-error 'parse-dimension "dimension string" str)]) (string->number num-string))])]))
(define (copy-block-attrs source-hash dest-hash) (define (copy-block-attrs source-hash dest-hash)
@ -66,7 +67,6 @@ Naming guidelines
(define-attrs (font-family (define-attrs (font-family
font-path font-path
font-size font-size
font-size-adjust
font-color font-color
font-features font-features
font-features-adjust font-features-adjust
@ -79,7 +79,6 @@ Naming guidelines
link link
href href
line-height line-height
line-height-adjust
hyphenate hyphenate
list-index list-index
no-colbr no-colbr
@ -226,4 +225,4 @@ Naming guidelines
:pdf-keywords)) #true)) :pdf-keywords)) #true))
(define (takes-path? k) (define (takes-path? k)
(and (memq k (list :image-file)) #true)) (and (memq k (list :image-file)) #true))

@ -80,31 +80,42 @@
(define this-italic (hash-ref! attrs :font-italic #false)) (define this-italic (hash-ref! attrs :font-italic #false))
(hash-set! attrs :font-path (font-attrs->path this-font-family this-bold this-italic)))) (hash-set! attrs :font-path (font-attrs->path this-font-family this-bold this-italic))))
(define (parse-percentage pstr) (define (parse-adjustment pstr suffix)
(and (and
pstr
(string? pstr) (string? pstr)
(string-suffix? pstr "%") (string-suffix? pstr suffix)
(/ (string->number (string-trim pstr "%")) 100.0))) (string->number (string-trim pstr suffix))))
(define (adjuster-base attrs key adjustment-key default-value) (define (parse-percentage pstr)
;; font size and line height use this helper. (match (parse-adjustment pstr "%")
;; because they both can be specified directly, [#false #false]
;; or as an "adjustment" to the parent value, in which case [res (/ res 100.0)]))
;; we get the parent value and perform the adjustment.
(define this-val (hash-ref! attrs key default-value))
(define this-val-adjust (parse-percentage (hash-ref! attrs adjustment-key "100%")))
;; we bake the adjustment into the val...
(hash-set! attrs key (and this-val (* this-val this-val-adjust)))
;; and then set the adjustment back to 100% (since it's now accounted for)
(hash-set! attrs adjustment-key "100%"))
(define (resolve-font-size! attrs) (define (resolve-font-size! attrs)
;; convert font-size attributes into a simple font size ;; convert font-size attributes into a simple font size
(adjuster-base attrs :font-size :font-size-adjust default-font-size)) ;; we stashed the previous size in private key 'font-size-previous
(define prev-font-size-key 'font-size-previous)
(define val (hash-ref attrs :font-size default-font-size))
(define adjustment (or (parse-percentage val) (parse-adjustment val "em")))
;; if our value represents an adjustment, we apply the adjustment to the previous value
;; otherwise we use our value directly
(define base-size (if adjustment (hash-ref attrs prev-font-size-key default-font-size) val))
(define base-size-adjusted (and base-size (* base-size (or adjustment 1))))
;; we write our new value into both font-size and font-size-previous
;; because as we cascade down, we're likely to come across superseding values
;; of font-size (but font-size-previous will persist)
(hash-set! attrs :font-size base-size-adjusted)
(hash-set! attrs prev-font-size-key base-size-adjusted))
(define (resolve-line-height! attrs) (define (resolve-line-height! attrs)
;; convert line-height attributes into a simple line height ;; convert line-height attributes into a simple line height
(adjuster-base attrs :line-height :line-height-adjust default-line-height)) (hash-update! attrs :line-height
(λ (val)
(define adjustment (or (parse-percentage val) (parse-adjustment val "em")))
(define base-height (if adjustment (hash-ref attrs :font-size) val))
(and base-height (* base-height (or adjustment 1))))
default-line-height))
(define (resolve-font-tracking! attrs) (define (resolve-font-tracking! attrs)
;; if it's a percentage, we need to look at the font size. ;; if it's a percentage, we need to look at the font size.

@ -105,7 +105,9 @@
resolve-font-path! resolve-font-path!
resolve-font-size! resolve-font-size!
resolve-font-tracking! resolve-font-tracking!
resolve-line-height! ;; we resolve line height after font size
;; because line height might be dependent
resolve-line-height!
parse-font-features!))]) parse-font-features!))])
(proc attrs))) (proc attrs)))

@ -25,7 +25,7 @@
[_ (qexpr (append (list->attrs [_ (qexpr (append (list->attrs
:keep-first-lines "2" :keep-first-lines "2"
:keep-last-lines "3" :keep-last-lines "3"
:font-size-adjust "100%" :font-size "100%"
:hyphenate "true" :hyphenate "true"
:display (symbol->string (gensym))) :display (symbol->string (gensym)))
attrs) exprs)])) attrs) exprs)]))
@ -77,7 +77,7 @@
(define-tag-function (strong attrs exprs) (define-tag-function (strong attrs exprs)
(qexpr (append (list->attrs (qexpr (append (list->attrs
:font-bold "true" :font-bold "true"
:font-size-adjust "100%") :font-size "100%")
attrs) exprs)) attrs) exprs))
(define b strong) (define b strong)
@ -91,7 +91,7 @@
(qexpr (append (qexpr (append
(list->attrs (list->attrs
:font-italic "true" :font-italic "true"
:font-size-adjust "100%") attrs) exprs)) :font-size "100%") attrs) exprs))
(define i em) (define i em)

Loading…
Cancel
Save