dc<%>: fix baseline for slow-path non-combined text drawing

For example, fix baseline when drawing "a\u2144" with the
default fonr under Windows, where #\u2144 is subtituted from
another font.
This commit is contained in:
Matthew Flatt 2013-02-04 18:58:00 -07:00
parent 442f6eaaae
commit c17c7cd1b0

View File

@ -1501,52 +1501,68 @@
(free log-clusters) (free log-clusters)
#t))))) #t)))))
;; We use the slower, per-layout way: ;; We use the slower, per-layout way:
(for/fold ([w 0.0][h 0.0][d 0.0][a 0.0]) (let* ([query-and-cache
([ch (in-string s)]) (lambda (ch layout)
(let ([layout (vector-ref (hash-ref layouts (char->integer ch)) 0)]) (let ([logical (make-PangoRectangle 0 0 0 0)])
(let-values ([(lw lh ld la flh) (pango_layout_get_extents layout #f logical)
(let ([v (and cache (hash-ref cache (char->integer ch) #f))]) (let ([baseline (pango_layout_get_baseline layout)]
(if v [orig-h (PangoRectangle-height logical)])
;; Used cached size: (let ([lw (force-hinting
(values (vector-ref v 0) (/ (PangoRectangle-width logical)
(vector-ref v 1) (exact->inexact PANGO_SCALE)))]
(vector-ref v 2) [flh (/ orig-h (exact->inexact PANGO_SCALE))]
(vector-ref v 3) [ld (exact->inexact (/ (- orig-h baseline) (exact->inexact PANGO_SCALE)))]
(vector-ref v 6)) [la 0.0])
;; Query and record size: (let ([lh (ceiling flh)])
(let ([logical (make-PangoRectangle 0 0 0 0)]) (when cache
(pango_layout_get_extents layout #f logical) (hash-set! cache (char->integer ch)
(let ([baseline (pango_layout_get_baseline layout)] (vector lw lh ld la
[orig-h (PangoRectangle-height logical)]) ;; baseline in Pango units; for fast path
(let ([lw (force-hinting baseline
(/ (PangoRectangle-width logical) ;; rounded width in Pango units; for fast path
(exact->inexact PANGO_SCALE)))] (inexact->exact
[flh (/ orig-h (exact->inexact PANGO_SCALE))] (floor (* lw (->fl PANGO_SCALE))))
[ld (exact->inexact (/ (- orig-h baseline) (exact->inexact PANGO_SCALE)))] ;; unrounded height, for slow-path alignment
[la 0.0]) flh)))
(let ([lh (ceiling flh)]) (values lw lh ld la flh))))))]
(when cache [bl
(hash-set! cache (char->integer ch) (if draw-mode
(vector lw lh ld la ;; For drawing, need to compute baseline first:
;; baseline in Pango units; for fast path (for/fold ([h 0.0]) ([ch (in-string s)])
baseline (let ([layout (vector-ref (hash-ref layouts (char->integer ch)) 0)])
;; rounded width in Pango units; for fast path (max (let ([v (and cache (hash-ref cache (char->integer ch) #f))])
(inexact->exact (if v
(floor (* lw (->fl PANGO_SCALE)))) ;; Used cached size:
;; unrounded height, for slow-path alignment (- (vector-ref v 6) (vector-ref v 2))
flh))) ;; Query and record size:
(values lw lh ld la flh)))))))]) (let-values ([(lw lh ld la flh) (query-and-cache ch layout)])
(when draw-mode (- flh ld))))
(cairo_move_to cr h)))
(text-align-x/delta (+ x w) 0) 0.0)])
(let ([bl (- flh ld)]) (for/fold ([w 0.0] [h 0.0] [d 0.0] [a 0.0])
(text-align-y/delta (+ y bl) 0))) ([ch (in-string s)])
;; Here's the draw command, which uses most of the time in this mode: (let ([layout (vector-ref (hash-ref layouts (char->integer ch)) 0)])
(let ([line (pango_layout_get_line_readonly layout 0)]) (let-values ([(lw lh ld la flh)
(if (eq? draw-mode 'draw) (let ([v (and cache (hash-ref cache (char->integer ch) #f))])
(pango_cairo_show_layout_line cr line) (if v
(pango_cairo_layout_line_path cr line)))) ;; Used cached size:
(values (if blank? 0.0 (+ w lw)) (max h lh) (max d ld) (max a la)))))) (values (vector-ref v 0)
(vector-ref v 1)
(vector-ref v 2)
(vector-ref v 3)
(vector-ref v 6))
;; Query and record size:
(query-and-cache ch layout)))])
(when draw-mode
(cairo_move_to cr
(text-align-x/delta (+ x w) 0)
(text-align-y/delta (+ y bl) 0))
;; Here's the draw command, which uses most of the time in this mode:
(let ([line (pango_layout_get_line_readonly layout 0)])
(if (eq? draw-mode 'draw)
(pango_cairo_show_layout_line cr line)
(pango_cairo_layout_line_path cr line))))
(values (if blank? 0.0 (+ w lw)) (max h lh) (max d ld) (max a la)))))))
(when rotate? (cairo_restore cr)))))))) (when rotate? (cairo_restore cr))))))))
(define/private (extract-only-run layout vec) (define/private (extract-only-run layout vec)