# Posn in graphics/graphics

**URL:** <https://racket.discourse.group/t/posn-in-graphics-graphics/4273>\
**Category:** Questions & Answers\
**Created:** [May 31, 2026, 4:48pm UTC](https://racket.discourse.group/t/posn-in-graphics-graphics/4273 "2026-05-31T16:48:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![joskoot](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joskoot/32/1964_2.png) [@joskoot](https://racket.discourse.group/u/joskoot)\
**Post date:** [May 31, 2026, 4:48pm UTC](https://racket.discourse.group/t/posn-in-graphics-graphics/4273/1 "2026-05-31T16:48:05Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [May 31, 2026, 6:01pm UTC](https://racket.discourse.group/t/posn-in-graphics-graphics/4273/2 "2026-05-31T18:01:15Z")

</div>

I’ve never used `graphics/graphics`, which I [see in the documentation](https://docs.racket-lang.org/graphics/index.html) “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](https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#Drawing_Points_Lines_Rectangles_and_Arcs) 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”](https://docs.racket-lang.org/draw/overview.html#%28part._.Transformations%29) 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](https://docs.racket-lang.org/draw/bitmap_.html#%28tech._backing._scale%29) or [display](https://docs.racket-lang.org/gui/Windowing_Functions.html#%28def._%28%28lib._mred%2Fmain..rkt%29._get-display-backing-scale%29%29). 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.

---

<div class="post-metadata">

**Author:** ![joskoot](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joskoot/32/1964_2.png) [@joskoot](https://racket.discourse.group/u/joskoot)\
**Post date:** [June 1, 2026, 5:47am UTC](https://racket.discourse.group/t/posn-in-graphics-graphics/4273/3 "2026-06-01T05:47:23Z")

</div>

Thanks for your clear answer.

---

<div class="post-metadata">

**Author:** ![gneuner](https://avatars.discourse-cdn.com/v4/letter/g/b9e5f3/32.png) [@gneuner](https://racket.discourse.group/u/gneuner)\
**Post date:** [June 1, 2026, 3:06pm UTC](https://racket.discourse.group/t/posn-in-graphics-graphics/4273/4 "2026-06-01T15:06:54Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [June 1, 2026, 4:02pm UTC](https://racket.discourse.group/t/posn-in-graphics-graphics/4273/5 "2026-06-01T16:02:21Z")

</div>

> [@gneuner](#):
>
> 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.

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](https://web.archive.org/web/20101211053922/http://blog.racket-lang.org/2010/12/racket-version-5.html) (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.
