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}:
@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].
@ -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.
}
@deftogether[(@defthing[#:kind "attribute" font-size symbol?]
@defthing[#:kind "attribute" font-size-adjust symbol?])]{
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-size 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).
}
@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).
}
@deftogether[(@defthing[#:kind "attribute" line-height symbol?]
@defthing[#:kind "attribute" line-height-adjust 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.
@defthing[#:kind "attribute" line-height symbol?]{
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

@ -22,10 +22,11 @@
[#false str] ; a string other than a dimension string, so leave it
[(list _ num-string unit)
((match unit
[(regexp #rx"(pt|point)(s)?$") values]
[(regexp #rx"in(ch(es)?)?$") in->pts]
[(regexp #rx"cm$") (compose1 in->pts cm->in)]
[(regexp #rx"mm$") (compose1 in->pts cm->in mm->cm)]
[(regexp #rx"(pt|point)(s)?$") values] ; points
[(regexp #rx"in(ch(es)?)?$") in->pts] ; inches
[(regexp #rx"cms?$") (compose1 in->pts cm->in)] ; 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))])]))
(define (copy-block-attrs source-hash dest-hash)
@ -66,7 +67,6 @@ Naming guidelines
(define-attrs (font-family
font-path
font-size
font-size-adjust
font-color
font-features
font-features-adjust
@ -79,7 +79,6 @@ Naming guidelines
link
href
line-height
line-height-adjust
hyphenate
list-index
no-colbr
@ -226,4 +225,4 @@ Naming guidelines
:pdf-keywords)) #true))
(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))
(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
pstr
(string? pstr)
(string-suffix? pstr "%")
(/ (string->number (string-trim pstr "%")) 100.0)))
(string-suffix? pstr suffix)
(string->number (string-trim pstr suffix))))
(define (adjuster-base attrs key adjustment-key default-value)
;; font size and line height use this helper.
;; because they both can be specified directly,
;; or as an "adjustment" to the parent value, in which case
;; 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 (parse-percentage pstr)
(match (parse-adjustment pstr "%")
[#false #false]
[res (/ res 100.0)]))
(define (resolve-font-size! attrs)
;; 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)
;; 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)
;; if it's a percentage, we need to look at the font size.

@ -105,7 +105,9 @@
resolve-font-path!
resolve-font-size!
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!))])
(proc attrs)))

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

Loading…
Cancel
Save