UXGemGraphics
UXGemGraphics is the GEM realization of
UXGraphics: the AES’s own VDI
workstation, plus the theme.
#use <UXKit> // or #import "UXGemGraphics.xc"Thin on purpose
Section titled “Thin on purpose”It is the thinnest of the seven vocabularies. A
UXView that draws itself makes the same VDI
calls that objc_draw makes for a G_BUTTON.
Custom views and stock widgets are therefore pixel-consistent by construction. There is no separate drawing path to drift and no palette to keep in step, so a custom control drawn beside a native one matches it.
Every other backend (GDI, CoreGraphics, cairo, Canvas2D) is a sibling of this class, implementing the same protocol over a different surface.
The coordinate contract
Section titled “The coordinate contract”Incoming coordinates are bounds-relative; the bound origin makes them absolute:
g.bind(handle, theme, absRect);g.fillRect(UXGeom.make(0, 0, 10, 10), pen); // the view's own top-leftAll seven vocabularies share this contract, so a drawRect body is written
once. A view never knows where on screen it is.
GEM’s y grows down, the direction the whole protocol uses. The Mac shim flips to match; the other backends already agree.
It has theme art
Section titled “It has theme art”hasThemeArt() // trueGEM has a real theme with drawable slices, so
drawTheme draws something here. The GDI
and Cocoa vocabularies answer false, and the toolkit falls back to
drawing the pieces itself.
Capability queries in this toolkit follow this pattern: ask what the backend can do, and have a neutral answer for when it cannot.
It is the one that does not stroke natively
Section titled “It is the one that does not stroke natively”strokesNatively() // false — the only backend that says soThe VDI has no path stroker with joins and caps, so strokeNative is empty
and UXPainter’s neutral stroker does all
the work: a quad per segment, a fan per join, a polygon per cap.
Because GEM is the one backend where the neutral stroker is the only path, that stroker is exercised every time anything is stroked here. A regression in it shows up as a failing GEM test instead of going unnoticed.
On the other six backends, the neutral stroker still draws every arrowhead, because no platform has one.
Pens are indices
Section titled “Pens are indices”Colours are VDI pen indices rather than RGB, with fillRectRGB and
fillPolygonRGB as the true-colour entry points. Pen 0 is white and pen
1 is ink. A default
UXCharAttr uses 1 so that a
default-constructed style is visible.
The other backends mirror the same index table, so a pen means the same colour everywhere.
fontIdFor maps a family name to a VDI font id. A family the workstation
does not have falls back instead of failing, so a document written on one
machine stays legible on another.
Text measurement goes through the driver, not this class. Layout needs to
measure text before drawTextFont draws it.
See also
Section titled “See also”UXGraphics: the protocol, and the primitive setUXGemDriver: which owns the context it hands todrawRectUXPainter: the neutral stroker this backend depends on entirelyUXGdiGraphics: the first sibling