racket/draw: fix baseline on font substitution in "combine" mode

This commit is contained in:
Matthew Flatt 2011-04-08 11:39:41 -06:00
parent e0db3ed2e3
commit 114c64765d

View File

@ -1244,7 +1244,7 @@
;; This is combine mode. It has to be a little complicated, after all,
;; because we may need to implement font substitution ourselves, which
;; breaks the string into multiple layouts.
(let loop ([s s] [w 0.0] [h 0.0] [d 0.0] [a 0.0])
(let loop ([s s] [draw? draw?] [measured? #f] [w 0.0] [h 0.0] [d 0.0] [a 0.0])
(cond
[(not s)
(when rotate? (cairo_restore cr))
@ -1280,12 +1280,25 @@
;; find a face that works for the long character:
(install-alternate-face (string-ref s 0) layout font desc attrs context))
(substring s (max 1 ok-count))))])
(cond
[(and draw? next-s (not measured?))
;; It's going to take multiple layouts, so first gather measurements.
(let-values ([(w2 h d a) (loop s #f #f w h d a)])
;; draw again, supplying `h', `d', and `a' for the whole line
(loop s #t #t w h d a))]
[else
(let ([logical (make-PangoRectangle 0 0 0 0)])
(pango_layout_get_extents layout #f logical)
(let ([nh (/ (PangoRectangle-height logical) (exact->inexact PANGO_SCALE))]
[nd (/ (- (PangoRectangle-height logical)
(pango_layout_get_baseline layout))
(exact->inexact PANGO_SCALE))])
(when draw?
(let ([bl (/ (pango_layout_get_baseline layout) (exact->inexact PANGO_SCALE))])
(let ([bl (if measured? (- h d) (- nh nd))])
(pango_layout_get_extents layout #f logical)
(cairo_move_to cr (text-align-x/delta (+ x w) 0) (text-align-y/delta (+ y bl) 0))
(cairo_move_to cr
(text-align-x/delta (+ x w) 0)
(text-align-y/delta (+ y bl) 0))
;; Draw the text:
(pango_cairo_show_layout_line cr (pango_layout_get_line_readonly layout 0))))
(cond
@ -1296,12 +1309,8 @@
(let ([nw (if blank?
0.0
(integral (/ (PangoRectangle-width logical) (exact->inexact PANGO_SCALE))))]
[nh (/ (PangoRectangle-height logical) (exact->inexact PANGO_SCALE))]
[nd (/ (- (PangoRectangle-height logical)
(pango_layout_get_baseline layout))
(exact->inexact PANGO_SCALE))]
[na 0.0])
(loop next-s (+ w nw) (max h nh) (max d nd) (max a na)))]))))]))
(loop next-s measured? draw? (+ w nw) (max h nh) (max d nd) (max a na)))])))])))]))
;; This is character-by-character mode. It uses a cached per-character+font layout
;; object.
(let ([cache (if (or combine?