The Graphics Class#
Graphics is the high-level, immediate-mode 2D drawing interface. It renders
fills, strokes, paths, text, images, and GPU textures into a rendering surface
through the active GraphicsContext. You rarely
construct one yourself - the most common way to obtain a Graphics is inside
Component::paint.
void MyComponent::paint (Graphics& g) override
{
g.setFillColor (Colors::cornflowerblue);
g.fillAll();
}
The state model#
Graphics is a stateful drawing context. Drawing calls use the current state:
fill color / gradient, stroke color / gradient, stroke type, blend mode,
opacity, transform, drawing area, and clip path. You set state, then draw.
g.setFillColor (Colors::white); // set state
g.fillRect (bounds); // draw with current state
g.setStrokeColor (Colors::black); // change state
g.setStrokeWidth (2.0f);
g.strokeRect (bounds); // draw with new state
Saving and restoring state#
Use saveState() to snapshot the full state and restore it automatically. It
returns a SavedState RAII guard: when it leaves scope (or you call
restore()), the previous state is reinstated. This is the safe way to apply a
temporary transform, clip, or color.
{
auto saved = g.saveState();
g.setTransform (AffineTransform::rotation (angle, cx, cy));
g.setClipPath (clipBounds);
g.setFillColor (Colors::red);
g.fillPath (needle);
} // state restored here
Colors, gradients, and strokes#
Fills and strokes each have an independent color or gradient. Setting a color switches that channel to solid; setting a gradient switches it to the gradient.
g.setFillColor (Colors::orange); // solid fill
g.setFillColorGradient (myGradient); // gradient fill
g.setStrokeColor (Colors::black); // solid stroke
g.setStrokeWidth (3.0f); // convenience for stroke width
g.setStrokeType ({ 3.0f, StrokeJoin::Round, StrokeCap::Round });
g.setStrokeJoin (StrokeJoin::Bevel);
g.setStrokeCap (StrokeCap::Square);
g.setStrokeMiterLimit (4.0f);
See Primitives for the stroke types and gradients.
Opacity, blending, and feather#
g.setOpacity (0.5f); // 0..1, applies to subsequent drawing
g.setBlendMode (BlendMode::Multiply); // compositing mode
g.setFeather (2.0f); // soft edge falloff
Transform, drawing area, and clip#
Transform - an
AffineTransformapplied to all subsequent geometry.setTransformreplaces it;addTransformcomposes on top of the current one.Drawing area - the rectangle drawing is offset into and clipped against (
setDrawingArea/getDrawingArea).fillAll()fills this area.Clip path - a rectangle or
Paththat constrains drawing (setClipPath/getClipPath).
g.addTransform (AffineTransform::translation (10.0f, 10.0f));
g.setClipPath (contentBounds);
Drawing operations#
Fills and strokes#
Every shape has a fill* (solid interior) and stroke* (outline) form. Stroke
width and style come from the current stroke state.
Shape |
Fill |
Stroke |
|---|---|---|
Whole area |
|
- |
Line |
- |
|
Rectangle |
|
|
Rounded rect |
|
|
Ellipse |
|
|
Path |
|
|
Rounded rectangles accept either a uniform radius or four per-corner radii (top-left, top-right, bottom-left, bottom-right).
g.setFillColor (Colors::darkslategray);
g.fillRoundedRect (bounds, 8.0f);
g.setStrokeColor (Colors::white);
g.setStrokeWidth (1.5f);
g.strokeRoundedRect (bounds, 8.0f);
Text#
Text is drawn fitted into a rectangle with a Font and Justification. Fonts
come from the ApplicationTheme, not constructed inline.
auto font = ApplicationTheme::getGlobalTheme()->getDefaultFont();
g.setFillColor (Colors::white);
g.fillFittedText ("Hello YUP", font, textBounds, Justification::center);
StyledText overloads (fillFittedText (const StyledText&, ...)) draw
pre-laid-out attributed text. There are strokeFittedText variants for outlined
text.
Images and GPU textures#
g.drawImageAt (image, { x, y }); // draw at a point, natural size
g.drawImage (image, targetRect); // scale into a rectangle
g.drawTexture (gpuTexture, targetRect); // draw a GPU texture directly
drawTexture composites a GpuTexture
straight from the RHI (e.g. GpuCanvas::asTexture()) without allocating a
CPU-side image - the fast path for GPU-generated content.
Transparency layers#
For correct group opacity - where a set of overlapping shapes must fade as a single unit - use a transparency layer. It renders offscreen, then composites the finished result back with the layer opacity.
auto layer = g.beginTransparencyLayer (targetArea, 0.5f);
if (layer.isValid())
{
auto& lg = layer.getGraphics(); // draws in layer-local coordinates
lg.setFillColor (Colors::red);
lg.fillEllipse (circleA);
lg.fillEllipse (circleB); // overlap won't double up when faded
layer.commit();
}
Inside the layer, coordinates are layer-local: the target area’s top-left is
(0, 0).
Offscreen rendering into an Image#
Graphics can be constructed to render into an Image on the GPU and read the
result back on the CPU - useful for thumbnails, export, and tests.
Image target { 512, 512, PixelFormat::RGBA };
{
Graphics g { context, target };
g.setFillColor (Colors::cornflowerblue);
g.fillAll();
g.readPixelsToImage(); // fills target's CPU pixel buffer
}
// target now holds the rendered pixels
Related methods: isOffscreen(), commitOffscreenTarget(), commitToImage()
(sets the rendered GPU texture on the Image for later drawImage without a CPU
round-trip), and readPixelsToImage().
Tip
For richer GPU work - custom pipelines, render passes, and post-processing -
step down to the RHI. GpuCanvas in particular bridges 2D
Graphics drawing and low-level render passes on one surface.
The GraphicsContext#
GraphicsContext abstracts the active rendering backend behind one interface.
It is created via a static factory with an Api and Options:
GraphicsContext::Options options;
auto context = GraphicsContext::createContext (GraphicsContext::Metal, options);
Supported Api values: Headless, OpenGL, OpenGLES, Direct3D, Metal,
WebGPU. Key Options include retinaDisplay, allowHeadlessRendering,
enableReadPixels.
The context owns backend resources and exposes capability probes such as
getApi(), dpiScale(handle), and isGpuAvailable(). In a typical
application the windowing layer creates and drives the context for you, handing
a ready-to-use Graphics to each Component::paint.
See also#
Primitives - the value types drawing calls consume.
How to draw - a practical, task-oriented drawing guide.
RHI - the low-level GPU layer beneath
Graphics.