arc
arcn
break
call
circle
clip
, eoclip
Z
, z
, closepath
colorstop
C
, curveto
c
, rcurveto
defhsla
defrgba
ellipse
fill
, eofill
getmetadata
H
, h
if
lineargrad
L
, lineto
l
, rlineto
M
, moveto
m
, rmoveto
newpath
preserve
print
proc
Q
q
radialgrad
rect
repeat
resetclip
resetdash
resetmatrix
restore
rotate
roundedrect
save
scale
scalexy
setcolor
setdash
setdashoffset
sethsla
setlinecap
setlinejoin
setlinewidth
setrgba
setvar
stroke
S
, s
translate
T
, t
V
, v
drawvg (draw vector graphics) is a language to draw two-dimensional graphics on top of video frames. It is not intended to be used as a general-purpose language. Since its scope is limited, it prioritizes being concise and easy to use.
For example, using the Canvas API we can render a triangle running this code in a Web browser:
const canvas = document.getElementById("canvas"); const ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(125, 50); ctx.lineTo(100, 100); ctx.lineTo(150, 100); ctx.closePath(); ctx.stroke();
The same triangle can be written with this drawvg script:
moveto 125 50 lineto 100 100 150 100 closepath stroke
It can be shortened using the aliases for moveto
, lineto
,
and closepath
:
M 125 50 L 100 100 150 100 Z stroke
Both newlines (U+000A
) and spaces (U+0020
) can be used
interchangeably as delimiters, so multiple commands can appear on the
same line:
M 125 50 L 100 100 150 100 Z stroke
Finally, drawvg can use FFmpeg expressions and frame metadata in command arguments. In this example, we are using the variables w (frame width) and h (frame height) to create a circle in the middle of the frame.
circle (w / 2) (h / 2) (w / 3) stroke
Many commands are a direct equivalent to a function in the Cairo graphics library. For such commands, the reference below provides a link to the related Cairo documentation.
The syntax is heavily inspired by languages like
Magick
Vector Graphics, or SVG’s <path>
. Many command names are taken from
PostScript.
A drawvg script consists of a series of commands to describe 2D graphics.
A command is an identifier (like setcolor
or lineto
)
followed by its arguments. Each item in the code (command name,
arguments, etc.) is separated by any of the following characters:
' '
)
','
)
'\n'
)
'\t'
)
'\r'
)
The beginning of the item indicates how it will be interpreted:
//
Comment
0
, …, 9
, +
, -
Number literal
(
Expression
{
, }
Block delimiters
Name of a command, a color, etc.
Comments start with two slashes (//
), and stop at the end of the
line (either a \n
, or the end of the script).
circle 100 100 50 // this is ignored fill // this is also ignored
//
must appear after a space, or at the beginning of the line. If
//
is preceded by any non-blank character, the parser will
consider //
as part of the previous item.
For example, in this script:
circle 10 10 50// something
The parser throws an error because it tries to parse 50//
as a
number literal.
The way commands are parsed is inspired by SVG’s <path>
:
Most programming languages expect characters like parenthesis, commas, or semicolons, to separate items. For example:
moveto(10, 10); lineto(20, 30);
The equivalent in drawvg is:
moveto 10 10 lineto 20 30
closepath
or
stroke
), the next command starts at the next item.
Example |
---|
In the next script there are 4 different commands: newpath rect 10 20 30 40 setcolor teal fill |
Most commands in SVG’s <path>
are also present in drawvg. For some of them,
there is an alias to a longer name:
curveto
for C
.
rcurveto
for c
.
lineto
for L
.
rlineto
for l
.
moveto
for M
.
rmoveto
for m
.
closepath
for Z
, z
.
Other commands only exist in a single-letter form:
This makes it possible to use a path in SVG to create the same shape in a drawvg script.
For many commands, the name can be omitted when it is used multiple times in successive calls.
In the reference below, these commands has a Can be Implicit note in their signature.
Example |
---|
For example, in this script: M 50 50 l 10 10 l 10 -10 l 10 10 l 10 -10 l 10 10 stroke After the first call to M 50 50 l 10 10 10 -10 10 10 10 -10 10 10 stroke |
To reuse the same command (l
, in the previous example), the
parser checks if the item after the last argument is a numeric value,
like a number literal or a FFmpeg expression.
Example |
---|
In this example: l 10 20 30 40 stroke
|
This is another feature taken from SVG’s <path>
. An important difference with
SVG is that the separator between items is always required. In SVG, it can be
omitted in some cases. For example, the expression m1-2
is equivalent to
m 1 -2
in SVG, but a syntax error in drawvg.
Most commands expect numeric arguments, like number literals, variable names, or expressions.
setcolor
and colorstop
expect a color.
setlinecap
and setlinejoin
expect a constant value.
A number literal is an item in the script that represents a constant
value. Any item that starts with a decimal digit (between 0
and
9
), a -
or a +
, is interpreted as a number literal.
The value is parsed with
av_strtod
.
It supports the prefix 0x
to write a value with hexadecimal
digits, and
many
units (like K
or GiB
).
In the next example, all literals represent the same value:
10000 1e4 10K 0x2710
FFmpeg expressions can be used as arguments for any command that expects a numeric argument. The expression must be enclosed in parenthesis.
Example |
---|
The variables w and h represent the width and height of the
frame. We can compute the center of the frame by dividing them by M (w / 2) (h / 2) They can also contain parenthesis (to group operations, to call functions, etc): moveto ((w + 10) / 2) // x (h / (2 * cos(t))) // y |
The variables n and t can be used to compute a value that changes over time.
Example |
---|
To draw a circle oscillating from left to right, we can use an
expression based on circle (w / 2 + sin(2 * t) * w / 4) // x (h / 2) // y (w / 5) // radius stroke |
Expressions can be split in multiple lines, but they can’t contain comments within them.
moveto // This is a comment. (w // This is part of the expression, not a comment. + h)
When an expression is only a reference to a variable, the parenthesis can be omitted, and the item is just the variable name.
Example |
---|
The next 3 expressions are equivalent: in all cases, they create a rectangle covering the whole frame. rect (0) (0) (w) (h) rect 0 0 w h rect (0) 0 (w) h |
It is possible to create a variable with the same name of a command, and
then use it as an argument. In the previous example, the item h is a
reference to a variable (frame height), but in other contexts it may be
a command (h
).
For implicit commands, the parser prioritizes commands over variable names when it has to determine if the command is reused.
Example |
---|
In this example, the variable c is used as the first argument in two
calls to setvar c 5 l c 10 c 15 This issue can be fixed by surrounding the start of the second call with parenthesis: setvar c 5 l c 10 (c) 15 |
The color to stroke and to fill paths can be set with setcolor
.
Its argument has the same syntax for colors in FFmpeg:
#RRGGBB
format.
@a
suffix can be added to set the alpha value,
where a
is a number between 0
and 1
.
The color can be a variable name. In that case, its value is interpreted
as a 0xRRGGBBAA
code.
circle 75 100 50 setcolor #FF0000 fill circle 125 100 50 setvar CustomGreen 0x90EEAAFF setcolor CustomGreen fill circle 175 100 50 setcolor blue@0.5 fill
The commands setrgba
and sethsla
allow setting colors
using expressions.
defrgba
and defhsla
compute the color and store it in a
variable.
The argument for setlinecap
and setlinejoin
is an
identifier referring to a constant value.
setlinecap round
A path is a complex shape, composed by lines and curves, that can be used to fill a region, to stroke an outline, or to establish a clip region.
In order to draw anything on top of a video frame, first we have to
define a path, and then use stroke
or fill
.
The
tutorial
on paths in MDN is a good introduction to the topic. It is focused on
SVG’s <path>
, but the same concepts can be applied in drawvg.
Some commands require a current point. Initially, the
current point is set to
NaN
. It is initialized
with M
or moveto
. Other commands, like lineto
or
curveto
, updates the current point to the new end of the
shape.
The current point can be cleared with newpath
. Commands
that clear the path, like stroke
or fill
, also clear the
current point.
Example | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
Given this script: moveto 20 100 rlineto 150 -90 rlineto -50 200 closepath stroke These are the coordinates of the current point after executing each command:
The same script can be written with single-letter aliases: M 20 100 l 150 -90 -50 200 z stroke |
A path is defined by adding lines, curves, or basic shapes.
Single-letter commands are taken from SVG’s <path>
.
The region within the shape defined by a path can be filled with
fill
or eofill
. Each command uses a different
fill
rule:
fill
uses the
winding
rule, also known as
nonzero rule.
eofill
uses the
even–odd
rule.
Example |
---|
This script shows the difference between the winding and even–odd rules: rect 50 10 100 60 circle 150 70 40 setcolor seagreen fill rect 50 130 100 60 circle 150 190 40 setcolor skyblue eofill |
stroke
draws a line around the shape defined by the path. The
stroke can be configured with different commands:
Example |
---|
This example use moveto 0 0 lineto w h setlinecap round setdash 50 50 setlinewidth 20 setdashoffset (hypot(w, h) * t / -3) setcolor seagreen stroke |
A clip
region can be established with clip
and eoclip
.
If there is an active clip region, the new clip region will be the
intersection between the existing one and the path. resetclip
reset the clip region to the whole frame.
eoclip
uses the
even–odd
rule to compute the clip region.
Example |
---|
rect 50 50 100 200 clip circle 30 30 150 setcolor seagreen fill // Draw outside the clip region. resetclip circle 30 30 150 setlinewidth 3 setcolor skyblue stroke |
The path is cleared after any operation on it, like fill
or
stroke
. To reuse the same path in multiple operations,
preserve
must be called before them.
Example |
---|
In this example, each path is used twice. circle 120 120 50 setcolor seagreen preserve stroke clip circle 100 100 50 setcolor skyblue preserve fill setcolor tomato stroke |
A drawvg can use some variables, provided by the interpreter, to compute values in FFmpeg expressions:
X coordinate of the current point.
Y coordinate of the current point.
Width, in pixels, of the frame.
Height, in pixels, of the frame.
The loop counter in repeat blocks.
Frame number.
Timestamp, in seconds.
Timestamp, in seconds, of the first frame.
Duration, in seconds, of the frame.
New variables can be created with the setvar
command. It
associates a name with a numeric value.
The name must follow these rules:
_
).
The same variable can be assigned multiple times.
Example |
---|
In this example, the result of an expression is stored in a variable
with the name progress. Then, it is used for the x and
width arguments of setvar progress (w * (pow(mod(t / 2 + 0.5, 1), 2.5))) rect ((w - progress) / 2) 0 progress h setcolor darkblue fill |
Currently, a script can contain only 20 different variable names, but this limit can be modified in the future.
The pattern for fill and stroke operations can be either a solid color, or a gradient.
The pattern is not cleared after being used in a fill or stroke operation, but it is replaced by any command that sets a new pattern.
To configure a gradient, first call to lineargrad
or
radialgrad
, and then add color stops by calling colorstop
for each stop.
Example |
---|
In this example, the whole frame is filled with a linear gradient: lineargrad 0 0 w h colorstop 0 skyblue colorstop 1 darkblue rect 0 0 w h fill In this example, a radial gradient is used to simulate a sphere: radialgrad 90 90 5 120 120 100 colorstop 0.0 #90DDFF colorstop 0.9 #000030 colorstop 1.0 #000000 rect 0 0 w h fill |
setcolor
and colorstop
accept a variable name as the
argument. When a variable is used, its value is interpreted as a
0xRRGGBBAA
code.
Example |
---|
// Use color #1020FF, alpha = 50% setvar someblue 0x1020FF7F setcolor someblue rect 30 30 120 120 fill rect 90 90 120 120 fill |
If a variable has the same name of a known color, the variable has preference, and will be used instead of the predefined color.
Example |
---|
setcolor teal rect 30 30 120 120 fill setvar teal 0x70AAAAFF // Now, `teal` is #70AAAA setcolor teal rect 90 90 120 120 fill |
defrgba
and defhsla
compute the 0xRRGGBBAA
value
for a color given its color components:
Each color component must be in range 0
to 1
, except
hue, which is 0
to 360
.
Example |
---|
defrgba colorA 1 0.5 0.25 1 // colorA = RGB(255, 127, 63) defhsla colorB 200 0.75 0.25 1 // colorB = HSL(200, 75%, 25%) rect 0 0 (w / 2) h setcolor colorA fill rect (w / 2) 0 (w / 2) h setcolor colorB fill |
The coordinates for each command can be scaled, rotated, and translated, by using the following commands:
The transformations are applied when the command is executed. They have no effect on the existing path, only on the new segments added to it.
They are done by updating the
current
transformation matrix in the Cairo context. To reset the matrix to its
original state, before any transformation, use resetmatrix
.
The transform origin for scale and rotation is initially at 0, 0
,
but it can be adjusted with translate
.
Example |
---|
// Map (0, 0) as the center of the frame. translate (w / 2) (h / 2) // Scale the space as if the frame is 1x1 pixel. scalexy w h // Draw multiple lines with the same arguments, // but each one on a different rotation. repeat 10 { rotate (PI / 10) M -0.25 0 H 0.25 } // Reset transformations, so the scale does not // affect stroke. resetmatrix stroke |
The state of a drawvg script contains all parameters used for drawing operations, like the current color, the transformation matrix, the stroke configuration, etc.
The save
command pushes a snapshot of the state to an internal
stack. Later, restore
pops the latest snapshot from the stack,
and uses it as the new state.
The parameters that can be saved and restored are:
Some FFmpeg filters add metadata to frames. The command
getmetadata
can read metadata items containing a numeric value,
and store it in a variable that can be used for command arguments.
Example |
---|
The // Get metadata from cropdetect filter and store it // in `cd*` variables. getmetadata cdx lavfi.cropdetect.x getmetadata cdy lavfi.cropdetect.y getmetadata cdw lavfi.cropdetect.w getmetadata cdh lavfi.cropdetect.h rect cdx cdy cdw cdh setcolor yellow@0.5 setlinewidth 10 stroke To test the script, copy it to a ffplay -i example-video.webm -vf 'cropdetect, drawvg=file=drawcropdetect.vgs' |
if
/ repeat
Statements There is limited support for control flow statements: only if
and
repeat
.
Both commands receive two arguments: an expression and a block.
if (condition) { // commands } repeat (count) { // commands }
if
executes its block if the result of (condition)
is not
zero.
repeat
executes its block the number of times specified by
(count)
. In each iteration, the variable i is used as a
loop
counter.
If the result of the expression is not a finite number (like
NaN
) the block is not
executed.
FFmpeg expressions only supports arithmetic operators (like +
for addition).
Comparison operators (like !=
) are supported via functions, while
logical operators (like &&
for AND
) can be emulated with
arithmetic operations.
Expression | FFmpeg Equivalent |
---|---|
x = y | eq(x, y) |
x < y | lt(x, y) |
x > y | gt(x, y) |
x ≤ y | lte(x, y) |
x ≥ y | gte(x, y) |
a ≤ x ≤ b | between(x, a, b) |
Logical operators can be emulated with multiplication (for AND
),
or addition (for OR
):
Expression | FFmpeg Equivalent |
---|---|
x OR y | x + y |
x AND y | x * y |
Example |
---|
In other programming languages, a code like this: if (x > y && z != 1) { // … } Can be written for drawvg like this: if (gt(x, y) * not(eq(z, 1))) { // … } |
break
causes a repeat
loop to be terminated immediately.
If it is executed outside a repeat
block, it terminates the whole
script, or the current procedure.
Example |
---|
In this example, we are using the The loop can be executed moveto 0 0 repeat 500 { rlineto (randomg(0) * 15) (randomg(0) * 20) if (gt(cx, w)) { break } } stroke |
A procedure is a name associated with a block that can be executed multiple times. It can take between 0 and 6 parameters.
proc
is used to set the parameter names and the block for a
procedure:
proc p0 { // … } proc p1 param1 param2 { // … }
Inside the block, the arguments can be accessed as regular variables:
proc square center_x center_y side { rect (center_x - side / 2) (center_y - side / 2) side side }
call
executes the block assigned to the procedure name. It
requires the name of the procedure, and the value for each parameter
defined in the call to proc
.
call p0 call p1 1 2 call square (w / 2) (h / 2) (w / t)
Example |
---|
In this example, the procedure setvar len (w / 10) setlinewidth 5 proc zigzag { repeat 10 { l len len len (-len) } stroke } setcolor #40C0FF M 0 60 call zigzag setcolor #00AABB M 0 120 call zigzag setcolor #20F0B7 M 0 180 call zigzag The color and the Y coordinate of the starting point can be sent as procedure arguments: setvar len (w / 10) setlinewidth 5 proc zigzag color y { setcolor color M 0 y repeat 10 { l len len len (-len) } stroke } call zigzag 0x40C0FFFF 60 call zigzag 0x00AABBFF 120 call zigzag 0x20F0B7FF 180 |
When the procedure returns, the value of the variable for each argument
is restored to the value it had before calling the procedure. Changes in
other variables (with setvar
, getmetadata
, defhsla
,
and defrgba
) are preserved.
Example |
---|
In the next example, the variable A has the value setvar A 0 proc P A { print A } print A call P 1 print A It writes the following messages: [7:7] A = 0.000 [4:8] A = 1.000 [9:7] A = 0.000 |
break
causes the script to leave the current procedure, similar
to the
return
statement in other programming languages, unless it is called within a
repeat
loop.
The body of the procedure must be defined with proc
before
using call
.
Example |
---|
In this example, when the procedure call notyet proc notyet { // ... } |
A procedure can be redefined by other calls to proc
with the same
name. In such case, call
invokes the last assigned block.
Example |
---|
In this example, the procedure proc example { // block1 } call example // executes block1 proc example { // block2 } call example // executes block2 |
There are some functions specific to drawvg available in FFmpeg expressions.
p
p(x, y)
returns the color of the pixel at coordinates
x, y
, as a 0xRRGGBBAA
value. This value can be assigned to
a variable, which can be used later as the argument for setcolor
.
If the coordinates are outside the frame, or any of the arguments is not
a finite number (like
NaN
), the function
returns NaN
.
The transformation matrix is applied to the
arguments. To use the original frame coordinates, call
resetmatrix
between save
and restore
:
save resetmatrix setvar pixel (p(0, 0)) // top-left pixel of the frame. restore setcolor pixel
Bitwise operations can be used to extract individual color components:
setvar pixel (p(x, y)) if (not(isnan(pixel))) { setvar px_red (pixel / 0x1000000) setvar px_green (bitand(pixel / 0x10000, 0xFF)) setvar px_blue (bitand(pixel / 0x100, 0xFF)) setvar px_alpha (bitand(pixel, 0xFF)) }
pathlen
pathlen(n)
computes the length of the current path, by adding the
length of each line segment returned by
cairo_copy_path_flat
.
The function expects an argument n, as the maximum number of line
segments to add to the length, or 0
to add all segments.
Example |
---|
In this example, M (w / 2) (h / 2) setvar a -1 repeat 16 { rcurveto (a * 2 / 3) 0 (a * 2 / 3) (a) 0 (a) setvar a (-sgn(a) * (abs(a) + 10)) } setlinewidth 3 setdash (pathlen(0) * (1 - mod(t / 5, 1))) 1e6 setcolor teal stroke |
randomg
randomg(idx)
is similar to the random(idx)
function,
available in FFmpeg expressions, but its state is global to the frame, instead
of specific to each expression.
To understand the difference, we need to dive into how
random(idx)
works inside a drawvg script.
First, each expression in FFmpeg has a set of 10 internal variables,
which can be written with st(idx, value)
, and can be read with
ld(idx)
. idx is a value between 0
and 9
.
These variables are initialized to 0
.
When a drawvg script is parsed, each expression is compiled with
av_expr_parse
,
from libavutil, and these
compiled expressions are reused for every frame. The changes in the
internal variables (with st(idx, value)
) are visible between
frames, but they are not shared between expressions.
Example |
---|
In this example, the expression for the X coordinate updates its
internal variable circle (st(0, mod(ld(0) + 15, w))) // X 120 // Y (ld(0) + 20) // radius fill
The radius is not affected because its internal variable (from
Also, note that this example is just to show how internal variables are kept between frames. A better approach to create this animation is to use the variables n or t: circle (mod(n * 15, w)) 120 20 fill |
The function random(idx)
returns a
pseudorandom
value between 0
and 1
. idx is the internal variable
that is used both as the seed and to keep the state of the number
generator.
Example |
---|
The next example uses circle (random(0) * w) (random(0) * h) 10 fill The circle in every frame is at a different position, but always on the diagonal line of the frame. This happens because the values for the coordinates X and Y are identical, since both number generators use the same seed. To distribute the circles over the whole frame we need different seeds
for each expression. This can be achieved by writing a non-zero value
(like circle (random(0) * w) (st(0, if(ld(0), ld(0), 0xF0F0)); random(0) * h) 10 fill This approach is only useful if we need completely different positions in each frame. In the next example, random values are used to distribute many circles over the frame, but the position is fixed. The only change over time is the fill color: repeat 20 { circle (st(0, i + 1e5); random(0) * w) (st(0, i + 1e10); random(0) * h) 10 } sethsla (t * 60) 0.5 0.5 1 preserve fill setcolor black@0.5 setlinewidth 1 stroke This is achieved by using a precomputed state before calling |
The randomg(idx)
function, which is specific to drawvg scripts,
is similar to random(idx)
, but intended to solve the previous
problems:
The parameter idx has two uses:
randomg
with a specific index will use the
argument as the seed for the number generator in that index.
In a script like this:
M (randomg(0xFF1)) (randomg(0xFF0)) l (randomg(0xAA1)) (randomg(0xFF0))
There are 4 calls to randomg
:
0xFF1
, uses the internal state
at index 1
(because 0xFF1
modulo 4
is 1
).
Since this is the first use of that index, the number generator is
initialized with the seed 0xFF1
.
0
with the value 0xFF0
.
0xAA1
, and it uses index
1
. Since that state is already initialized (with the seed
0xFF1
), the value 0xAA1
is ignored, and it returns the
next number.
Example |
---|
This example renders a simple rain animation, moving lines from top to bottom.
rect 0 0 w h setcolor midnightblue fill setcolor white repeat 50 { setvar offset (t * (randomg(0) + 1)) moveto (mod(randomg(0) + offset / 6, 1) * w) (mod(randomg(0) + offset, 1) * h) rlineto 6 36 setlinewidth (randomg(1) / 2 + 0.2) stroke } |
print
It is possible to trace the execution of a drawvg script by printing the
value of an expression, either with the print
command, or with
the print function.
In both cases, the values are written to the FFmpeg log.
Printing expressions may have a noticeable impact on the performance, so it is preferable to use it only when necessary.
The function print(t)
writes the value of t, and returns its
argument.
Example |
---|
Given a line line this: M (sin(2 * PI * t) * w) 0 We can see the values of M (print(sin(2 * PI * t)) * w) 0 Executing this script with a 1 second / 8 FPS video shows the expected values for the sine function. $ ffmpeg \ -f lavfi \ -i 'color=r=8:d=1, drawvg=M (print(sin(2 * PI * t)) * w) 0' \ -f null /dev/null \ |& grep 'Eval @' [Eval @ 0x7f500f502d20] 0.000000 [Eval @ 0x7f4ff784b420] 0.707107 [Eval @ 0x7f4ff784ba20] 1.000000 [Eval @ 0x7f4ff784c020] 0.707107 [Eval @ 0x7f4ff784c620] 0.000000 [Eval @ 0x7f4ff784cc20] -0.707107 [Eval @ 0x7f4ff784d220] -1.000000 [Eval @ 0x7f4ff784d820] -0.707107 |
print
The command print
accepts an arbitrary number of arguments, and
for each one it writes:
When there are multiple expressions, they are separated by the |
character.
Example |
---|
The next script prints the position of the current point after the
M 10 20 l 100 100 print cx cy stroke For each frame, it produces this output: [3:7] cx = 110.000000 | [3:10] cy = 120.000000 The next example prints the values of $ ffmpeg \ -f lavfi \ -i 'color=r=8:d=1, drawvg=print (random(0))' \ -f null /dev/null \ |& grep 'drawvg @' [drawvg @ 0x50a000000180] [1:7] (random(0)) = 0.229731 [drawvg @ 0x50a000000180] [1:7] (random(0)) = 0.959813 [drawvg @ 0x50a000000180] [1:7] (random(0)) = 0.071676 [drawvg @ 0x50a000000180] [1:7] (random(0)) = 0.044600 [drawvg @ 0x50a000000180] [1:7] (random(0)) = 0.134127 [drawvg @ 0x50a000000180] [1:7] (random(0)) = 0.320513 [drawvg @ 0x50a000000180] [1:7] (random(0)) = 0.857675 [drawvg @ 0x50a000000180] [1:7] (random(0)) = 0.562456 |
arc
arc xc yc radius angle1 angle2
— Can be implicit
Adds a circular arc of the given radius to the current path. The arc is centered at xc, yc, begins at angle1 and proceeds in the direction of increasing angles to end at angle2.
If there is a current point, a line is added from it to the beginning of
the arc. If this is not desired, use newpath
before arc
to clear
the current point.
See the documentation of the
cairo_arc
function for more details.
Example |
---|
arc 120 120 60 0 (3 * PI / 2) stroke |
arcn
arcn xc yc radius angle1 angle2
— Can be implicit
Similar to arc
, but it differs in the direction of the arc
between the two angles.
See the documentation of the
cairo_arc_negative
function for more details.
Example |
---|
In this example, both arc 120 90 60 (PI / 2) 0 newpath arcn 120 150 60 (PI / 2) 0 stroke |
newpath
is needed to prevent a line between the two arcs.
break
break
break
terminates the execution of the innermost block, either a
repeat
loop or a procedure.
If it is used outside of a repeat
/ proc
block, it
terminates the script for the current frame.
call
call name args*
Invokes a procedure defined by proc
.
See the Procedures section above for more details.
circle
circle xc yc radius
— Can be implicit
Adds a circle of the given radius to the current path. The circle is centered at xc, yc. The current point is cleared before and after adding the circle.
This is a convenience wrapper for arc
. A call to circle
is
equivalent to:
newpath arc xc yc radius (0) (2 * PI) newpath
clip
, eoclip
clip, eoclip
Establishes a new clip region by intersecting the current clip region
with the current path as it would be filled by fill
or
eofill
.
eoclip
uses the
even–odd
rule. See fill rules for more details.
The path is cleared after updating the clip region, unless the
preserve
command is used before clip
or eoclip
.
See the documentation of the
cairo_clip
function for more details.
Z
, z
, closepath
Z, z, closepath
Adds a line segment to the path from the current point to the beginning
of the current sub-path, and closes this sub-path. The beginning is set by any
of the move commands (M
, m
, moveto
,
rmoveto
).
See the documentation of the
cairo_close_path
function for more details.
colorstop
colorstop offset color
— Can be implicit
Adds a color stop to a gradient pattern.
offset is a value between 0
and 1
, and it specifies
the location along the gradient’s control vector.
This command must be executed after lineargrad
or
radialgrad
.
Color stops can be added in any number of calls to colorstop
. In
the next example, the 3 blocks define the same gradient:
// 1 colorstop 0.0 red colorstop 0.5 green colorstop 1.0 blue // 2 colorstop 0 red 0.5 green colorstop 1 blue // 3 colorstop 0 red 0.5 green 1 blue
See the documentation of the
cairo_pattern_add_color_stop_rgba
function for more details.
Example |
---|
In this example, color stops are added in a lineargrad 0 0 w h repeat 6 { defhsla s (i * 60) 0.8 0.5 1 colorstop (i / 5) s } rect 0 0 w h fill It is possible to avoid transitions between color stops by repeating the same color in two stops: lineargrad 0 0 w h repeat 6 { defhsla s (i * 60) 0.8 0.5 1 colorstop (i / 5) s colorstop ((i + 1) / 5) s } rect 0 0 w h fill |
C
, curveto
C, curveto x1 y1 x2 y2 x y
— Can be implicit
Draw a cubic Bézier curve from the current point to the end point specified by x, y. The start control point is specified by x1, y1 and the end control point is specified by x2, y2.
The behaviour is identical to the C
command in SVG’s <path>
. For more
details, see Cubic Bézier Curve on MDN, and the Curve Commands section of the Paths tutorial on MDN.
Example |
---|
moveto 20 20 curveto 0 (h / 2) // start control point w (h / 2) // end control point (w - 20) (h - 20) // end point stroke |
c
, rcurveto
c, rcurveto dx1 dy1 dx2 dy2 dx dy
— Can be implicit
Like curveto
, but the coordinates are relative to the current point.
defhsla
defhsla varname h s l a
Similar to sethsla
, but instead of establishing the color for
stroke and fill operations, the computed color is stored as a
0xRRGGBBAA
value in the variable varname.
varname can then be used as a color for setcolor
and
colorstop
.
See sethsla
for more details on how the color is computed.
defrgba
defrgba varname r g b a
Computes a color from the red, green, blue, and
alpha components, and assigns it to the variable varname
as a 0xRRGGBBAA
value.
All components are values between 0
and 1
. Values outside
that range are clamped to it.
ellipse
ellipse cx cy rx ry
— Can be implicit
Adds an ellipse to the current path. Similar to circle
, but it is
possible to use different radius for both axes.
Example |
---|
ellipse 120 120 75 50 stroke |
fill
, eofill
fill, eofill
Fill the current path, using the current pattern (either a solid color or a gradient).
eofill
uses the
even–odd
rule. See fill rules for more details.
The path is cleared after the operation, unless the preserve
command is used before fill
or eofill
.
See the documentation of the
cairo_fill
function for more details.
getmetadata
getmetadata varname key
Get the value of a metadata entry created by another filter, and assign it to the variable varname.
If there is no metadata entry for key, or its value is not a
number, varname is set to
NaN
.
See the Frame Metadata section above for an example.
H
, h
H, h x
— Can be implicit
Draw a horizontal line from the current point to x.
The coordinate for H
is absolute, and for h
it is relative
to the current point.
if
if condition { block }
Executes a block if the value of condition is not zero, and a
finite number (unlike
NaN
).
See the Comparison and Logical Operators section above for more details on how to write conditional expressions.
lineargrad
lineargrad x0 y0 x1 y1
Set the current pattern to a new linear gradient, along the line from the coordinates x0, y0 to x1, y1.
This gradient can be used for stroke and fill operations.
Use colorstop
to set the color for each position in the gradient.
L
, lineto
L, lineto x y
— Can be implicit
Draw a line from the current point to the coordinates at x, y.
See the documentation of the
cairo_line_to
function for more details.
l
, rlineto
l, rlineto dx dy
— Can be implicit
Like lineto
, but the coordinates are relative to the current point.
M
, moveto
M, moveto x y
— Can be implicit
Begin a new sub-path, and set the current point to x, y.
m
, rmoveto
m, rmoveto dx dy
— Can be implicit
Like moveto
, but the coordinates are relative to the current point.
newpath
newpath
Begin a new sub-path. Like moveto
, but there is no
current point after it.
Example |
---|
In the next example, setlinewidth 3 setcolor skyblue arcn 70 90 20 0 (PI) arc 70 150 20 0 (PI) stroke setcolor seagreen arcn 170 90 20 0 (PI) newpath arc 170 150 20 0 (PI) stroke |
preserve
preserve
Indicates that the next operation to fill, stroke, or clip, must preserve the path, so the same path can be used in multiple operations.
It has effect on these commands:
The script can contain any command between preserve
and the
associated operation. This allows modifying other properties, like the
current color.
Example |
---|
In this example, the same path is used for both circle (w / 2) (h / 2) (w / 3) setcolor skyblue preserve fill setlinewidth 10 setcolor seagreen stroke |
preserve
can be called multiple times, if the same path has to be
used in 3 or more operations.
Example |
---|
In this example, the path created by circle 100 100 50 preserve fill preserve stroke clip |
print
print expr
— Can be implicit
Print its arguments to the FFmpeg log.
See the Command print section above for more details.
proc
proc name params* { block }
Assign the block and the parameters for the procedure name. The
procedure can be called multiple times with the call
command.
See the Procedures section above for more details.
Q
Q x1 y1 x y
Draw a quadratic Bézier curve from the current point to the end point specified by x, y. The control point is specified by x1, y1.
The behaviour is identical to the Q
command in SVG’s <path>
. For more
details, see Quadratic Bézier curve on MDN, and the Curve Commands section of the Paths tutorial on MDN.
Example |
---|
moveto 20 20 Q 0 h // control point (w - 20) (h - 20) // end point stroke |
q
q dx1 dy1 dx dy
Like Q
, but the coordinates are relative to the current point.
radialgrad
radialgrad cx0 cy0 radius0 cx1 cy1 radius1
Creates a new radial gradient between the two circles defined by cx0 cy0 radius0 and cx1 cy1 radius1. Each set of arguments is the coordinates of the center and the radius.
This gradient can be used for stroke and fill operations.
Use colorstop
to set the color for each position in the gradient.
Example |
---|
The animation in the next example shows how the two circles defined in
the The red circle represent the circle for the cx0 cy0 radius0 arguments, and the yellow circle is the one for the cx1 cy1 radius1 arguments. setvar cx0 (mod(t * 30, w)) setvar cy0 120 setvar radius0 20 setvar cx1 120 setvar cy1 120 setvar radius1 70 radialgrad cx0 cy0 radius0 cx1 cy1 radius1 colorstop 0 lightblue 1 darkblue // Fill the frame with the gradient. rect 0 0 w h fill // Draw inner circle. circle cx0 cy0 radius0 setcolor red stroke // Draw outer circle. circle cx1 cy1 radius1 setcolor yellow stroke |
rect
rect x y width height
Adds a rectangle of the given size (width × height), at position x, y, to the current path. The current point is cleared before and after adding the rectangle.
See the documentation of the
cairo_rectangle
function for more details.
repeat
repeat count { block }
Executes a block the number of times indicated by count.
In each iteration, the variable i is used as a
loop
counter. It takes the values from 0
to count - 1
. When
the loop is terminated, the variable is restored to the value before
starting the loop.
If count is less than 1
, or it is not a finite number
(like NaN
), the block is
not executed.
resetclip
resetclip
Reset the current clip region to its original state, covering the whole frame.
See the documentation of the
cairo_reset_clip
function for more details.
resetdash
resetdash
Disable the dash pattern to be used by stroke
. This reverts any
change made by setdash
and setdashoffset
.
It calls
cairo_set_dash
with num_dashes
set to 0
.
resetmatrix
resetmatrix
Resets the current transformation matrix.
restore
restore
Restores the state saved by a preceding call to save
.
For more details, see the State Stack section above, and the
cairo_restore
function.
rotate
rotate angle
Modifies the current transformation matrix by rotating the user-space axes by angle radians.
See the documentation of the
cairo_rotate
function for more details.
Example |
---|
In this example:
scalexy w h translate 0.5 0.5 rotate (PI / 4) rect -0.25 -0.25 0.5 0.5 resetmatrix stroke |
roundedrect
roundedrect x y width height radius
— Can be implicit
Like rect
, but a circular arc is used for the corners.
Example |
---|
The next example shows the same rectangle, with different values for the corner radius. The radius is computed by multiplying i (the
loop counter) by
repeat 9 { roundedrect (mod(i, 3) * 80 + 5) // x (floor(i / 3) * 80 + 5) // y 70 70 // size (i * 4.5) // radius } stroke |
save
save
Saves a copy of the current state on an internal stack. This copy can be
restored later with restore
.
For more details, see the State Stack section above, and the
cairo_save
function.
scale
scale sxy
Similar to scalexy
, but the same value is used for both axes. It
is equivalent to:
scalexy sxy sxy
scalexy
scalexy sx sy
Modifies the current transformation matrix by scaling the X and Y user-space axes by sx and sy respectively.
See the documentation of the
cairo_scale
function for more details.
See rotate
for an example on combining multiple transformations.
setcolor
setcolor color
Set a solid color as the current pattern for stroke and fill operations
See the Colors section above for more details.
setdash
setdash length
— Can be implicit
Sets the dash pattern to be used by stroke
.
Each call to setdash
adds a length to the pattern, alternating
between on and off portions of the stroke.
After a call to setdash
, resetdash
is needed either to
create a new pattern, or to discard the current one.
See the documentation of the
cairo_set_dash
function for more details.
setdashoffset
setdashoffset offset
Set the offset into the dash pattern at which the stroke should start.
setdash
must be called before setdashoffset
.
See the documentation of the
cairo_set_dash
function for more details.
Example |
---|
The next animation shows the effect of scalexy w h M 0.5 1 curveto 0 0.5, 1 0.5, 0.5 0 resetmatrix setdash 20 5 // 20 on, 5 off setdashoffset (t * 100) setlinewidth 20 stroke |
sethsla
sethsla h s l a
Set the current pattern to a solid color, given the hue, saturation, and lightness, and alpha components.
h is the hue, a value between 0
and 359
. Negative
values are clamped to 0
, and values greater than 359
are
interpreted as modulo 360.
s (saturation), l (lightness), and a (alpha), are
values between 0
and 1
.
The conversion to RGB is implemented according to the formulae from Wikipedia.
setlinecap
setlinecap cap
Set the current line cap style, which determines the shape used to draw the end points of lines.
cap must be one of the following names:
butt
round
square
It calls to
cairo_set_line_cap
to set the line cap style.
Example |
---|
This example draws 3 lines with the same length, each one with a different line cap style: setlinewidth 40 setlinecap butt setcolor tomato M 60 40 v 100 stroke setlinecap round setcolor seagreen M 120 40 v 100 stroke setlinecap square setcolor skyblue M 180 40 v 100 stroke M 20 40 H 220 m 0 100 H 20 setcolor black@0.5 setlinewidth 2 stroke |
setlinejoin
setlinejoin join
Sets the current line join style, which determines the shape used to join two line segments.
join must be one of the following names:
bevel
miter
round
It calls to
cairo_set_line_join
to set the line join style.
Example |
---|
This example draws 3 lines with the same length, each one with a different line join style: setlinewidth 30 setlinejoin bevel setcolor tomato M 70 20 l 50 50 50 -50 stroke setlinejoin miter setcolor seagreen M 70 90 l 50 50 50 -50 stroke setlinejoin round setcolor skyblue M 70 160 l 50 50 50 -50 stroke |
setlinewidth
setlinewidth width
Set the line width for stroke
.
width is affected by the transformation matrix.
To specify a width that is not affected by other transformations,
resetmatrix
can be used between save
/ restore
:
save resetmatrix setlinewidth 1 stroke // Restore matrix after stroke. restore
See the documentation of the
cairo_set_line_width
function for more details.
setrgba
setrgba r g b a
Set the current pattern to a solid color, given the red, green, blue, and alpha components.
All components are values between 0
and 1
. Values outside
that range are clamped to it.
setvar
setvar varname value
Set the variable varname to value.
See the User Variables section above for more details.
stroke
stroke
Strokes the current path according to the current line width, line join, line cap, and dash settings.
The path is cleared after the operation, unless the preserve
command is used before stroke
.
See the documentation of the
cairo_stroke
function for more details.
S
, s
S, s x2 y2 x y
— Can be implicit
Draw a smooth cubic Bézier curve from the current point to the end point specified by x, y. The end control point is specified by x2, y2.
The start control point is the reflection of the end control point of the previous curve command about the current point.
The behaviour is identical to the S
command in SVG’s <path>
. For more
details, see Cubic Bézier Curve on MDN, and the Curve Commands section of the Paths tutorial on MDN.
s
is like S
, but the coordinates are relative to the current point.
Example |
---|
M 20 120 c 25 -50, 25 50, 50 0 repeat 3 { s 20 50, 50 0 } stroke |
translate
translate tx ty
Modifies the current transformation matrix by translating the user-space origin by tx, ty.
See the documentation of the
cairo_translate
function for more details.
T
, t
T, t x y
— Can be implicit
Draw a smooth quadratic Bézier curve from the current point to the end point specified by x, y.
The control point is the reflection of the control point of the previous curve command about the current point.
The behaviour is identical to the T
command in SVG’s <path>
. For more
details, see Quadratic Bézier curve on MDN, and the Curve Commands section of the Paths tutorial on MDN.
t
is like T
, but the coordinates are relative to the
current point.
Example |
---|
M 20 120 q 10 -20, 20 0 repeat 9 { t 20 0 } stroke |
V
, v
V, v y
— Can be implicit
Draw a vertical line from the current point to y.
The coordinate for V
is absolute, and for v
it is relative
to the current point.
This document was generated using makeinfo.