Added get-path-bounding-box.

This commit is contained in:
Jens Axel Søgaard 2013-08-10 19:46:42 +02:00
parent 13e7f2f03d
commit 61a4c85d0d
4 changed files with 92 additions and 1 deletions

View File

@ -621,6 +621,36 @@ See also @method[dc<%> set-origin] and @method[dc<%> get-transformation].
Gets the current pen. See also @method[dc<%> set-pen].
}
@defmethod[(get-path-bounding-box [path (is-a?/c dc-path%)]
[type (or/c 'path 'stroke 'fill)])
(values real? real? real? real?)]{
Returns a rectangle that encloses the paths points.
The return values are the left, top, width, and, height of the rectangle.
The numbers are in logical coordinates.
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).
If the pen width is zero, then an empty rectangle will be returned. The size and clipping of the
drawing context is ignored.
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
is zero, then an empty rectangle will be returned. The size and clipping of the drawing
context 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.
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
process" stops when an empty rectangle is returned. This that zero-area segments contributes
the rectangle.
For all types if the path is empty, then an empty rectangle @racket[(values 0 0 0 0)]
will be returned.
}
@defmethod[(get-rotation) real?]{

View File

@ -33,7 +33,7 @@
(define dc-path%
(class object%
;; A path is a list of pairs and vectors:
;; * The pairs corerspond to points on the path
;; * The pairs correspond to points on the path
;; * A vector must be between two pairs; it specifies
;; control points for a curve between the two points.
@ -173,6 +173,26 @@
(max b (vector-ref p 1) (vector-ref p 3)))]))])
(values l t (- r l) (- b t))))))
(define/public (do-get-path-bounding-box cr type align-x align-y)
(flatten-closed!)
(flatten-open!)
(if (and (null? closed-points)
(null? open-points)
(not cr))
(values 0. 0. 0. 0.)
(let ()
(define cairo_op
(cond
[(eq? type 'path) cairo_path_extents]
[(eq? type 'fill) cairo_fill_extents]
[(eq? type 'stroke) cairo_stroke_extents]
[else (error 'get-tight-binding-boc "expected 'path, 'fill, or, 'stroke")]))
(cairo_save cr)
(do-path cr align-x align-y)
(define-values (x1 y1 x2 y2) (cairo_op cr))
(cairo_restore cr)
(values x1 y1 y2 y2))))
(define/public (move-to x y)
(when (or (pair? open-points)
(pair? rev-open-points))

View File

@ -1134,6 +1134,15 @@
(rounded-rect x y (sub1w width) (sub1h height)
(lambda (x) (align-x x)) (lambda (y) (align-y y)))
(draw cr #f #t)))))
(define (bounding-box-type? o) (member o '(path fill stroke)))
(def/public (get-path-bounding-box [dc-path% path] [bounding-box-type? type])
(with-cr
(values 0. 0. 0. 0.)
cr
(send path do-get-path-bounding-box cr type
(lambda (x) (align-x x)) (lambda (y) (align-y y)))))
(def/public (draw-spline [real? x1] [real? y1] [real? x2] [real? y2] [real? x3] [real? y3])
(with-cr

View File

@ -125,6 +125,22 @@
(set! warned? #t))
(values 0 0 0 0)))))
(define-cairo cairo_fill_extents (_cfun _cairo_t
(x1 : (_ptr o _double))
(y1 : (_ptr o _double))
(x2 : (_ptr o _double))
(y2 : (_ptr o _double))
-> _void
-> (values x1 y1 x2 y2)))
(define-cairo cairo_stroke_extents (_cfun _cairo_t
(x1 : (_ptr o _double))
(y1 : (_ptr o _double))
(x2 : (_ptr o _double))
(y2 : (_ptr o _double))
-> _void
-> (values x1 y1 x2 y2)))
;; Transforms
(define-cairo cairo_translate (_cfun _cairo_t _double* _double* -> _void))
(define-cairo cairo_scale (_cfun _cairo_t _double* _double* -> _void))
@ -440,6 +456,22 @@
(define-cairo cairo_copy_path (_cfun _cairo_t -> _cairo_path_t-pointer)
#:wrap (allocator cairo_path_destroy))
(define-cairo cairo_path_extents (_cfun _cairo_t
(x1 : (_ptr o _double))
(y1 : (_ptr o _double))
(x2 : (_ptr o _double))
(y2 : (_ptr o _double))
-> _void
-> (values x1 y1 x2 y2))
;; cairo_path_extents is in version 1.6 and later
#:fail (lambda ()
(let ([warned? #f])
(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
CAIRO_PATH_MOVE_TO
CAIRO_PATH_LINE_TO