Skip to content

Commit b0da526

Browse files
authored
Allow controlling line ending caps for plots (#6) (#123)
* Add `line-cap` and `plot-line-cap` parameters (#6) ... they control the line endings for plotted elements (`line-cap`) and the plot decorations, such as axis ticks (`plot-line-cap`). Previously all line endings were round, creating a "crayon" style effect, visible for lines whose width is greater than 1. Also fixed a bug with `hrule`, `vrule` renderers, which attempted to use `'butt` style: since pens were cached, if `vrule` created a pen, all subsequent uses of that pen (same color and width) would use `'butt` line endings, OTOH, if `vrule` reused a pen, because a pen if the same color and width was previously used, the `vrule` line ending would be `'round`
1 parent cad274d commit b0da526

File tree

19 files changed

+97
-14
lines changed

19 files changed

+97
-14
lines changed

plot-doc/plot/scribblings/contracts.scrbl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,15 @@ The contract for @(racket #:style) arguments when they refer to lines, and param
101101
For the meaning of integer pen styles, see @(racket ->pen-style).
102102
}
103103

104+
@defthing[plot-pen-cap/c contract? #:value (one-of/c 'round 'projecting 'butt)]{
105+
106+
The contract for caps, or line endings, for lines drawn on the plot. Used
107+
by the @racket[plot-line-cap] and @racket[line-cap] parameters.
108+
109+
@history[#:added "8.10"]
110+
111+
}
112+
104113
@defthing[plot-brush-style/c contract? #:value (or/c exact-integer?
105114
(one-of/c 'transparent 'solid
106115
'bdiagonal-hatch 'fdiagonal-hatch 'crossdiag-hatch

plot-doc/plot/scribblings/params.scrbl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ Amount of ambient light, and whether 3D plots are rendered with diffuse and spec
108108
@racket[lines], is controlled by the @racket[line-width] parameter.
109109
}
110110

111+
@defparam[plot-line-cap cap plot-pen-cap/c #:value 'round]{
112+
113+
The cap of the lines used to draw plot axes and other non-renderer elements.
114+
See also @racket[line-cap].
115+
116+
@history[#:added "8.10"]
117+
118+
}
119+
111120
@deftogether[((defparam plot-foreground color plot-color/c #:value 0)
112121
(defparam plot-background color plot-color/c #:value 0))]{
113122
The plot foreground and background color.
@@ -254,11 +263,21 @@ Used as a default keyword argument in @racket[function], @racket[inverse], @rack
254263
@deftogether[((defparam line-color color plot-color/c #:value 1)
255264
(defparam line-width width (>=/c 0) #:value 1)
256265
(defparam line-style style plot-pen-style/c #:value 'solid)
266+
(defparam line-cap cap plot-pen-cap/c #:value 'round)
257267
(defparam line-alpha alpha (real-in 0 1) #:value 1))]{
258-
The pen color, pen width, pen style and opacity of lines in plots.
259-
Used as default keyword arguments of @racket[function], @racket[inverse], @racket[lines],
260-
@racket[parametric], @racket[polar], @racket[density], @racket[isoline], @racket[lines3d],
261-
@racket[parametric3d] and @racket[isoline3d].
268+
269+
The pen color, pen width, pen style, pen cap and opacity of lines in plots.
270+
271+
Except for @racket[line-cap], all other parameters are used as default
272+
keyword arguments of @racket[function], @racket[inverse], @racket[lines],
273+
@racket[parametric], @racket[polar], @racket[density], @racket[isoline],
274+
@racket[lines3d], @racket[parametric3d] and @racket[isoline3d].
275+
276+
The @racket[line-cap] parameter applies to lines drawn by renderers in a
277+
plot. See also @racket[plot-line-cap].
278+
279+
@history[#:added "8.10"]
280+
262281
}
263282

264283
@section{Intervals}

plot-lib/plot/private/common/contract.rkt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
(one-of/c 'transparent 'solid 'dot 'long-dash
5454
'short-dash 'dot-dash)))
5555

56+
(define plot-pen-cap/c (one-of/c 'round 'butt 'projecting))
57+
5658
(define plot-brush-style/c (or/c exact-integer?
5759
(one-of/c 'transparent 'solid
5860
'bdiagonal-hatch 'fdiagonal-hatch 'crossdiag-hatch

plot-lib/plot/private/common/parameter-groups.rkt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
plot-pen-color-map
4141
plot-brush-color-map
4242
arrow-head-size-or-scale
43-
arrow-head-angle))
43+
arrow-head-angle
44+
plot-line-cap
45+
line-cap))
4446

4547
(define-parameter-group plot3d-appearance
4648
(plot3d-samples
@@ -110,7 +112,9 @@
110112
(U Symbol #f)
111113
(U Symbol #f)
112114
(U (List '= Nonnegative-Real) Nonnegative-Real)
113-
Nonnegative-Real)
115+
Nonnegative-Real
116+
Plot-Pen-Cap
117+
Plot-Pen-Cap)
114118
;;plot3d-appearance
115119
(List Positive-Integer Real Real Nonnegative-Real Boolean Boolean)
116120
;;plot-labels

plot-lib/plot/private/common/parameters.rkt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
(defparam2 plot-foreground-alpha alpha Real Nonnegative-Real 1 (unit-ivl 'plot-foreground-alpha))
6969
(defparam2 plot-background-alpha alpha Real Nonnegative-Real 1 (unit-ivl 'plot-background-alpha))
7070
(defparam2 plot-line-width width Real Nonnegative-Real 1 (nonnegative-rational 'plot-line-width))
71+
(defparam plot-line-cap Plot-Pen-Cap 'round)
7172
(defparam2 plot-tick-size size Real Nonnegative-Real 10 (nonnegative-rational 'plot-tick-size))
7273
(defparam2 plot-font-size size Real Nonnegative-Real 11 (nonnegative-rational 'plot-font-size))
7374
(defparam plot-font-face face (U String #f) #f)
@@ -179,6 +180,7 @@
179180
(defparam line-color Plot-Color 1)
180181
(defparam2 line-width Real Nonnegative-Real 1 (nonnegative-rational 'line-width))
181182
(defparam line-style Plot-Pen-Style 'solid)
183+
(defparam line-cap Plot-Pen-Cap 'round)
182184
(defparam2 line-alpha Real Nonnegative-Real 1 (unit-ivl 'line-alpha))
183185

184186
;; Intervals

plot-lib/plot/private/common/plot-device.rkt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@
172172
;; -----------------------------------------------------------------------------------------------
173173
;; Pen, brush, alpha parameters
174174

175-
(define pen-hash ((inst make-hash (Vector Integer Integer Integer Real) (Instance Pen%))))
175+
(define pen-hash ((inst make-hash (Vector Integer Integer Integer Real Symbol) (Instance Pen%))))
176176
(define transparent-pen (make-pen% 0 0 0 1 'transparent 'round))
177177

178178
(: pen-color (List Real Real Real))
@@ -185,7 +185,7 @@
185185
;; Sets the pen, using a hash table to avoid making duplicate objects. At time of writing (and for
186186
;; the forseeable future) this is much faster than using a pen-list%, because it doesn't have to
187187
;; synchronize access. It's also not thread-safe.
188-
(define/public (set-pen color width style [cap 'round])
188+
(define/public (set-pen color width style [cap (line-cap)])
189189
(set! pen-style (->pen-style style))
190190
(cond [(eq? pen-style 'transparent)
191191
(set! pen-color '(0 0 0))
@@ -198,16 +198,16 @@
198198
(app real->color-byte g)
199199
(app real->color-byte b))
200200
pen-color)
201-
(send dc set-pen (hash-ref! pen-hash (vector r g b width)
201+
(send dc set-pen (hash-ref! pen-hash (vector r g b width cap)
202202
(λ () (make-pen% r g b width 'solid cap))))]))
203203

204204
;; Sets the pen used to draw major ticks.
205205
(define/public (set-major-pen [style 'solid])
206-
(set-pen (plot-foreground) (plot-line-width) style))
206+
(set-pen (plot-foreground) (plot-line-width) style (plot-line-cap)))
207207

208208
;; Sets the pen used to draw minor ticks.
209209
(define/public (set-minor-pen [style 'solid])
210-
(set-pen (plot-foreground) (* 1/2 (plot-line-width)) style))
210+
(set-pen (plot-foreground) (* 1/2 (plot-line-width)) style (plot-line-cap)))
211211

212212
(define brush-hash ((inst make-hash (Vector Integer Integer Integer Symbol) (Instance Brush%))))
213213
(define transparent-brush (make-brush% 0 0 0 'transparent))

plot-lib/plot/private/common/types.rkt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
(deftype Plot-Pen-Style
3838
(U Integer Plot-Pen-Style-Sym))
3939

40+
(deftype Plot-Pen-Cap
41+
(U 'round 'projecting 'butt))
42+
4043
(deftype Plot-Brush-Style-Sym
4144
(U 'transparent 'solid
4245
'bdiagonal-hatch 'fdiagonal-hatch 'crossdiag-hatch
@@ -164,4 +167,4 @@
164167
[draw-legend (-> (Listof legend-entry) Rect Void)]))
165168

166169
(require "plotmetrics.rkt")
167-
(provide Plot-Metrics<%> Plot-Pict Plot-Metrics-Functions)
170+
(provide Plot-Metrics<%> Plot-Pict Plot-Metrics-Functions)

plot-lib/plot/private/plot2d/line.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@
230230
(ivl->plot-label (ivl x-min x-max)) (ivl->plot-label (ivl y-min y-max))))
231231

232232
(send area put-alpha alpha)
233-
(send area put-pen color width style 'butt)
233+
(send area put-pen color width style)
234234
(case h/v
235235
[(h) (send area put-line (vector (or v-min x-min) v) (vector (or v-max x-max) v))]
236236
[(v) (send area put-line (vector v (or v-min y-min)) (vector v (or v-max y-max)))]))

plot-lib/plot/private/plot2d/plot-area.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@
803803

804804
(define/public (put-alpha alpha) (send pd set-alpha alpha))
805805

806-
(define/public (put-pen color width style [cap 'round]) (send pd set-pen color width style cap))
806+
(define/public (put-pen color width style [cap (line-cap)]) (send pd set-pen color width style cap))
807807
(define/public (put-major-pen [style 'solid]) (send pd set-major-pen style))
808808
(define/public (put-minor-pen [style 'solid]) (send pd set-minor-pen style))
809809

plot-lib/plot/private/utils-and-no-gui.rkt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Anchor
88
Plot-Color
99
Plot-Pen-Style
10+
Plot-Pen-Cap
1011
Plot-Brush-Style
1112
Point-Sym
1213
List-Generator
@@ -93,6 +94,7 @@
9394
plot-background
9495
plot-background-alpha
9596
plot-line-width
97+
plot-line-cap
9698
plot-tick-size
9799
plot-font-size
98100
plot-font-face
@@ -141,6 +143,7 @@
141143
line-color
142144
line-width
143145
line-style
146+
line-cap
144147
line-alpha
145148
interval-color
146149
interval-style

plot-test/plot/tests/PRs/6.rkt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#lang racket
2+
3+
(require rackunit
4+
plot racket/runtime-path
5+
"../helpers.rkt")
6+
7+
;; See https://github.com/racket/plot/issues/6 and associated discution.
8+
9+
(define-runtime-path pr6-data-round "./test-data/pr6-round.dat")
10+
(define-runtime-path pr6-data-butt "./test-data/pr6-butt.dat")
11+
(define-runtime-path pr6-data-projecting "./test-data/pr6-projecting.dat")
12+
13+
(define (do-plot-pr6 output-fn)
14+
(parameterize
15+
([plot-line-width 10]
16+
[line-width 10]
17+
[plot-pen-color-map 'set1])
18+
(output-fn
19+
(list
20+
(function sin -5 5 #:color 1 #:label "sin(x)")
21+
(function cos -5 5 #:color 2 #:label "cos(x)")))))
22+
23+
(define pr6-test-suite
24+
(test-suite
25+
"PR#6: Add plot-line-cap and line-cap parameters"
26+
(test-case "pr6-round"
27+
(parameterize ([plot-line-cap 'round]
28+
[line-cap 'round])
29+
(check-draw-steps do-plot-pr6 pr6-data-round)))
30+
(test-case "pr6-butt"
31+
(parameterize ([plot-line-cap 'butt]
32+
[line-cap 'butt])
33+
(check-draw-steps do-plot-pr6 pr6-data-butt)))
34+
(test-case "pr6-projecting"
35+
(parameterize ([plot-line-cap 'projecting]
36+
[line-cap 'projecting])
37+
(check-draw-steps do-plot-pr6 pr6-data-projecting)))))
38+
39+
(module+ test
40+
(require rackunit/text-ui)
41+
(run-tests pr6-test-suite))
15.4 KB
Binary file not shown.
75.2 KB
Loading
Binary file not shown.
Loading
15.4 KB
Binary file not shown.
80.2 KB
Loading
-4 Bytes
Binary file not shown.
2.43 KB
Loading

0 commit comments

Comments
 (0)