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%
|
(define region%
|
||||||
(class object%
|
(class object%
|
||||||
|
|
||||||
(init [the-dc #f])
|
(init [(the-dc dc) #f])
|
||||||
(define dc the-dc)
|
(define dc the-dc)
|
||||||
(when dc
|
(when dc
|
||||||
(unless (dc . is-a? . dc<%>)
|
(unless (dc . is-a? . dc<%>)
|
||||||
|
@ -62,7 +62,36 @@
|
||||||
[r r]
|
[r r]
|
||||||
[b b])
|
[b b])
|
||||||
(if (null? paths)
|
(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)])
|
(let-values ([(l2 t2 r2 b2) (send (caar paths) get-bounding-box)])
|
||||||
(loop (cdr paths)
|
(loop (cdr paths)
|
||||||
(min l l2)
|
(min l l2)
|
||||||
|
@ -126,7 +155,19 @@
|
||||||
(set! temp-cr
|
(set! temp-cr
|
||||||
(cairo_create
|
(cairo_create
|
||||||
(cairo_image_surface_create CAIRO_FORMAT_A8 1 1))))
|
(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]
|
(def/public (set-arc [real? x]
|
||||||
[real? y]
|
[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
|
(possibly discontinuous). It is normally used for clipping drawing
|
||||||
operations.
|
operations.
|
||||||
|
|
||||||
Each @scheme[region%] object is associated to a particular
|
A @scheme[region%] object can be associated to a particular
|
||||||
@scheme[dc<%>] object, specified when the region is created. A region
|
@scheme[dc<%>] object when the region is created. In that case, the
|
||||||
can only be used with its associated @scheme[dc<%>] object. The origin
|
region uses the drawing context's current transformation matrix,
|
||||||
and scale of a drawing context determine the bounding box and drawing
|
translation, scaling, and rotation, independent of the transformation
|
||||||
location of a region at the time that a region is created (or set); a
|
that is in place when the region is installed. Otherwise, the region
|
||||||
region is independent of the current scale and origin when the region
|
is transformed as usual when it is installed into a
|
||||||
is used. For an auto-scrolled canvas, the canvas's current scrolling
|
@scheme[dc<%>]. For an auto-scrolled canvas, the canvas's current
|
||||||
applies when the region is used (and it does not affect the region's
|
scrolling always applies when the region is used (and it does not
|
||||||
bounding box).
|
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<%>
|
See also @xmethod[dc<%> set-clipping-region] and @xmethod[dc<%>
|
||||||
get-clipping-region].
|
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)
|
@defmethod[(get-bounding-box)
|
||||||
(values real? real? real? real?)]{
|
(values real? real? real? real?)]{
|
||||||
|
|
||||||
Returns a rectangle that encloses the region. The return values are
|
Returns a rectangle that approximately encloses the region. The
|
||||||
the left, top, width, and height of the rectangle. The bounding box
|
return values are the left, top, width, and height of the
|
||||||
is precisely correct for unsmoothed drawing, but it is only
|
rectangle. If the region has an associated drawing context, the
|
||||||
approximate for smoothed drawing.
|
bounding box is in the drawing context's current logical coordinates.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@defmethod[(get-dc)
|
@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?]{
|
boolean?]{
|
||||||
|
|
||||||
Returns @scheme[#t] if the given point is approximately within the
|
Returns @scheme[#t] if the given point is approximately within the
|
||||||
region, @scheme[#f] otherwise. The given point is scaled and
|
region, @scheme[#f] otherwise. If the region has an associated
|
||||||
translated according to the region's @scheme[dc<%>]'s current scale
|
drawing context, the given point is effectively transformed according
|
||||||
and translation.
|
to the region's @scheme[dc<%>]'s current transformation matrix.
|
||||||
|
|
||||||
The approximate in-region test represents the true result for
|
|
||||||
unsmoothed drawing, but it not necessarily for smoothed drawing.
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
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
|
An intersect corresponds to clipping with this region's path, and then
|
||||||
smoothed drawing, an intersect corresponds to clipping with this
|
clipping with the given region's path. Further combining sends to
|
||||||
region's path, and then clipping with the given region's path.
|
this region correspond to combination with the original path before
|
||||||
Further combining sends to this region correspond to combination with
|
initial clip, and further combination with this region as an argument
|
||||||
the original path before initial clip, and further combination with
|
correspond to a combination with the given path after the initial
|
||||||
this region as an argument correspond to a combination with the given
|
clip. Thus, an intersecting region is a poor input for
|
||||||
path after the initial clip. Thus, an intersecting region is a poor
|
@method[region% union], @method[region% subtract], or @method[region%
|
||||||
input for @method[region% union], @method[region% subtract], or
|
xor], but it intersects properly in further calls to @method[region%
|
||||||
@method[region% xor], but it intersects properly in further calls to
|
intersect].
|
||||||
@method[region% intersect].
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +90,7 @@ The result is always reliable for unsmoothed and smoothed drawing. For
|
||||||
boolean?]{
|
boolean?]{
|
||||||
|
|
||||||
Returns @scheme[#t] if the region is approximately empty, @scheme[#f]
|
Returns @scheme[#t] if the region is approximately empty, @scheme[#f]
|
||||||
otherwise. An approximately empty region is truly empty for
|
otherwise.
|
||||||
unsmoothed drawing, but it may contain points for smoothed drawing.
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
See also @xmethod[dc<%> draw-ellipse], since the region content is
|
||||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||||
|
|
||||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
The region corresponds to a clockwise path with a @tech{flexible
|
||||||
smoothed drawing, the region corresponds to a clockwise path with a
|
fill}. The region is also @tech{atomic} for the purposes of region
|
||||||
@scheme['winding] fill. The region is also @defterm{atomic} for the
|
combination.
|
||||||
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
|
See also @xmethod[dc<%> draw-ellipse], since the region content is
|
||||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||||
|
|
||||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
The region corresponds to a clockwise path with a @tech{flexible
|
||||||
smoothed drawing, the region corresponds to a clockwise path with a
|
fill}. The region is also @tech{atomic} for the purposes of region
|
||||||
@scheme['winding] fill. The region is also @defterm{atomic} for the
|
combination.
|
||||||
purposes of region combination.
|
|
||||||
|
|
||||||
@|DrawSizeNote|
|
@|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
|
See also @xmethod[dc<%> draw-path], since the region content is
|
||||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||||
|
|
||||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
The fill style affects how well the region reliably combines with
|
||||||
smoothed drawing, the fill style affects how well the region reliably
|
other regions (via @method[region% union], @method[region% xor], and
|
||||||
combines with other regions (via @method[region% union],
|
@method[region% subtract]). The region is also @tech{atomic} for the
|
||||||
@method[region% xor], and @method[region% subtract]). The region is
|
purposes of region combination.
|
||||||
also @defterm{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
|
See also @xmethod[dc<%> draw-polygon], since the region content is
|
||||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
determined the same way as brush-based filling in a @scheme[dc<%>].
|
||||||
|
|
||||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
The fill style affects how well the region reliably combines with
|
||||||
smoothed drawing, the fill style affects how well the region reliably
|
other regions (via @method[region% union], @method[region% xor], and
|
||||||
combines with other regions (via @method[region% union],
|
@method[region% subtract]). The region is also @tech{atomic} for the
|
||||||
@method[region% xor], and @method[region% subtract]). The region is
|
purposes of region combination.
|
||||||
also @defterm{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.
|
Sets the region to the interior of the specified rectangle.
|
||||||
|
|
||||||
See also @xmethod[dc<%> draw-rectangle], since the region content is
|
The region corresponds to a clockwise path with a @tech{flexible
|
||||||
determined the same way as brush-based filling in a @scheme[dc<%>].
|
fill}. The region is also @tech{atomic} for the purposes of region
|
||||||
|
combination.
|
||||||
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.
|
|
||||||
|
|
||||||
@|DrawSizeNote|
|
@|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
|
content is determined the same way as brush-based filling in a
|
||||||
@scheme[dc<%>].
|
@scheme[dc<%>].
|
||||||
|
|
||||||
The result is reliable for both unsmoothed and smoothed drawing. For
|
The region corresponds to a clockwise path with a @tech{flexible
|
||||||
smoothed drawing, the region corresponds to a clockwise path with a
|
fill}. The region is also @tech{atomic} for the purposes of region
|
||||||
@scheme['winding] fill. The region is also @defterm{atomic} for the
|
combination.
|
||||||
purposes of region combination.
|
|
||||||
|
|
||||||
@|DrawSizeNote|
|
@|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
|
in the given region. (The given region may contain points that are
|
||||||
not in the current region; such points are ignored.)
|
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
|
The result is consistent across platforms and devices, but it is never
|
||||||
drawing, the result is consistent across platforms and devices, but
|
a true subtraction. A subtraction corresponds to combining the
|
||||||
it is never a true subtraction. A subtraction corresponds to
|
sub-paths of this region with the reversed sub-paths of the given
|
||||||
combining the sub-paths of this region with the reversed sub-paths of
|
region, then intersecting the result with this region. This fails as
|
||||||
the given region, then intersecting the result with this region. This
|
a true subtraction, because the boundary of loops (with either
|
||||||
fails as a true subtraction, because the boundary of loops (with
|
@scheme['odd-even] or @scheme['winding] filling) is ambiguous.
|
||||||
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.
|
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
|
A union corresponds to combining the sub-paths of each region into one
|
||||||
drawing, a union corresponds to combining the sub-paths of each
|
path, using an @scheme['odd-even] fill if either of the region uses
|
||||||
region into one path, using an @scheme['odd-even] fill if either of
|
an @scheme['odd-even] fill (otherwise using a @scheme['winding]
|
||||||
the region uses an @scheme['odd-even] fill (otherwise using a
|
fill), a @scheme['winding] fill in either region uses a
|
||||||
@scheme['winding] fill). Consequently, while the result is consistent
|
@scheme[winding] fill, or the fill remains a @tech{flexible fill}
|
||||||
across platforms and devices, it is a true union only for certain
|
if both paths have a @tech{flexible fill}. Consequently, while the
|
||||||
input regions. For example, it is a true union for non-overlapping
|
result is consistent across platforms and devices, it is a true union
|
||||||
atomic and union regions. It is also a true union for atomic and
|
only for certain input regions. For example, it is a true union for
|
||||||
union regions (potentially overlapping) that are all clockwise and
|
non-overlapping @deftech{atomic} and union regions. It is also a true
|
||||||
use @scheme['winding] fill.
|
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.,
|
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).
|
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
|
The result is consistent across platforms and devices, but it is not
|
||||||
drawing, the result is consistent across platforms and devices, but
|
necessarily a true xoring. An xoring corresponds to combining the
|
||||||
it is not necessarily a true xoring. An xoring corresponds to
|
sub-paths of this region with the reversed sub-paths of the given
|
||||||
combining the sub-paths of this region with the reversed sub-paths of
|
region. The result uses an @scheme['odd-even] fill if either of the
|
||||||
the given region. The result uses an @scheme['odd-even] fill if either
|
region uses an @scheme['odd-even] fill, a @scheme['winding] fill in
|
||||||
of the region uses an @scheme['odd-even] fill (otherwise using a
|
either region uses a @scheme[winding] fill, or the fill remains a
|
||||||
@scheme['winding] fill). Consequently, the result is a reliable xoring
|
@tech{flexible fill} if both paths have a @tech{flexible
|
||||||
only for certain input regions. For example, it is reliable for
|
fill}. Consequently, the result is a reliable xoring only for certain
|
||||||
atomic and xoring regions that all use @scheme['even-odd] fill.
|
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