Cairo Antialiasing Modes: When SUBPIXEL Helps and When It Hurts
Cairo offers NONE, GRAY and SUBPIXEL antialiasing, but SUBPIXEL is silently downgraded on PDF/PS. Match the mode to the surface type for predictable rendering.
23 Oct 2025, 07:00 UTC

You set cairo_set_antialias to SUBPIXEL for crisp UI text, ship the app, and then your PDF export looks either unchanged or subtly worse. That mismatch is the Cairo antialiasing trap: the mode you request is not always the mode you get, and the right choice depends on the surface, not on personal preference.
The useful takeaway is to treat antialiasing as a surface contract. Pick GRAY for portable vector and image output, SUBPIXEL only for on-screen RGB LCD surfaces where you control pixel geometry, and NONE for performance-critical pixel art or overlays. Check the surface type before you set the mode.
The concrete problem: crisp on screen, inconsistent on export
Cairo exposes three antialiasing modes per context via cairo_set_antialias(). The mode affects fill(), stroke(), and text rendering by how edge coverage is blended into destination pixels.
- NONE disables blending. Edges are aliased, fast, and jagged.
- GRAY blends edges with grayscale coverage. It is device independent.
- SUBPIXEL exploits the physical RGB stripe layout of LCD subpixels to increase effective horizontal resolution. It can sharpen horizontal strokes and text on standard LCDs.
SUBPIXEL is the source of surprise. On a typical RGB-stripe LCD it can improve perceived sharpness. On non-standard pixel layouts, rotated displays, or surfaces that have no subpixel information, it can introduce color fringes. More importantly, Cairo silently downgrades SUBPIXEL to GRAY on PDF and PostScript surfaces.
Backend compatibility and silent downgrades
Antialiasing is surface-type dependent. The mode is not a global preference you can toggle mid-draw without recreating the context.
GRAY is the safest default for PDF, PS, and most image surfaces. It ignores subpixel ordering and produces consistent results across devices and printers. It does not provide the horizontal-line sharpness of SUBPIXEL on LCDs, but it will not produce color artifacts in vector output.
SUBPIXEL requires subpixel information from the surface. Cairo will accept the request on an image surface, but on PDF and PS surfaces the request is silently ignored and GRAY is used. Developers expecting LCD-sharpened vector output get no effect and no warning.
NONE produces crisp but jagged edges. The decision is per-surface and cannot be altered without creating a new cairo context and surface. Code that toggles modes dynamically on the same surface will not behave as expected.
Worked example: choose mode by surface type
The pattern is to query the surface type, then set the mode once at context creation.
// pseudo C, run where you create the Cairo context
cairo_surface_t *surface = ...; // image surface for screen, or pdf surface for export
cairo_t *cr = cairo_create(surface);
cairo_surface_type_t type = cairo_surface_get_type(surface);
if (type == CAIRO_SURFACE_TYPE_IMAGE) {
// On-screen RGB LCD, subpixel info likely available
cairo_set_antialias(cr, CAIRO_ANTIALIAS_SUBPIXEL);
} else if (type == CAIRO_SURFACE_TYPE_PDF || type == CAIRO_SURFACE_TYPE_PS) {
// Vector output: force GRAY for portability
cairo_set_antialias(cr, CAIRO_ANTIALIAS_GRAY);
} else {
// Fallback for other backends
cairo_set_antialias(cr, CAIRO_ANTIALIAS_GRAY);
}
Meaningful placeholders: surface is the target you created with cairo_image_surface_create or cairo_pdf_surface_create. Required permissions are normal file write access for PDF/PS output. Expected check: after creation, rendering of small text and 45-degree lines should show RGB subpixel patterns on an LCD image surface with SUBPIXEL, and uniform grayscale blending on PDF with GRAY. Risk: setting SUBPIXEL on a PDF surface does not error, it is silently downgraded, so visual tests are the only way to notice.
Trade-off and limitation
SUBPIXEL improves perceived sharpness for horizontal features on standard LCDs at the cost of portability and potential color fringing. GRAY is portable and predictable at the cost of maximum on-screen crispness. NONE is fastest but visually harsh.
A practical way to check the result is to render the same 45-degree line in each mode to a small image surface and magnify the edge. SUBPIXEL should show RGB subpixel patterns on an LCD, GRAY shows uniform grayscale blending, NONE shows a stair-step edge. For PDF, inspect the output at high zoom in a viewer; you will see GRAY blending regardless of the requested mode.
Changing the mode on an existing context requires recreating the target surface, because the mode is bound to surface capabilities. Do not attempt to switch modes mid-draw for the same surface.
Actionable closing
Default to CAIRO_ANTIALIAS_GRAY for any output that leaves your process. Use CAIRO_ANTIALIAS_SUBPIXEL only for on-screen image surfaces where you know the display is standard RGB stripe and you want sharper text. Reserve CAIRO_ANTIALIAS_NONE for pixel art, performance overlays, or when aliasing is intentional. Query cairo_surface_get_type before setting the mode, and test with a magnified edge sample for each backend you ship.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.