laurent.orseau
2019-9-19 08:21:21

do you think you can use that in metapict then?


soegaard2
2019-9-19 10:24:35

Yes an crop-automatic would be easy to do. But we need to figure out how to render a pict to a cairo_recording_surface_t first. The record-dc% in racket/draw is implemented in Racket and doesn’t use cairo_recording_surface_t.


soegaard2
2019-9-19 11:30:31

Good news. The code of racket/draw contains a dc-mixin that makes it easy to make a new kind of dc%. Initial experiment turned out well. #lang racket/base (require racket/class racket/draw/private/syntax ; "syntax.rkt" racket/draw/unsafe/cairo racket/draw/private/dc ; "dc.rkt" racket/draw/private/local ; local.rkt" "bb.rkt" ) (provide cairo-record-dc%) (define dc-backend% (class default-dc-backend% (init [(init-x0 x0)] [(init-y0 y0)] [(init-w width)] [(init-h height)]) (unless (real? init-x0) (raise-type-error (init-name 'record-dc%) "non-real or #f" init-x0)) (unless (real? init-y0) (raise-type-error (init-name 'record-dc%) "non-real or #f" init-y0)) (unless (and (real? init-w) (not (negative? init-w))) (raise-type-error (init-name 'record-dc%) "nonnegative real or #f" init-w)) (unless (and (real? init-h) (not (negative? init-h))) (raise-type-error (init-name 'record-dc%) "nonnegative real or #f" init-h)) (define width init-w) (define height init-h) (define x0 init-x0) (define y0 init-y0) (define s (cairo_recording_surface_create CAIRO_CONTENT_COLOR_ALPHA #f)) (define c (and s (cairo_create s))) (when s (cairo_surface_destroy s)) ; decrease reference count (define/override (ok?) (and c #t)) (define/override (get-cr) c) (def/override (get-size) (values width height)) (define/override (end-cr) (cairo_surface_finish s) (cairo_destroy c) (set! c #f) (set! s #f)) ; keep these? (define/override (get-pango font) (send font get-pango)) (define/override (get-font-metrics-key sx sy) (if (and (= sx 1.0) (= sy 1.0)) 3 0)) (define/override (can-combine-text? sz) #t) (define/public (multiple-pages-ok?) #f) (define/public (get-inked-extents) (cairo_recording_surface_ink_extents s 0. 0. 10. 10.)) (super-new))) (define cairo-record-dc% (class (dc-mixin dc-backend%) (super-new))) (define cr-dc (new cairo-record-dc% [x0 0.0] [y0 0.0] [width 1000.] [height 1000.])) (require pict) (define p (pin-over (rectangle 30 40) 20 20 (circle 15))) (draw-pict p cr-dc 0 0) (send cr-dc get-inked-extents)


laurent.orseau
2019-9-19 11:54:29

what’s bb.rkt?


laurent.orseau
2019-9-19 11:55:28

got it. it’s the file above


laurent.orseau
2019-9-19 11:56:12

Nice!


laurent.orseau
2019-9-19 11:56:35

This should even fix the broken bounding box for disks et al. with borders


laurent.orseau
2019-9-19 11:57:09

like (disk 20 #:border-width 20) is not well rendered in DrRacket at least, the sizes are wrong as they don’t include the border.


soegaard2
2019-9-19 12:15:17

Nice example. I know why it happens, but need to look up whether it is intentional.


laurent.orseau
2019-9-19 12:16:02

I hope it’s not, because it’s ugly


laurent.orseau
2019-9-19 12:16:21

Also #:border-width 0 still draws a border…


soegaard2
2019-9-19 13:16:04

A border width 0 means the thinnest (non-zero) possible width.


soegaard2
2019-9-19 13:17:11

The disc is drawn as a filled circle and the outline is drawn with a pen of width 20. Only the circle is counted in the bounding box.


soegaard2
2019-9-19 13:18:12

I can’t think the exact place in the documentation, but I consider ``` (beside (rectangle 10 10) (rectangle 10 10))


soegaard2
2019-9-19 13:19:19

The bounding box for (rectangle 10 10) is a rectangle of width 10 and height 10. When you stroke the outline with a pen, half the ink is outside the other half is inside.


soegaard2
2019-9-19 13:20:11

The concequence is that the edge shared by the two rectangles is only drawn once.


soegaard2
2019-9-19 13:21:39

Well, it might be drawn twice, but it will be the same edge.


soegaard2
2019-9-19 13:22:31

If the width of the pen was added to the bounding box, using beside would make the shared edge twice as wide.


soegaard2
2019-9-19 13:23:32

DrRacket compensates for this by drawing “a bit more” than the bounding box.


soegaard2
2019-9-19 13:24:05

I am not sure what a “bit more” is exactly.


laurent.orseau
2019-9-19 13:33:08

Yeah, well i find this behaviour broken. A bounding box is supposed to be bounding what’s drawn. What you’re talking about is an alignment box.


laurent.orseau
2019-9-19 13:34:25

When i draw a single disk with a border of size 20, i don’t want to see it cut in a square


soegaard2
2019-9-19 13:35:15

I agree that there should have been two types of boxes in a pict.


soegaard2
2019-9-19 13:38:26

Difficult to find a reasonable backward-compatible solution.


laurent.orseau
2019-9-19 13:44:30

Personally I find the current behaviour buggy, so replacing it with the correct bounding-box behaviour would just be bug fixing, which is not considered as backward incompatibility :stuck_out_tongue:


soegaard2
2019-9-19 14:12:44

soegaard2
2019-9-19 14:13:06

Getting there.


laurent.orseau
2019-9-19 14:20:12

nice!


soegaard2
2019-9-19 14:22:29

Here is a single file to experiment with. I am slightly surprised that I get 39 and not 40 as the width in the example.


laurent.orseau
2019-9-19 14:24:04

yes, it seems to be off by 1 pixel on that example. Weird


laurent.orseau
2019-9-19 14:26:27

This shows that the cropping is always off by one: (for/list ([i (in-range 1 20)]) (crop/inked (frame (crop/inked (cc-superimpose (blank 100 100) (circle i))))))


soegaard2
2019-9-19 14:28:43

This is odd too:


soegaard2
2019-9-19 14:29:11

The circle of radius 1 is blank?!


laurent.orseau
2019-9-19 14:30:47

looks like another bug


soegaard2
2019-9-19 14:31:35

Maybe it is a racket-mode bug. Seems to work in DrRacket.


laurent.orseau
2019-9-19 14:31:50

(for/list ([i 40 ])(frame (circle i))) is also off by one in DrRacket


laurent.orseau
2019-9-19 14:31:59

I’m doing my tests in DrRacket


laurent.orseau
2019-9-19 14:32:24

and (circle 1) is also blank, but has size 1


laurent.orseau
2019-9-19 14:32:46

ah, no sometimes I can see a pixel


laurent.orseau
2019-9-19 14:32:49

alignment problem?


laurent.orseau
2019-9-19 14:33:19

scratch that actually. What I see is the frame


soegaard2
2019-9-19 14:36:10

Maybe it is an off-by–0.5 error? I think Racket adds 0.5 before calling Cairo if … something.



soegaard2
2019-9-19 14:39:52

> In addition, for pen drawing through draw-rectangle, draw-ellipse, draw-rounded-rectangle, and draw-arc, the given width and height are each decreased by 1.0 divided by the alignment scale.


soegaard2
2019-9-19 14:42:38
(require (only-in metapict aligned smoothed unsmoothed))
(pict-width (crop/inked (aligned    (disk 20 #:border-width 20))))
(pict-width (crop/inked (smoothed   (disk 20 #:border-width 20))))
(pict-width (crop/inked (unsmoothed (disk 20 #:border-width 20))))

gives ``` 39


soegaard2
2019-9-19 14:42:39

40


soegaard2
2019-9-19 14:42:44

39 ```


laurent.orseau
2019-9-19 14:44:42

ouch


soegaard2
2019-9-19 14:46:00

I suddenly remember I wrote this note in “pict.rkt” at some point: > ;;; IMPORTANT NOTE > ;;; Remember that to set the smoothing mode to ’smoothed if you implement > ;;; new picts constructors, that use coordinates.


laurent.orseau
2019-9-19 14:56:06

:slightly_smiling_face: