#lang debug racket (require "attrs.rkt" "param.rkt" "log.rkt" "debug.rkt" "struct.rkt" quad/base pitfall) (provide (all-defined-out)) (define ((block-draw-start first-line) q doc) ;; adjust drawing coordinates for border inset (match-define (list bil bit bir bib) (for/list ([k (in-list (list :border-inset-left :border-inset-top :border-inset-right :border-inset-bottom))]) (quad-ref first-line k 0))) (match-define (list left top) (pt+ (quad-origin q) (list bil bit))) (match-define (list width height) (pt- (size q) (list (+ bil bir) (+ bit bib)))) ;; fill rect (let ([bgc (quad-ref first-line :background-color)]) (when bgc (rect doc left top width height) (fill doc bgc))) ;; draw border (match-define (list bw-left bw-top bw-right bw-bottom) (map (λ (k) (max 0 (quad-ref first-line k 0))) (list :border-width-left :border-width-top :border-width-right :border-width-bottom))) ;; adjust start and end points based on adjacent border width ;; so all borders overlap rectangularly (define (half x) (/ x 2.0)) (define right (+ left width)) (define bottom (+ top height)) (define (box-side x1 y1 x2 y2 color stroke-width) (when (positive? stroke-width) (move-to doc x1 y1) (line-to doc x2 y2) (stroke doc (or color "black") stroke-width))) (box-side (- left (half bw-left)) top (+ right (half bw-right)) top (quad-ref first-line :border-color-top) bw-top) (box-side right (- top (half bw-top)) right (+ bottom (half bw-bottom)) (quad-ref first-line :border-color-right) bw-right) (box-side (+ right (half bw-right)) bottom (- left (half bw-left)) bottom (quad-ref first-line :border-color-bottom) bw-bottom) (box-side left (+ bottom (half bw-bottom)) left (- top (half bw-top)) (quad-ref first-line :border-color-left) bw-left) (case (quad-ref first-line :block-clip) [(#true) (when (eq? (log-clipping?) 'warn) (for ([line (in-list (quad-elems q))]) (define line-width (pt-x (size line))) (define line-elem-width (sum-x (quad-elems line))) (when (< line-width line-elem-width) (define error-str (apply string-append (for/list ([q (in-list (quad-elems line))]) (match (quad-elems q) [(list (? string? str)) str] [_ ""])))) (log-quadwriter-warning (format "clipping overfull line: ~v" error-str))))) (save doc) (rect doc left top width height) (clip doc)])) (define ((block-draw-end first-line) q doc) (case (quad-ref first-line :block-clip) [(#true) (restore doc)]) (when (draw-debug-block?) (draw-debug q doc "#6c6" "#9c9"))) (define (insert-blocks lines) (define groups-of-lines (contiguous-group-by (λ (x) (quad-ref x :display)) lines)) (append* (for/list ([line-group (in-list groups-of-lines)]) (if (quad-ref (car line-group) :display) (list (lines->block line-group)) line-group)))) (define (lines->block lines) (match lines [(cons line _) (make-quad #:type block-quad #:from 'sw #:to 'nw #:elems (from-parent lines 'nw) #:tag 'block #:attrs (quad-attrs line) #:size (delay (pt (pt-x (size line)) ; (+ (sum-y lines) (quad-ref line :inset-top 0) (quad-ref line :inset-bottom 0)))) #:shift-elems (pt 0 (quad-ref line :inset-top 0)) #:draw-start (block-draw-start line) #:draw-end (block-draw-end line))]))