fix region bounding-box and hit-test; catch up docs
This commit is contained in:
parent
d10669d34e
commit
e0a2a66dc8
|
@ -19,7 +19,7 @@
|
|||
(define region%
|
||||
(class object%
|
||||
|
||||
(init [the-dc #f])
|
||||
(init [(the-dc dc) #f])
|
||||
(define dc the-dc)
|
||||
(when dc
|
||||
(unless (dc . is-a? . dc<%>)
|
||||
|
@ -62,7 +62,36 @@
|
|||
[r r]
|
||||
[b b])
|
||||
(if (null? paths)
|
||||
(values l t r b)
|
||||
(if matrix
|
||||
;; Convert absolute coordinates back to the DC's
|
||||
;; logical space by inverting its transformation
|
||||
(let ([m (send dc get-clipping-matrix)])
|
||||
;; Matrix is [ma mc
|
||||
;; mb md]
|
||||
(let ([ma (vector-ref m 0)]
|
||||
[mb (vector-ref m 2)]
|
||||
[mc (vector-ref m 1)]
|
||||
[md (vector-ref m 3)]
|
||||
[dx (vector-ref m 4)]
|
||||
[dy (vector-ref m 5)])
|
||||
(let ([det (- (* ma md) (* mb mc))])
|
||||
(if (zero? det)
|
||||
;; determinant is 0 => dc's matrix maps any area to 0
|
||||
(values 0.0 0.0 0.0 0.0)
|
||||
;; tx and ty apply inverse matrix
|
||||
(let ([tx (lambda (x y)
|
||||
(let ([x (- x dx)]
|
||||
[y (- y dy)])
|
||||
(/ (- (* md x) (* mb y)) det)))]
|
||||
[ty (lambda (x y)
|
||||
(let ([x (- x dx)]
|
||||
[y (- y dy)])
|
||||
(/ (- (* ma y) (* mc x)) det)))])
|
||||
;; unwind bound-box points to pre-transformed
|
||||
(values (tx l t) (ty l t)
|
||||
(tx r b) (ty r b)))))))
|
||||
;; no dc un-transformation needed
|
||||
(values l t r b))
|
||||
(let-values ([(l2 t2 r2 b2) (send (caar paths) get-bounding-box)])
|
||||
(loop (cdr paths)
|
||||
(min l l2)
|
||||
|
@ -126,7 +155,19 @@
|
|||
(set! temp-cr
|
||||
(cairo_create
|
||||
(cairo_image_surface_create CAIRO_FORMAT_A8 1 1))))
|
||||
(install-region temp-cr #t (lambda (cr v) (and v (cairo_in_fill temp-cr x y)))))))
|
||||
(let-values ([(x y)
|
||||
(if matrix
|
||||
;; need to use the DC's current transformation
|
||||
(let ([m (send dc get-clipping-matrix)])
|
||||
(values (+ (* x (vector-ref m 0))
|
||||
(* y (vector-ref m 2))
|
||||
(vector-ref m 4))
|
||||
(+ (* x (vector-ref m 1))
|
||||
(* y (vector-ref m 3))
|
||||
(vector-ref m 5))))
|
||||
;; no transformation needed
|
||||
(values x y))])
|
||||
(install-region temp-cr #t (lambda (cr v) (and v (cairo_in_fill temp-cr x y))))))))
|
||||
|
||||
(def/public (set-arc [real? x]
|
||||
[real? y]
|
||||
|
|
|
@ -7,40 +7,51 @@ A @scheme[region%] object specifies a portion of a drawing area
|
|||
(possibly discontinuous). It is normally used for clipping drawing
|
||||
operations.
|
||||
|
||||
Each @scheme[region%] object is associated to a particular
|
||||
@scheme[dc<%>] object, specified when the region is created. A region
|
||||
can only be used with its associated @scheme[dc<%>] object. The origin
|
||||
and scale of a drawing context determine the bounding box and drawing
|
||||
location of a region at the time that a region is created (or set); a
|
||||
region is independent of the current scale and origin when the region
|
||||
is used. For an auto-scrolled canvas, the canvas's current scrolling
|
||||
applies when the region is used (and it does not affect the region's
|
||||
bounding box).
|
||||
A @scheme[region%] object can be associated to a particular
|
||||
@scheme[dc<%>] object when the region is created. In that case, the
|
||||
region uses the drawing context's current transformation matrix,
|
||||
translation, scaling, and rotation, independent of the transformation
|
||||
that is in place when the region is installed. Otherwise, the region
|
||||
is transformed as usual when it is installed into a
|
||||
@scheme[dc<%>]. For an auto-scrolled canvas, the canvas's current
|
||||
scrolling always applies when the region is used (and it does not
|
||||
affect the region's bounding box).
|
||||
|
||||
Region combination with operations like @racket[region% union] are
|
||||
approximate, and they are implemented by combining paths. Certain
|
||||
combinations work only if the paths have a suitable fill mode, which
|
||||
can be either @racket['winding], @racket['even-odd], or a
|
||||
@deftech{flexible fill} mode. When a region is installed as a device
|
||||
context's clipping region, any subpath with a @deftech{flexible fill}
|
||||
mode uses @racket['even-odd] mode if any other path uses
|
||||
@racket['even-odd] mode.
|
||||
|
||||
See also @xmethod[dc<%> set-clipping-region] and @xmethod[dc<%>
|
||||
get-clipping-region].
|
||||
|
||||
|
||||
@defconstructor[([dc (is-a?/c dc<%>)])]{
|
||||
@defconstructor[([dc (or/c (is-a?/c dc<%>) #f)])]{
|
||||
|
||||
Creates an empty region.
|
||||
Creates an empty region. If @racket[dc] is a @scheme[dc<%>] object,
|
||||
the @scheme[dc<%>]'s current transformation matrix is essentially
|
||||
recorded in the region.
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(get-bounding-box)
|
||||
(values real? real? real? real?)]{
|
||||
|
||||
Returns a rectangle that encloses the region. The return values are
|
||||
the left, top, width, and height of the rectangle. The bounding box
|
||||
is precisely correct for unsmoothed drawing, but it is only
|
||||
approximate for smoothed drawing.
|
||||
Returns a rectangle that approximately encloses the region. The
|
||||
return values are the left, top, width, and height of the
|
||||
rectangle. If the region has an associated drawing context, the
|
||||
bounding box is in the drawing context's current logical coordinates.
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(get-dc)
|
||||
(is-a?/c dc<%>)]{
|
||||
(or/c (is-a?/c dc<%>) #f)]{
|
||||
|
||||
Returns the region's drawing context.
|
||||
Returns the region's drawing context, if it was created for one.
|
||||
|
||||
}
|
||||
|
||||
|
@ -49,12 +60,9 @@ Returns the region's drawing context.
|
|||
boolean?]{
|
||||
|
||||
Returns @scheme[#t] if the given point is approximately within the
|
||||
region, @scheme[#f] otherwise. The given point is scaled and
|
||||
translated according to the region's @scheme[dc<%>]'s current scale
|
||||
and translation.
|
||||
|
||||
The approximate in-region test represents the true result for
|
||||
unsmoothed drawing, but it not necessarily for smoothed drawing.
|
||||
region, @scheme[#f] otherwise. If the region has an associated
|
||||
drawing context, the given point is effectively transformed according
|
||||
to the region's @scheme[dc<%>]'s current transformation matrix.
|
||||
|
||||
}
|
||||
|
||||
|
@ -63,18 +71,18 @@ The approximate in-region test represents the true result for
|
|||
|
||||
Sets the region to the intersection of itself with the given region.
|
||||
|
||||
The DC of @scheme[rgn] and @this-obj[] must be the same.
|
||||
The drawing context of @scheme[rgn] and @this-obj[] must be the same,
|
||||
or they must both be unassociated to any drawing context.
|
||||
|
||||
The result is always reliable for unsmoothed and smoothed drawing. For
|
||||
smoothed drawing, an intersect corresponds to clipping with this
|
||||
region's path, and then clipping with the given region's path.
|
||||
Further combining sends to this region correspond to combination with
|
||||
the original path before initial clip, and further combination with
|
||||
this region as an argument correspond to a combination with the given
|
||||
path after the initial clip. Thus, an intersecting region is a poor
|
||||
input for @method[region% union], @method[region% subtract], or
|
||||
@method[region% xor], but it intersects properly in further calls to
|
||||
@method[region% intersect].
|
||||
An intersect corresponds to clipping with this region's path, and then
|
||||
clipping with the given region's path. Further combining sends to
|
||||
this region correspond to combination with the original path before
|
||||
initial clip, and further combination with this region as an argument
|
||||
correspond to a combination with the given path after the initial
|
||||
clip. Thus, an intersecting region is a poor input for
|
||||
@method[region% union], @method[region% subtract], or @method[region%
|
||||
xor], but it intersects properly in further calls to @method[region%
|
||||
intersect].
|
||||
|
||||
}
|
||||
|
||||
|
@ -82,8 +90,7 @@ The result is always reliable for unsmoothed and smoothed drawing. For
|
|||
boolean?]{
|
||||
|
||||
Returns @scheme[#t] if the region is approximately empty, @scheme[#f]
|
||||
otherwise. An approximately empty region is truly empty for
|
||||
unsmoothed drawing, but it may contain points for smoothed drawing.
|
||||
otherwise.
|
||||
|
||||
}
|
||||
|
||||
|
@ -100,10 +107,9 @@ Sets the region to the interior of the specified wedge.
|
|||
See also @xmethod[dc<%> draw-ellipse], since the region content is
|
||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||
|
||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
||||
smoothed drawing, the region corresponds to a clockwise path with a
|
||||
@scheme['winding] fill. The region is also @defterm{atomic} for the
|
||||
purposes of region combination.
|
||||
The region corresponds to a clockwise path with a @tech{flexible
|
||||
fill}. The region is also @tech{atomic} for the purposes of region
|
||||
combination.
|
||||
|
||||
}
|
||||
|
||||
|
@ -118,10 +124,9 @@ Sets the region to the interior of the specified ellipse.
|
|||
See also @xmethod[dc<%> draw-ellipse], since the region content is
|
||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||
|
||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
||||
smoothed drawing, the region corresponds to a clockwise path with a
|
||||
@scheme['winding] fill. The region is also @defterm{atomic} for the
|
||||
purposes of region combination.
|
||||
The region corresponds to a clockwise path with a @tech{flexible
|
||||
fill}. The region is also @tech{atomic} for the purposes of region
|
||||
combination.
|
||||
|
||||
@|DrawSizeNote|
|
||||
|
||||
|
@ -138,11 +143,10 @@ Sets the region to the content of the given path.
|
|||
See also @xmethod[dc<%> draw-path], since the region content is
|
||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||
|
||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
||||
smoothed drawing, the fill style affects how well the region reliably
|
||||
combines with other regions (via @method[region% union],
|
||||
@method[region% xor], and @method[region% subtract]). The region is
|
||||
also @defterm{atomic} for the purposes of region combination.
|
||||
The fill style affects how well the region reliably combines with
|
||||
other regions (via @method[region% union], @method[region% xor], and
|
||||
@method[region% subtract]). The region is also @tech{atomic} for the
|
||||
purposes of region combination.
|
||||
|
||||
}
|
||||
|
||||
|
@ -156,11 +160,10 @@ Sets the region to the interior of the specified polygon.
|
|||
See also @xmethod[dc<%> draw-polygon], since the region content is
|
||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||
|
||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
||||
smoothed drawing, the fill style affects how well the region reliably
|
||||
combines with other regions (via @method[region% union],
|
||||
@method[region% xor], and @method[region% subtract]). The region is
|
||||
also @defterm{atomic} for the purposes of region combination.
|
||||
The fill style affects how well the region reliably combines with
|
||||
other regions (via @method[region% union], @method[region% xor], and
|
||||
@method[region% subtract]). The region is also @tech{atomic} for the
|
||||
purposes of region combination.
|
||||
|
||||
}
|
||||
|
||||
|
@ -172,13 +175,9 @@ The result is reliable for both unsmoothed and smoothed drawing. For
|
|||
|
||||
Sets the region to the interior of the specified rectangle.
|
||||
|
||||
See also @xmethod[dc<%> draw-rectangle], since the region content is
|
||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||
|
||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
||||
smoothed drawing, the region corresponds to a clockwise path with a
|
||||
@scheme['winding] fill. The region is also @defterm{atomic} for the
|
||||
purposes of region combination.
|
||||
The region corresponds to a clockwise path with a @tech{flexible
|
||||
fill}. The region is also @tech{atomic} for the purposes of region
|
||||
combination.
|
||||
|
||||
@|DrawSizeNote|
|
||||
|
||||
|
@ -197,10 +196,9 @@ See also @xmethod[dc<%> draw-rounded-rectangle], since the region
|
|||
content is determined the same way as brush-based filling in a
|
||||
@scheme[dc<%>].
|
||||
|
||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
||||
smoothed drawing, the region corresponds to a clockwise path with a
|
||||
@scheme['winding] fill. The region is also @defterm{atomic} for the
|
||||
purposes of region combination.
|
||||
The region corresponds to a clockwise path with a @tech{flexible
|
||||
fill}. The region is also @tech{atomic} for the purposes of region
|
||||
combination.
|
||||
|
||||
@|DrawSizeNote|
|
||||
|
||||
|
@ -214,15 +212,16 @@ Sets the region to the subtraction of itself minus the given region.
|
|||
in the given region. (The given region may contain points that are
|
||||
not in the current region; such points are ignored.)
|
||||
|
||||
This region's DC and given region's DC must be the same.
|
||||
This region's drawing context and given region's drawing context must
|
||||
be the same, or they must both be unassociated to any drawing
|
||||
context.
|
||||
|
||||
The result is always reliable for unsmoothed drawing. For smoothed
|
||||
drawing, the result is consistent across platforms and devices, but
|
||||
it is never a true subtraction. A subtraction corresponds to
|
||||
combining the sub-paths of this region with the reversed sub-paths of
|
||||
the given region, then intersecting the result with this region. This
|
||||
fails as a true subtraction, because the boundary of loops (with
|
||||
either @scheme['odd-even] or @scheme['winding] filling) is ambiguous.
|
||||
The result is consistent across platforms and devices, but it is never
|
||||
a true subtraction. A subtraction corresponds to combining the
|
||||
sub-paths of this region with the reversed sub-paths of the given
|
||||
region, then intersecting the result with this region. This fails as
|
||||
a true subtraction, because the boundary of loops (with either
|
||||
@scheme['odd-even] or @scheme['winding] filling) is ambiguous.
|
||||
|
||||
}
|
||||
|
||||
|
@ -231,18 +230,22 @@ The result is always reliable for unsmoothed drawing. For smoothed
|
|||
|
||||
Sets the region to the union of itself with the given region.
|
||||
|
||||
This region's DC and given region's DC must be the same.
|
||||
This region's drawing context and given region's drawing context must
|
||||
be the same, or they must both be unassociated to any drawing
|
||||
context.
|
||||
|
||||
The result is always reliable for unsmoothed drawing. For smoothed
|
||||
drawing, a union corresponds to combining the sub-paths of each
|
||||
region into one path, using an @scheme['odd-even] fill if either of
|
||||
the region uses an @scheme['odd-even] fill (otherwise using a
|
||||
@scheme['winding] fill). Consequently, while the result is consistent
|
||||
across platforms and devices, it is a true union only for certain
|
||||
input regions. For example, it is a true union for non-overlapping
|
||||
atomic and union regions. It is also a true union for atomic and
|
||||
union regions (potentially overlapping) that are all clockwise and
|
||||
use @scheme['winding] fill.
|
||||
A union corresponds to combining the sub-paths of each region into one
|
||||
path, using an @scheme['odd-even] fill if either of the region uses
|
||||
an @scheme['odd-even] fill (otherwise using a @scheme['winding]
|
||||
fill), a @scheme['winding] fill in either region uses a
|
||||
@scheme[winding] fill, or the fill remains a @tech{flexible fill}
|
||||
if both paths have a @tech{flexible fill}. Consequently, while the
|
||||
result is consistent across platforms and devices, it is a true union
|
||||
only for certain input regions. For example, it is a true union for
|
||||
non-overlapping @deftech{atomic} and union regions. It is also a true
|
||||
union for @tech{atomic} and union regions (potentially overlapping)
|
||||
that are all clockwise and use @scheme['winding] fill or if the fills
|
||||
are all @tech{flexible fills}.
|
||||
|
||||
}
|
||||
|
||||
|
@ -252,17 +255,20 @@ The result is always reliable for unsmoothed drawing. For smoothed
|
|||
Sets the region to the xoring of itself with the given region (i.e.,
|
||||
contains points that are enclosed by exactly one of the two regions).
|
||||
|
||||
This region's DC and given region's DC must be the same.
|
||||
This region's drawing context and given region's drawing context must
|
||||
be the same, or they must both be unassociated to any drawing
|
||||
context.
|
||||
|
||||
The result is always reliable for unsmoothed drawing. For smoothed
|
||||
drawing, the result is consistent across platforms and devices, but
|
||||
it is not necessarily a true xoring. An xoring corresponds to
|
||||
combining the sub-paths of this region with the reversed sub-paths of
|
||||
the given region. The result uses an @scheme['odd-even] fill if either
|
||||
of the region uses an @scheme['odd-even] fill (otherwise using a
|
||||
@scheme['winding] fill). Consequently, the result is a reliable xoring
|
||||
only for certain input regions. For example, it is reliable for
|
||||
atomic and xoring regions that all use @scheme['even-odd] fill.
|
||||
The result is consistent across platforms and devices, but it is not
|
||||
necessarily a true xoring. An xoring corresponds to combining the
|
||||
sub-paths of this region with the reversed sub-paths of the given
|
||||
region. The result uses an @scheme['odd-even] fill if either of the
|
||||
region uses an @scheme['odd-even] fill, a @scheme['winding] fill in
|
||||
either region uses a @scheme[winding] fill, or the fill remains a
|
||||
@tech{flexible fill} if both paths have a @tech{flexible
|
||||
fill}. Consequently, the result is a reliable xoring only for certain
|
||||
input regions. For example, it is reliable for @tech{atomic} and
|
||||
xoring regions that all use @scheme['even-odd] fill.
|
||||
|
||||
}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user