racket/draw: fix outline adjustment in `draw-rectangle' and others

This commit is contained in:
Matthew Flatt 2012-05-10 09:12:48 -06:00
parent dbd940611e
commit 1432912357
2 changed files with 52 additions and 42 deletions

View File

@ -312,6 +312,15 @@
(set! x-align-delta (/ (bitwise-and 1 (max 1 (inexact->exact (floor (* effective-scale-x w))))) 2.0))
(set! y-align-delta (/ (bitwise-and 1 (max 1 (inexact->exact (floor (* effective-scale-y w))))) 2.0))))))
(define/private (sub1w w)
(if (aligned? smoothing)
(max 0.0 (- w (/ effective-scale-x)))
w))
(define/private (sub1h h)
(if (aligned? smoothing)
(max 0.0 (- h (/ effective-scale-y)))
h))
(def/public (set-font [font% f])
(set! font f))
@ -994,15 +1003,15 @@
(with-cr
(check-ok who)
cr
(let ([draw-one (lambda (align-x align-y brush? pen? d)
(let ([draw-one (lambda (align-x align-y brush? pen? sub1w sub1h)
(let* ([orig-x x]
[orig-y y]
[x (align-x x)]
[y (align-y y)]
[width (- (align-x (+ orig-x width)) x)]
[width (if (width . >= . d) (- width d) width)]
[width (sub1w width)]
[height (- (align-y (+ orig-y height)) y)]
[height (if (height . >= . d) (- height d) height)]
[height (sub1h height)]
[radius-x (/ width 2)]
[radius-y (/ height 2)]
[center-x (+ x radius-x)]
@ -1024,9 +1033,10 @@
(cairo_restore cr)
(draw cr brush? pen?))))])
(when (brush-draws?)
(draw-one (lambda (x) x) (lambda (y) y) #t #f 0.0))
(draw-one (lambda (x) x) (lambda (y) y) #t #f (lambda (x) x) (lambda (x) x)))
(when (pen-draws?)
(draw-one (lambda (x) (align-x x)) (lambda (y) (align-y y)) #f #t 1.0)))))
(draw-one (lambda (x) (align-x x)) (lambda (y) (align-y y)) #f #t
(lambda (x) (sub1w x)) (lambda (x) (sub1h x)))))))
(def/public (draw-arc [real? x] [real? y] [nonnegative-real? width] [nonnegative-real? height]
[real? start-radians] [real? end-radians])
@ -1100,8 +1110,8 @@
(cairo_new_path cr)
(cairo_rectangle cr x y width height)
(draw cr #t #f)
(let ([w2 (- (align-x (+ x (sub1 width))) ax)]
[h2 (- (align-y (+ y (sub1 height))) ay)])
(let ([w2 (- (align-x (+ x (sub1w width))) ax)]
[h2 (- (align-y (+ y (sub1h height))) ay)])
(when (and (positive? w2)
(positive? h2))
(cairo_new_path cr)
@ -1125,7 +1135,7 @@
(rounded-rect x y width height (lambda (x) x) (lambda (y) y))
(draw cr #t #f))
(when (pen-draws?)
(rounded-rect x y (sub1 width) (sub1 height)
(rounded-rect x y (sub1w width) (sub1h height)
(lambda (x) (align-x x)) (lambda (y) (align-y y)))
(draw cr #f #t)))))

View File

@ -66,14 +66,16 @@ Draws a counter-clockwise circular arc, a part of the ellipse
The current pen is used for the arc. If the current brush is not
transparent, it is used to fill the wedge bounded by the arc plus
lines (not drawn) extending to the center of the inscribed ellipse.
If both the pen and brush are non-transparent, the wedge is filled
with the brush before the arc is drawn with the pen.
The wedge and arc meet so that no space is left between them, but the
precise overlap between the wedge and arc is platform- and
size-specific. Typically, the regions drawn by the brush and pen
overlap. In unsmoothed or aligned mode, the path for the outline is
adjusted by shrinking the bounding ellipse width and height by one
drawing unit after scaling.
If both the pen and brush are non-transparent, the wedge is filled
with the brush before the arc is drawn with the pen. The wedge and
arc meet so that no space is left between them, but the precise
overlap between the wedge and arc is platform- and size-specific.
Typically, the regions drawn by the brush and pen overlap. More
generally, the pen is centered over the outline of the arc, rounding
toward the center in unsmoothed mode.
@|DrawSizeNote|
@ -179,15 +181,16 @@ See @method[dc<%> draw-bitmap] for information about @racket[dest-x],
Draws an ellipse contained in a rectangle with the given top-left
corner and size. The current pen is used for the outline, and the
current brush is used for filling the shape.
current brush is used for filling the shape. If both the pen and
brush are non-transparent, the ellipse is filled with the brush
before the outline is drawn with the pen.
If both the pen and brush are non-transparent, the ellipse is filled
with the brush before the outline is drawn with the pen. The filling
and outline meet so that no space is left between them, but the
precise overlap between the filling and outline is platform- and
size-specific. Typically, the regions drawn by the brush and pen
overlap. More generally, the pen is centered over the outline of the
ellipse, rounding toward the center in unsmoothed mode.
Brush filling and pen outline meet so that no space is left between
them, but the precise overlap between the filling and outline is
platform- and size-specific. Thus, the regions drawn by the brush
and pen may partially overlap. In unsmoothed or aligned mode, the
path for the outline is adjusted by shrinking the ellipse width and
height by one drawing unit after scaling.
@|DrawSizeNote|
@ -324,17 +327,15 @@ See also @method[dc<%> set-smoothing] for information on the
Draws a rectangle with the given top-left corner and size. The
current pen is used for the outline and the current brush for filling
the shape.
the shape. If both the pen and brush are non-transparent, the
rectangle is filled with the brush before the outline is drawn with
the pen.
If both the pen and brush are non-transparent, the rectangle is filled
with the brush before the outline is drawn with the pen. In
unsmoothed mode, when the pen is size 0 or 1, the filling precisely
overlaps the entire outline. As a result, if a rectangle is drawn
with a size-0 or size-1 @racket['xor] @racket[pen%] and an
@racket['xor] @racket[brush%], the outline is xored twice (first by
the brush, then by the pen), leaving it unchanged. More generally,
the pen is centered over the outline of the rectangle, rounding
toward the center in unsmoothed mode.
In unsmoothed or aligned mode, when the pen is size 0 or 1, the
filling precisely overlaps the entire outline. More generally, in
unsmoothed or aligned mode, the path for the outline is adjusted by
shrinking the rectangle width and height by one drawing unit after
scaling.
See also @method[dc<%> set-smoothing] for information on the
@racket['aligned] smoothing mode.
@ -354,7 +355,8 @@ See also @method[dc<%> set-smoothing] for information on the
Draws a rectangle with the given top-left corner, and with the given
size. The corners are quarter-circles using the given radius. The
current pen is used for the outline and the current brush for filling
the shape.
the shape. If both the pen and brush are non-transparent, the rectangle is filled
with the brush before the outline is drawn with the pen.
If @racket[radius] is positive, the value is used as the radius of the
rounded corner. If @racket[radius] is negative, the absolute value is
@ -364,14 +366,12 @@ If @racket[radius] is positive, the value is used as the radius of the
If @racket[radius] is less than @racket[-0.5] or more than half of
@racket[width] or @racket[height], @|MismatchExn|.
If both the pen and brush are non-transparent, the rectangle is filled
with the brush before the outline is drawn with the pen. The filling
and outline meet so that no space is left between them, but the
precise overlap between the filling and outline is platform- and
size-specific. Thus, the regions drawn by the brush and pen may
partially overlap. More generally, the pen is centered over the
outline of the rounded rectangle, rounding toward the center in
unsmoothed mode.
Brush filling and pen outline meet so that no space is left between
them, but the precise overlap between the filling and outline is
platform- and size-specific. Thus, the regions drawn by the brush
and pen may partially overlap. In unsmoothed or aligned mode, the
path for the outline is adjusted by shrinking the rectangle width and
height by one drawing unit after scaling.
See also @method[dc<%> set-smoothing] for information on the
@racket['aligned] smoothing mode.