Hi
posn-s of graphics/graphics are structs with two reals. They are used to locate objects in a viewport. I would expect locations to be identified by two exact nonnegative integers pointing to a pixel. We don't have fractions of pixels, do we? Where for example is (make-posn 3.4 5.6)? Does it identify the same position as (make-posn 3 6)? Maybe there is a reason posn has reals, but I do not see why. If there is such a reason, please tell me.
Racket is great!!!
Jos
I’ve never used graphics/graphics, which I see in the documentation “originated as SIXlib, a library of X Windows commands available within Chez Scheme at Rice University.” I’ve never seriously used libx11, either, but I see that its equivalent functions do use int, interestingly.
However, in Racket, graphics/graphics is implemented on top of racket/draw (with parts of racket/gui), which uses Cairo under the hood. In racket/draw, coordinates do not necessarily correspond to physical pixels. A racket/draw drawing context (dc<%>) has a “transformation matrix” which can scale, rotate, or add an offset to all drawing. An especially prominent use-case is for HiDPI displays, where 1.0 drawing unit might correspond to 2.0 physical pixels (or some fractional number): this is related to the “backing scale” of a bitmap or display. Non-integer drawing units are also useful more generally, e.g. with rotation, to defer any rounding to the last possible stage in the pipeline.
Thanks for your clear answer.
Yes, thank you for the explanation.
Although when I looked at draw for the fist time I recognized (almost) immediately that the API looked very much like Windows GDI, I was not aware until now that it actually was based on Cairo.
Windows GDI drawing functions all take integral coordinates. DCs do have a transform matrix (see [Get/Set]MapMode) which defaults to 1:1.
I've done a lot of screen graphics with GDI and DirectX, but I never had a use for DC transforms - they always seemed more suited to print devices than to screen display. For whatever reasons I always did coordinate calculations myself.
Anyway, thanks again.
To clarify, the implementation is currently based on Cairo, and certainly it has influenced the interface design in recent years, but most of the racket/draw API predates the adoption of Cairo in Racket 5.1 (though it was formerly only available via racket/gui):
On the inside, version 5.1 is the biggest single change in Racket (or PLT Scheme) history. We’ve reimplemented the GUI layer, which meant throwing out about 200,000 lines of C++ code that built on Xt, Win32, and Carbon. We’ve replaced that C++ code with about 30,000 lines of Racket code that builds on Gtk, Win32, Cocoa, Cairo, and Pango.
…
Cairo and Pango are the two big enablers of the Racket graphics rewrite. The old Racket graphics library depended on many toolkits (X11, Win32, QuickDraw, Quartz, PostScript, and more), and it had poor font handling. Again, the problem was that we chose the previous technology in 1995. Cairo and Pango have since solved the portable-graphics problem, and we were able to trade in 80,000 lines of C++ glue for about 8,000 lines of Racket glue. The code could be much less if we didn’t have to match most of the old drawing API, but we're still very happy with the result.