Added get-path-bounding-box take 2

This commit is contained in:
Jens Axel Søgaard 2013-08-10 23:09:15 +02:00
parent 61a4c85d0d
commit ac37ccb79c
5 changed files with 65 additions and 18 deletions

View File

@ -630,12 +630,12 @@ Returns a rectangle that encloses the paths points.
The return values are the left, top, width, and, height of the rectangle. The return values are the left, top, width, and, height of the rectangle.
The numbers are in logical coordinates. The numbers are in logical coordinates.
For the type @racket['stroke] the rectangle covers the area that would be affected ("inked") For the type @racket['stroke] the rectangle covers the area that would be affected (``inked'')
when drawn with the current pen by draw-path in the drawing context (with a transparent brush). when drawn with the current pen by draw-path in the drawing context (with a transparent brush).
If the pen width is zero, then an empty rectangle will be returned. The size and clipping of the If the pen width is zero, then an empty rectangle will be returned. The size and clipping of the
drawing context is ignored. drawing context is ignored.
For the type @racket['fill] the rectangle covers the area that would be affected ("inked") For the type @racket['fill] the rectangle covers the area that would be affected (``inked'')
by draw-path in the drawing context (with a non-transparent pen and brush). If the line width by draw-path in the drawing context (with a non-transparent pen and brush). If the line width
is zero, then an empty rectangle will be returned. The size and clipping of the drawing is zero, then an empty rectangle will be returned. The size and clipping of the drawing
context are ignored. context are ignored.
@ -643,9 +643,9 @@ context are ignored.
For the type @racket['path] the rectangle covers the path, but the pen and brush are ignored. For the type @racket['path] the rectangle covers the path, but the pen and brush are ignored.
The size and clipping of the drawing context are also ignored. The size and clipping of the drawing context are also ignored.
More precisely: The result is defined as the limit of the bounding boxes returned More precisely: The result is defined as the limit of the bounding boxes returned
by the 'stroke type for line widths approaching 0 with a round pen cap. The "limit by the @racket['stroke] type for line widths approaching 0 with a round pen cap. The ``limit
process" stops when an empty rectangle is returned. This that zero-area segments contributes process'' stops when an empty rectangle is returned. This implies that zero-area segments
the rectangle. contributes to the rectangle.
For all types if the path is empty, then an empty rectangle @racket[(values 0 0 0 0)] For all types if the path is empty, then an empty rectangle @racket[(values 0 0 0 0)]
will be returned. will be returned.

View File

@ -191,7 +191,7 @@
(do-path cr align-x align-y) (do-path cr align-x align-y)
(define-values (x1 y1 x2 y2) (cairo_op cr)) (define-values (x1 y1 x2 y2) (cairo_op cr))
(cairo_restore cr) (cairo_restore cr)
(values x1 y1 y2 y2)))) (values x1 y1 (- x2 x1) (- y2 y1)))))
(define/public (move-to x y) (define/public (move-to x y)
(when (or (pair? open-points) (when (or (pair? open-points)

View File

@ -801,7 +801,7 @@
(cairo_pattern_destroy p)) (cairo_pattern_destroy p))
;; Stroke, fill, and flush the current path ;; Stroke, fill, and flush the current path
(define/private (draw cr brush? pen?) (define/private (draw cr brush? pen? [do? #t])
(define (install-stipple st col mode transformation get put) (define (install-stipple st col mode transformation get put)
(let ([s (cond (let ([s (cond
[(get) => (lambda (s) s)] [(get) => (lambda (s) s)]
@ -987,10 +987,10 @@
[(miter) CAIRO_LINE_JOIN_MITER] [(miter) CAIRO_LINE_JOIN_MITER]
[(round) CAIRO_LINE_JOIN_ROUND] [(round) CAIRO_LINE_JOIN_ROUND]
[(bevel) CAIRO_LINE_JOIN_BEVEL])) [(bevel) CAIRO_LINE_JOIN_BEVEL]))
(cairo_stroke cr) (and do? (cairo_stroke cr))
(unless (or (eq? s 'solid) (eq? s 'xor)) (unless (or (eq? s 'solid) (eq? s 'xor))
(cairo_set_dash cr #() 0))))) (cairo_set_dash cr #() 0)))))
(flush-cr)) (and do? (flush-cr)))
(define/private (do-draw-arc who (define/private (do-draw-arc who
x y x y
@ -1141,8 +1141,14 @@
(with-cr (with-cr
(values 0. 0. 0. 0.) (values 0. 0. 0. 0.)
cr cr
(send path do-get-path-bounding-box cr type (let ()
(lambda (x) (align-x x)) (lambda (y) (align-y y))))) (cairo_save cr)
(draw cr #t #t #f)
(define-values (x y w h)
(send path do-get-path-bounding-box cr type
(lambda (x) (align-x x)) (lambda (y) (align-y y))))
(cairo_restore cr)
(values x y w h))))
(def/public (draw-spline [real? x1] [real? y1] [real? x2] [real? y2] [real? x3] [real? y3]) (def/public (draw-spline [real? x1] [real? y1] [real? x2] [real? y2] [real? x3] [real? y3])
(with-cr (with-cr

View File

@ -465,12 +465,7 @@
-> (values x1 y1 x2 y2)) -> (values x1 y1 x2 y2))
;; cairo_path_extents is in version 1.6 and later ;; cairo_path_extents is in version 1.6 and later
#:fail (lambda () #:fail (lambda ()
(let ([warned? #f]) cairo_stroke_extents))
(lambda (cr)
(unless warned?
(log-warning "cairo_path_extents is unavailable; returning the empty rectangle")
(set! warned? #t))
(values 0 0 0 0)))))
(define-enum 0 (define-enum 0
CAIRO_PATH_MOVE_TO CAIRO_PATH_MOVE_TO

View File

@ -1,4 +1,3 @@
(load-relative "loadtest.rktl") (load-relative "loadtest.rktl")
(require racket/gui/base) (require racket/gui/base)
@ -704,6 +703,53 @@
(test #f 'no (send r in-region? 5 5)) (test #f 'no (send r in-region? 5 5))
(test #t 'yes (send r in-region? 105 105))) (test #t 'yes (send r in-region? 105 105)))
;; ----------------------------------------
;; Test get-path-bounding-box
(define (test-square-bounding-boxes)
(define-syntax (box stx)
(syntax-case stx ()
[(_ expr ...)
#'(let-values ([(left top width height) expr ...])
(list left top width height))]))
(define dp ; a-square-path
(let ([dp (new dc-path%)])
(send dp move-to 10 20)
(send dp line-to 30 20)
(send dp line-to 30 50)
(send dp line-to 10 50)
(send dp line-to 10 20)
(send dp close)
dp))
(define bm (make-object bitmap% 100 100))
(define dc (new bitmap-dc% [bitmap bm]))
(send dc set-brush (send the-brush-list find-or-create-brush "red" 'solid))
(send dc set-smoothing 'smoothed)
(define (bbs pen-width)
(send dc set-pen (send the-pen-list find-or-create-pen "black" pen-width 'solid
'projecting 'round))
(define bb (box (send dp get-bounding-box)))
(define bb-path (box (send dc get-path-bounding-box dp 'path)))
(define bb-stroke (box (send dc get-path-bounding-box dp 'stroke)))
(define bb-fill (box (send dc get-path-bounding-box dp 'fill)))
(values bb bb-path bb-stroke bb-fill))
(define (inside? b1 b2) ; is b2 inside b1?
(match-define (list x y w h) b1)
(match-define (list s t a b) b2)
(and (< x s) (< y t) (> w a) (> h a)))
(define (test w)
(define-values (n p s f) (bbs w))
(when (= w 0) (set! w 1)) ; 1 is the hair line width
(and (inside? s p) ; p ignores pen width, s does not
(equal? n (list 10. 20. 20. 30.))
(equal? p n); no control points outside the convex hull
(equal? s (list (- 10. (/ w 2)) (- 20. (/ w 2)) (+ 20. w) (+ 30. w)))
(equal? p f)))
(and (test 10) (test 1) (test 0)))
(test #t 'get-path-bounding-box (test-square-bounding-boxes))
;; ---------------------------------------- ;; ----------------------------------------