RENDER extension
Client-side compositing: alpha-blended composition of "pictures" (drawables plus a pixel format), solid fills, gradients, geometric rasterization (triangles, trapezoids) and anti-aliased glyph rendering. This is the foundation modern toolkits draw with instead of the core protocol.
- Module:
X.require('render', cb)(X nameRENDER) - Source:
lib/ext/render.js· Tests:test/render.js - Spec: renderproto.txt
X.require('render', (err, Render) => {
const pixmap = X.AllocID();
X.CreatePixmap(pixmap, root, 24, 100, 100);
const pic = X.AllocID();
Render.CreatePicture(pic, pixmap, Render.rgb24);
const grad = X.AllocID();
Render.LinearGradient(grad, [0, 0], [100, 0],
[[0, [1, 0, 0, 1]], [1, [0, 0, 1, 1]]]); // red -> blue
Render.Composite(Render.PictOp.Src, grad, 0, pic,
0, 0, 0, 0, 0, 0, 100, 100);
});
While requiring, the module calls QueryPictFormat and scans the reply for
the standard formats, exposing their PICTFORMAT ids as properties:
Render.mono1— 1-bit alpha (a1)Render.rgb24— 24-bit TrueColor without alpha (x8r8g8b8)Render.rgba32— 32-bit TrueColor with alpha (a8r8g8b8)Render.a8— 8-bit alpha-only
Colors are given as [r, g, b, a] arrays of floats in 0..1 (clamped, scaled
to 16 bits per channel). Coordinates and matrix/filter values are JS numbers
converted to 16.16 FIXED (truncated to 1/65536 units) on the wire.
Requests
QueryVersion(clientMajor, clientMinor, cb)
cb(err, [major, minor]). Not called automatically — the extension object
carries no version fields unless you call this yourself.
QueryPictFormat(cb) / QueryPictFormats(cb)
cb(err, {formats}) — formats is an array of 12-element arrays:
[id, type, depth,
redShift, redMask, greenShift, greenMask,
blueShift, blueMask, alphaShift, alphaMask, colormap]
QueryPictFormats is a protocol-name alias. The screen/depth/visual and
subpixel sections of the reply are not parsed. Called automatically by
X.require to discover the standard formats above.
QueryPictIndexValues(pictformat, cb)
cb(err, values) — array of {pixel, red, green, blue, alpha}. Only valid
for indexed pictformats; on TrueColor-only servers (e.g. Xvfb) the server
answers with a Match error.
CreatePicture(pid, drawable, pictformat, values)
Creates picture pid over drawable with the given pictformat. Optional
values object accepts: repeat (Render.Repeat), alphaMap (picture),
alphaXOrigin, alphaYOrigin, clipXOrigin, clipYOrigin, clipMask
(pixmap or 0), graphicsExposures, subwindowMode, polyEdge
(Render.PolyEdge), polyMode (Render.PolyMode), dither (atom),
componentAlpha. No reply.
ChangePicture(pid, values)
Changes picture attributes; same values keys as CreatePicture, and any
key that is not undefined is sent (so 0 works, e.g. {clipMask: 0} resets
the clip). No reply.
SetPictureClipRectangles(pid, clipXOrigin, clipYOrigin, rects)
Sets the clip list; rects is a flat array [x1, y1, w1, h1, x2, y2, ...].
No reply.
FreePicture(pid)
No reply.
Composite(op, src, mask, dst, srcX, srcY, maskX, maskY, dstX, dstY, width, height)
The central operation: composites src (optionally through mask, 0 =
none) into dst with operator op (Render.PictOp). No reply.
Trapezoids(op, src, srcX, srcY, dst, maskFormat, trapz)
Rasterizes trapezoids; trapz is a flat list of 10 values per trapezoid:
top, bottom, leftX1, leftY1, leftX2, leftY2, rightX1, rightY1, rightX2, rightY2 (floats, converted to FIXED). Deprecated by the Render spec in
favor of Triangles/AddTraps, but functional. No reply.
Triangles(op, src, srcX, srcY, dst, maskFormat, tris)
Rasterizes triangles; tris is a flat array of vertex coordinates
[x1, y1, x2, y2, x3, y3, ...] (6 numbers per triangle, floats).
maskFormat is a pictformat or 0. No reply.
TriStrip(op, src, srcX, srcY, dst, maskFormat, points)
Triangle strip; points is a flat array [x1, y1, x2, y2, ...], each point
after the second adds a triangle. No reply.
TriFan(op, src, srcX, srcY, dst, maskFormat, points)
Triangle fan; same points layout as TriStrip, first point shared by all
triangles. No reply.
CreateGlyphSet(gsid, format)
Creates glyph set gsid whose glyphs use pictformat format (typically
Render.a8 for anti-aliased or Render.mono1 for bitmap glyphs). No reply.
ReferenceGlyphSet(gsid, existing)
Makes gsid a new reference to the existing glyph set. No reply.
FreeGlyphSet(gsid)
No reply.
AddGlyphs(gsid, glyphs)
Uploads glyph images. Each glyph is
{id, width, height, x, y, offX, offY, image} where image is a Buffer of
width * height bytes (for a8), x/y place the origin relative to the
bitmap, and offX/offY (pen advance) are given in 1/64 pixel units —
divided by 64 before sending. Rows are re-padded to a 4-byte stride
automatically. No reply. Caveats: the passed glyph objects are mutated
(image/width/offX/offY rewritten), and the request always uses BIG-REQUESTS
length encoding, so it requires the default auto-enabled
ext/big-requests.md.
AddGlyphsFromPicture(gsid, src, glyphs)
Copies glyphs from picture src; glyph entries additionally carry
srcX/srcY. No reply. As far as we know no X server implements this
request (expect a Bad Implementation error).
FreeGlyphs(gsid, glyphIds)
Removes the glyphs with the given ids from the set. No reply. Freed glyphs
are silently skipped by later CompositeGlyphs.
CompositeGlyphs8/16/32(op, src, dst, maskFormat, gsid, srcX, srcY, glyphs)
Draws glyph runs from glyph set gsid into dst (also callable as
CompositeGlyphs(glyphBits, op, ...) with glyphBits 8/16/32 selecting the
glyph index width). glyphs is an array whose entries are:
'string'— glyph indices are the char codes, drawn at the current pen position (0,0 delta);[dx, dy, 'string']— pen moves bydx,dybefore drawing;- a number — switches to that glyph set for subsequent entries.
Strings are limited to 254 glyphs per entry (longer strings are not split automatically). No reply.
FillRectangles(op, pid, color, rects)
Fills rectangles with a solid color ([r, g, b, a] floats); rects is a
flat array [x1, y1, w1, h1, ...]. No reply.
CreateCursor(cid, source, x, y)
Creates cursor cid from picture source — which must be an ARGB32
(Render.rgba32) picture — with hotspot x,y. No reply.
SetPictureTransform(pid, matrix)
Sets the projective transform applied when pid is used as a source;
matrix is an array of exactly 9 numbers (3x3 row-major). Throws on wrong
length or non-number elements. No reply.
QueryFilters(cb)
cb(err, [aliases, filters]) — filters is an array of filter name
strings, aliases an array of CARD16 indices mapping each filter to the one
it aliases (0xffff = no alias). Always queries the first screen's root
drawable.
SetPictureFilter(pid, name, filterParams)
Sets the source filter. Known names are validated client-side:
'nearest'/'bilinear'/'fast'/'good'/'best' (no parameters),
'convolution' (flat array [w, h, elem1, ..., elemWxH]), 'binomial' and
'gaussian' (exactly 1 number). Any other name throws, so server-specific
filters reported by QueryFilters beyond this list cannot be set. No reply.
CreateAnimCursor(cid, cursors)
Creates an animated cursor; cursors is an array of [cursor, delayMs]
pairs (or {cursor, delay} objects). No reply.
AddTraps(pic, offX, offY, trapList)
Adds trapezoids to an alpha picture; trapList is a flat array of FIXED
values (6 per trap: top l, r, y then bottom l, r, y), offset by
offX,offY. No reply.
CreateSolidFill(pid, r, g, b, a)
Creates a solid-fill source picture; channels are floats 0..1. No reply.
LinearGradient(pid, p1, p2, stops) / CreateLinearGradient(...)
Creates a linear gradient source from point p1 to p2 ([x, y] arrays).
stops is an array of [offset, [r, g, b, a]] pairs, offsets 0..1
ascending. No reply. CreateLinearGradient is a protocol-name alias.
RadialGradient(pid, p1, p2, r1, r2, stops) / CreateRadialGradient(...)
Radial gradient between the circle at p1 with radius r1 and the circle
at p2 with radius r2; same stops format. No reply.
ConicalGradient(pid, center, angle, stops) / CreateConicalGradient(...)
Conical gradient around center ([x, y]) starting at angle degrees;
same stops format. No reply.
Events / errors
No events. Five extension errors get descriptive messages via registered error parsers: PictFormat, Picture, PictOp, GlyphSet and Glyph ("...argument does not name a defined ...").
Notes
- Standard-format discovery happens once at require time; if a server lacks
one of the standard formats the corresponding property (
mono1,rgb24,rgba32,a8) is simplyundefined. - Enums attached to the extension object:
Render.PictOp— compositing operators: the PictOpClear..Saturate range (0..13), Disjoint* (0x10..0x1b), Conjoint* (0x20..0x2b) and the 0.11 blend modes Multiply..HSLLuminosity (0x30..0x3e).Render.PolyEdge = {Sharp: 0, Smooth: 1},Render.PolyMode = {Precise: 0, Imprecise: 1}Render.Repeat = {None: 0, Normal: 1, Pad: 2, Reflect: 3}Render.Subpixel = {Unknown: 0, HorizontalRGB: 1, HorizontalBGR: 2, VerticalRGB: 3, VerticalBGR: 4, None: 5}Render.Filters = {Nearest: 'nearest', Bilinear: 'bilinear', Convolution: 'convolution', Fast: 'fast', Good: 'good', Best: 'best'}
- FIXED conversion truncates toward zero (
parseInt(f * 65536)), so tiny negative values round up.