
Thank you very much

Can anyone explain why this program results in different numbers each time it is run?

#lang racket
(require pict)
(send (let/ec return (pict->bitmap (dc (λ (dc dx dy) (return (send dc get-pen))) 1 1)))
get-width)

The dc
pict is called twice, the fist time with an un-initialized draw context whose pen returns a different width each time. The second time, dc
is called with a device context that has a default pen with a width of 1. Try running this program several times:

#lang racket
(require pict)
(pict->bitmap (dc (λ (dc dx dy) (printf "*** ~a~%" (send (send dc get-pen) get-width))) 1 1))

@alexharsanyi Thanks!

Hmm. Wonder why it is called twice.

That doesn’t seem right.

The first time it is called when the dc
pict object is constructed. This code calls it once, and produces random values #lang racket
(require pict)
(define x (dc (λ (dc dx dy) (printf "*** ~a~%" (send (send dc get-pen) get-width))) 1 1))

Evaluating x multiple times will than call the lambda with a device context that always has a pen of width 1

IIRC the contract on dc
invokes the function with some random values as a sort of fuzz check?

So that means that all picts takes twice as much to to evaluate (than is strictly needed)?

The contract is: [dc (->i ([draw (-> (is-a?/c dc<%>) real? real? any)]
[w real?]
[h real?])
([d (or/c #f real?)]
[a (or/c #f real?)])
#:pre/name (draw)
"draw proc does not restore the dc state after being called"
(does-draw-restore-the-state-after-being-called? draw)
[p pict?])]

Looks ok, I think.

But I think you are on to something (wrt contracts).

This results in 1 every time:

(send (let/ec return (pict->bitmap (unsafe-dc (λ (dc dx dy) (return (send dc get-pen))) 1 1)))
get-width)

(changed dc to unsafe-dc)

does-draw-restore-the-state-after-being-called?
calls draw to check that it restores the state?

Oh.: (define (does-draw-restore-the-state-after-being-called? draw)
(define bdc (new bitmap-dc% [bitmap (make-bitmap 1 1)]))
(prandomize-state bdc)
(define old-state (get-dc-state bdc))
(draw bdc 0 0)
(equal? (get-dc-state bdc) old-state))

#lang racket
(require pict racket/draw)
(define p (send the-pen-list find-or-create-pen "black" 1 'solid))
(define x (dc (λ (dc dx dy) (send dc set-pen p)) 1 1))

The above fails the contract even though the pict is not rendered

The problem here is that the call (draw bdc 0 0)
could take a long time.

How often is does-draw-restore-the-state-after-being-called?
called? Every time the pict is rendered?

@soegaard2 IIRC it’s called only when the contract is attached

but i may be misremembering

based on the code examples above, it is called only when the pict is created, not when it is rendered

^ yeah that sounds right

So what happens if I have a pict that when drawn relies on creating subpicts?

Let’s say p is (above p1 p2).

Where p1 and p2 are pictures to be created.

Will the draw operation of, say, p1 be called twice or four times?

if p1 and p2 are created by your dc
drawer, it will be called twice.

the draw operation is splatted directly into the picts internal drawing structure, and isn’t wrapped by a contract that calls does-draw-restore-the-state-after-being-called?


if you find it’s reeeallllyy slow, or the extra side effects are getting in the way, you could use unsafe-dc

That or single out the case width=0 and height=0.

I have quite a few different uses of dc
in metapict - which depends heavily on picts within picts.

Thanks for the help.