- Qt 6.12
- Qt Canvas Painter
- QML Types
- Canvas2DContext
- Qt Canvas Painter | Commercial or GPLv3

# Canvas2DContext QML Type

Provides a 2D context for drawing on a Canvas2D item. More...

Import Statement: | `import QtCanvas2D`
Since: | Qt 6.12
Status: | Technology preview

This type is in technology preview and is subject to change.

- List of all members, including inherited members

## Properties

- antialias : real
- canvas : Canvas2D
- direction : string
- fillRule : string
- fillStyle : variant
- font : string
- globalAlpha : real
- globalBrightness : real
- globalCompositeOperation : string
- globalContrast : real
- globalSaturation : real
- highQualityStroking : bool
- lineCap : string
- lineJoin : string
- lineWidth : real
- miterLimit : real
- strokeStyle : variant
- textAlign : string
- textAntialias : real
- textBaseline : string
- textLineHeight : real
- textWrapMode : string
- windingEnforce : bool

## Methods

- void addPath(path2d path, transform2d transform)
- void addPath(path2d path, int start, int count, transform2d transform)
- void arc(real x, real y, real radius, real startAngle, real endAngle, bool anticlockwise)
- void arcTo(real x1, real y1, real x2, real y2, real radius)
- void beginHoleSubPath()
- void beginPath()
- void beginSolidSubPath()
- void bezierCurveTo(real cp1x, real cp1y, real cp2x, real cp2y, real x, real y)
- void circle(real centerX, real centerY, real radius)
- void cleanupResources()
- void clearRect(real x, real y, real width, real height)
- void closePath()
- boxgradient2d createBoxGradient(real x, real y, real width, real height, real feather, real radius)
- boxshadow2d createBoxShadow(real x, real y, real width, real height, real blur, string color, real radius)
- boxshadow2d createBoxShadow(real x, real y, real width, real height, real blur, string color, real radiusTopLeft, real radiusTopRight, real radiusBottomRight, real radiusBottomLeft)
- conicalgradient2d createConicalGradient(real x, real y, real angle)
- gridpattern2d createGridPattern(real x, real y, real width, real height, string lineColor, string backgroundColor, real lineWidth, real feather, real angle)
- lineargradient2d createLinearGradient(real x0, real y0, real x1, real y1)
- path2d createPath2D()
- path2d createPath2D(path2d path)
- path2d createPath2D(string svgPath)
- imagepattern2d createPattern(Image image, string repetition)
- radialgradient2d createRadialGradient(real x0, real y0, real r0, real x1, real y1, real r1)
- transform2d createTransform2D()
- void drawBoxShadow(boxshadow2d shadow)
- void drawImage(variant image, real dx, real dy)
- void drawImage(variant image, real dx, real dy, real dw, real dh)
- void drawImage(variant image, real sx, real sy, real sw, real sh, real dx, real dy, real dw, real dh)
- void ellipse(real centerX, real centerY, real radiusX, real radiusY)
- void ellipseRect(real x, real y, real width, real height)
- void fill()
- void fill(string fillRule)
- void fill(path2d path, int pathGroup)
- void fill(path2d path, string fillRule, int pathGroup)
- void fillRect(real x, real y, real width, real height)
- void fillText(text, x, y, maxWidth)
- void fillText(text, x, y, width, height)
- transform2d getTransform()
- void lineTo(real x, real y)
- object measureText(text)
- void moveTo(real x, real y)
- void quadraticCurveTo(real cpx, real cpy, real x, real y)
- void rect(real x, real y, real width, real height)
- void removePathGroup(int pathGroup)
- void reset()
- void resetClipping()
- void resetTransform()
- void restore()
- void rotate(real angle)
- void roundRect(real x, real y, real width, real height, real radius)
- void roundRect(real x, real y, real width, real height, real radiusTopLeft, real radiusTopRight, real radiusBottomRight, real radiusBottomLeft)
- void save()
- void scale(real scale)
- void scale(real sx, real sy)
- void setClipRect(real x, real y, real width, real height)
- void setPathWinding(string winding)
- void setTransform(transform2d transform)
- void setTransform(real a, real b, real c, real d, real e, real f)
- void skew(real angleX, real angleY)
- void stroke()
- void stroke(path2d path, int pathGroup)
- void strokeRect(real x, real y, real width, real height)
- void transform(transform2d transform)
- void transform(real a, real b, real c, real d, real e, real f)
- void translate(real x, real y)

## Detailed Description

The Canvas2DContext object can be created by `Canvas` item's `getContext()` method:

     Canvas2D {
       id: canvas
       onPaint: {
          var ctx = canvas.getContext('2d');
          //...
       }
     }

The Context2D API implements the same W3C Canvas 2D Context API standard with some enhanced features.

The Context2D API provides the rendering context which defines the methods and attributes needed to draw on the `Canvas` item. The following assigns the canvas rendering context to a `context` variable:

     var context = mycanvas.getContext("2d")

Here is a simple example of using Canvas2D to create a round button.

     let offsetX = 2;
     let offsetY = 4;
     let shadow = ctx.createBoxShadow(40 + offsetX, 70 + offsetY,
                                      120, 60,
                                      30, "#60373F26", 15);
     ctx.drawBoxShadow(shadow);
     // Paint rounded rect
     ctx.beginPath();
     ctx.roundRect(40, 70, 120, 60, 30);
     ctx.fillStyle = "#DBEB00";
     ctx.fill();
     // Paint text
     ctx.textAlign = "center";
     ctx.textBaseline = "middle";
     ctx.font = "24px 'Titillium Web'";
     ctx.fillStyle = "#373F26";
     ctx.fillText("CLICK!", 100, 100);

Here is another example of painting a simple graph.

     // Paint grid
     const grid = ctx.createGridPattern(0, 0, 10, 10,
                                        "#404040",
                                        "#202020");
     const w = 200;
     const h = 200;
     ctx.fillStyle = grid;
     ctx.fillRect(0, 0, w, h);
     // Paint axis
     ctx.fillStyle = "white";
     ctx.fillRect(0, 0.5 * h - 1, w, 2);
     ctx.fillRect(0.5 * w - 1, 0, 2, h);
     // Paint shadowed graph
     ctx.beginPath();
     ctx.moveTo(20, h * 0.8);
     ctx.bezierCurveTo(w * 0.2, h * 0.4,
                       w * 0.5, h * 0.8,
                       w - 20, h * 0.2);
     ctx.antialias = 10;
     ctx.lineWidth = 12;
     ctx.strokeStyle = "#D0000000";
     ctx.stroke();
     ctx.antialias = 1;
     ctx.lineWidth = 6;
     const lg = ctx.createLinearGradient(0, 0, 0, h);
     lg.addColorStop(0, "red");
     lg.addColorStop(1, "green");
     ctx.strokeStyle = lg;
     ctx.stroke();

## Property Documentation

### antialias : real

Holds the current antialias amount. More antialias means smoother painting. This only affects fill and stroke painting, not images or texts. The default value is `1.0` and the maximum value is `10.0`.

Antialiasing can be modified per-path so it can be set before each stroke/fill.

     ctx.lineWidth = 6;
     for (let i = 1; i < 10 ; i++) {
         let y = i * 20;
         ctx.antialias = i;
         ctx.beginPath();
         ctx.moveTo(20, y);
         ctx.bezierCurveTo(80, y + 20, 120,
                           y - 20, 180, y);
         ctx.stroke();
     }

See also textAntialias.

### canvas : Canvas2D

Holds the canvas item that the context paints on.

This property is read only.

### direction : string

Holds the current direction used to draw text. The possible values are:

Constant | Description
--- | ---
`"inherit"` | (default) The text direction is inherited from QGuiApplication layoutDirection. See https://doc.qt.io/qt-6/qguiapplication.html#layoutDirection-prop.
`"ltr"` | The text direction is left-to-right.
`"rtl"` | The text direction is right-to-left.
`"auto"` | The text direction is detected automatically based from the text string. See QString::isRightToLeft().

The default direction is `"inherit"`.

     ctx.textAlign = "center";
     ctx.textBaseline = "middle";
     ctx.font = "42px 'Titillium Web'";
     ctx.fillStyle = "black";
     ctx.fillText("Hi!", 100, 50);
     ctx.direction = "rtl";
     ctx.fillText("Hi!", 100, 150);

### fillRule : string

Holds the current fill rule used for filling shapes. This value is applied to all fill() calls after the rule has been set. The default fill rule is `"nonzero"`

The following fill rules are supported:

Constant | Description
--- | ---
`"nonzero"` | (or "WindingFill") The path is filled using the non zero winding rule. With this rule, we determine whether a point is inside the shape by using the following method. Draw a horizontal line from the point to a location outside the shape. Determine whether the direction of the line at each intersection point is up or down. The winding number is determined by summing the direction of each intersection. If the number is non zero, the point is inside the shape. This fill mode can also in most cases be considered as the intersection of closed shapes. This mode is the default.
`"evenodd"` | (or "OddEvenFill") The path is filled using the odd even fill rule. With this rule, we determine whether a point is inside the shape by using the following method. Draw a horizontal line from the point to a location outside the shape, and count the number of intersections. If the number of intersections is an odd number, the point is inside the shape.

     function paintStar() {
         ctx.beginPath();
         ctx.moveTo(120, 60);
         for (let i = 1; i < 6; ++i) {
             ctx.lineTo(60 + 60 * Math.cos(0.8 * i * Math.PI),
                 60 + 60 * Math.sin(0.8 * i * Math.PI));
         }
         ctx.fill();
         ctx.stroke();
     };
     ctx.fillRule = "nonzero";
     paintStar();
     ctx.translate(75, 75);
     ctx.fillRule = "evenodd";
     paintStar();

See also fill().

### fillStyle : variant

Holds the current style used for filling shapes. The default fill style is solid black ('#000000'). The style can be either a string containing a CSS color, QML color, or a canvas brush object. Invalid values are ignored. This property accepts several color syntaxes:

- 'rgb(red, green, blue)' - for example: 'rgb(255, 100, 55)' or 'rgb(100%, 70%, 30%)'
- 'rgba(red, green, blue, alpha)' - for example: 'rgb(255, 100, 55, 1.0)' or 'rgb(100%, 70%, 30%, 0.5)'
- 'hsl(hue, saturation, lightness)'
- 'hsla(hue, saturation, lightness, alpha)'
- '#RRGGBB' - for example: '#00FFCC'
- '#AARRGGBB' - for example: '#8000FFCC'
- SVG color name - for example: 'black', 'green' or 'lightsteelblue'
- Qt.hsla(hue, saturation, lightness, alpha) - for example: Qt.hsla(0.3, 0.7, 1, 1.0)
- Qt.rgba(red, green, blue, alpha) - for example: Qt.rgba(0.3, 0.7, 1, 1.0)

If `fillStyle` or strokeStyle is assigned many times in a loop, the Qt.rgba() syntax should be chosen, as it has the best performance, because it's already a valid QColor value and does not need to be parsed every time.

     ctx.fillStyle = "black";
     ctx.fillRect(20, 20, 160, 160);
     ctx.fillStyle = Qt.rgba(0, 0.25, 0.3, 1);
     ctx.fillRect(40, 40, 120, 120);
     ctx.fillStyle = "#2CDE85";
     ctx.fillRect(60, 60, 80, 80);

     const g2 = ctx.createRadialGradient(140, 40, 0, 300);
     g2.addColorStop(0, Qt.rgba(0.2, 0.8, 0.6));
     g2.addColorStop(1, Qt.rgba(0, 0.25, 0.3, 1));
     ctx.fillStyle = g2;
     ctx.fillRect(20, 20, 160, 160);
     g2.setCenterPosition(100, 100);
     ctx.fillStyle = g2;
     ctx.fillRect(40, 40, 120, 120);

See also createLinearGradient(), createRadialGradient(), createConicalGradient(), createBoxGradient(), createBoxShadow(), createPattern(), createGridPattern(), and strokeStyle.

### font : string

Holds the current font settings.

A subset of the w3C 2d context standard for font is supported:

- font-style (optional): normal | italic | oblique
- font-variant (optional): normal | small-caps
- font-weight (optional): normal | bold | 1 ... 1000
- font-size: Npx | Npt (where N is a positive number)
- font-family: See http://www.w3.org/TR/CSS2/fonts.html#propdef-font-family

Note: The font-size and font-family properties are mandatory and must be in the order they are shown above. In addition, a font family with spaces in its name must be quoted.

The default font value is "10px sans-serif".

### globalAlpha : real

Holds the current alpha (transparency) value applied to rendering operations. This alpha value is applied to all rendered shapes. Already transparent paths will get proportionally more transparent as well. Alpha should be between 0.0 (fully transparent) and 1.0 (fully opaque). By default alpha is `1.0`.

     ctx.fillStyle = "#d9f720";
     for (let i = 0; i < 4; i++) {
         let x = 100 * (i % 2);
         let y = 100 * Math.floor(i / 2);
         ctx.globalAlpha = 1.0 - i * 0.3;
         ctx.fillRect(x, y, 100, 100);
         ctx.drawImage("qt_logo2.png", x, y, 100, 100);
     }

### globalBrightness : real

Holds the current brightness value applied to rendering operations. This brightess is applied to all rendered shapes. A value of 0 will cause painting to be completely black. Value can also be bigger than 1.0, to increase the brightness. By default, brightness is `1.0`.

     ctx.fillStyle = "#d9f720";
     for (let i = 0; i < 4; i++) {
         let x = 100 * (i % 2);
         let y = 100 * Math.floor(i / 2);
         ctx.globalBrightness = 1.5 - i * 0.45;
         ctx.fillRect(x, y, 100, 100);
         ctx.drawImage("qt_logo2.png", x, y, 100, 100);
     }

### globalCompositeOperation : string

Holds the current composition operation. This mode is applied to all painting operations. Allowed operations are:

Constant | Description
--- | ---
`"source-atop"` | A atop B. Display the source image wherever both images are opaque. Display the destination image wherever the destination image is opaque but the source image is transparent. Display transparency elsewhere.
`"source-over"` | (default) A over B. Display the source image wherever the source image is opaque. Display the destination image elsewhere.
`"destination-out"` | B out A. Display the destination image wherever the destination image is opaque and the source image is transparent. Display transparency elsewhere. Note: To work properly, composite modes require enabling `alphaBlending` and using a transparent background for the canvas.

     const modes = ["source-over", "source-atop", "destination-out"];
     for (let i = 0; i < modes.length; i++) {
         // First item - source-over mode
         ctx.globalCompositeOperation = "source-over";
         let y = 5 + i * 65;
         ctx.fillStyle = "#D9F720";
         ctx.fillRect(20, y, 140, 40);
         // Second item - Different modes
         ctx.globalCompositeOperation = modes[i];
         ctx.beginPath();
         ctx.ellipse(130, y + 30, 60, 25);
         ctx.strokeStyle = "#00414A";
         ctx.fillStyle = "#2CDE85";
         ctx.fill();
         ctx.stroke();
     }

### globalContrast : real

Holds the current contrast value applied to rendering operations. This contrast is applied to all rendered shapes. A value of 0 will cause painting to be completely gray (0.5, 0.5, 0.5). Value can also be bigger than 1.0, to increase the contrast. By default, contrast is `1.0`.

     ctx.fillStyle = "#d9f720";
     for (let i = 0; i < 4; i++) {
         let x = 100 * (i % 2);
         let y = 100 * Math.floor(i / 2);
         ctx.globalContrast = 1.5 - i * 0.45;
         ctx.fillRect(x, y, 100, 100);
         ctx.drawImage("qt_logo2.png", x, y, 100, 100);
     }

### globalSaturation : real

Holds the current saturation value applied to rendering operations. This saturations is applied to all rendered shapes. A value of 0 will disable saturation and cause painting to be completely grayscale. Value can also be bigger than 1.0, to increase the saturation. By default, saturation is `1.0`.

     ctx.fillStyle = "#d9f720";
     for (let i = 0; i < 4; i++) {
         let x = 100 * (i % 2);
         let y = 100 * Math.floor(i / 2);
         ctx.globalSaturation = 1.5 - i * 0.5;
         ctx.fillRect(x, y, 100, 100);
         ctx.drawImage("qt_logo2.png", x, y, 100, 100);
     }

### highQualityStroking : bool

Holds the current high quality stroking enabling status. Setting this to `true` gives a more correct rendering in some less common cases where stroking overlaps and doesn't have full opacity. Enabling it results into higher rendering cost. The default value is `false`.

     // Increase the line width and reduce opacity to get
     // the stroking flaws visible.
     ctx.lineWidth = 20;
     ctx.globalAlpha = 0.5;
     if (myPath.isEmpty()) {
         myPath.moveTo(30, 30);
         myPath.lineTo(40, 30);
         myPath.lineTo(80, 170);
         myPath.lineTo(80, 30);
         myPath.lineTo(70, 30);
     }
     ctx.highQualityStroking = true;
     ctx.stroke(myPath);
     ctx.highQualityStroking = false;
     ctx.translate(90, 0);
     ctx.stroke(myPath);

### lineCap : string

Holds the current line cap style. The possible line cap styles are:

Constant | Description
--- | ---
`"butt"` | (default) The end of each line has a flat edge perpendicular to the direction of the line.
`"round"` | A semi-circle with the diameter equal to the width of the line is added on to the end of the line.
`"square"` | A rectangle with the length of the line width and the width of half the line width, placed flat against the edge perpendicular to the direction of the line.

     let path = ctx.createPath2D();
     path.moveTo(40, 60);
     path.lineTo(160, 60);
     ctx.lineCap = "butt";
     ctx.stroke(path);
     ctx.lineCap = "square";
     ctx.translate(0, 40);
     ctx.stroke(path);
     ctx.lineCap = "round";
     ctx.translate(0, 40);
     ctx.stroke(path);

### lineJoin : string

Holds the current line join style. A join exists at any point in a subpath shared by two consecutive lines. When a subpath is closed, then a join also exists at its first point (equivalent to its last point) connecting the first and last lines in the subpath.

The possible line join styles are:

Constant | Description
--- | ---
`"bevel"` | The triangular notch between the two lines is filled.
`"round"` | A circular arc between the two lines is filled.
`"miter"` | (default) The outer edges of the lines are extended to meet at an angle, and this area is filled.

     let path = ctx.createPath2D();
     path.moveTo(40, 20);
     path.lineTo(100, 80);
     path.lineTo(160, 40);
     path.lineTo(160, 70);
     ctx.lineJoin = "miter";
     ctx.stroke(path);
     ctx.lineJoin = "bevel";
     ctx.translate(0, 50);
     ctx.stroke(path);
     ctx.lineJoin = "round";
     ctx.translate(0, 50);
     ctx.stroke(path);

See also miterLimit.

### lineWidth : real

Holds the current line width. The default line width is `1.0`. When antialiasing is enabled, the line widths under a single pixel automatically fade the opacity, creating a smooth output.

     for (let i = 1; i < 10 ; i++) {
         let y = i * 20;
         ctx.lineWidth = 0.5 * i;
         ctx.beginPath();
         ctx.moveTo(20, y);
         ctx.bezierCurveTo(80, y + 20, 120,
                           y - 20, 180, y);
         ctx.stroke();
     }

See also stroke().

### miterLimit : real

Holds the current miter limit length. Miter limit controls when a sharp corner is beveled. When the corner length would become longer than this limit, a "bevel" lineJoin will be applied between the lines instead. This only has effect with the "miter" line join. The default limit is `10.0`.

     let path = ctx.createPath2D();
     path.moveTo(20, 40);
     path.lineTo(30, 130);
     path.lineTo(40, 40);
     path.lineTo(55, 80);

     ctx.lineJoin = "miter";
     ctx.miterLimit = 20;
     ctx.stroke(path);

     ctx.miterLimit = 8;
     ctx.translate(65, 0);
     ctx.stroke(path);

     ctx.miterLimit = 2;
     ctx.translate(65, 0);
     ctx.stroke(path);

See also lineJoin.

### strokeStyle : variant

Holds the current color or style to use for the lines around shapes, The style can be either a string containing a CSS color, QML color, or a canvas brush object. Invalid values are ignored.

The default value is black ('#000000').

     ctx.strokeStyle = "black";
     ctx.strokeRect(20, 20, 160, 160);
     ctx.strokeStyle = Qt.rgba(0, 0.25, 0.3, 1);
     ctx.strokeRect(40, 40, 120, 120);
     ctx.strokeStyle = "#2CDE85";
     ctx.strokeRect(60, 60, 80, 80);

     const g1 = ctx.createLinearGradient(180, 20, 20, 180);
     g1.addColorStop(0, Qt.rgba(0.2, 0.8, 0.6));
     g1.addColorStop(1, "black");
     ctx.strokeStyle = g1;
     ctx.strokeRect(20, 20, 160, 160);
     g1.addColorStop(1, "yellow");
     ctx.strokeStyle = g1;
     ctx.strokeRect(40, 40, 120, 120);

See also createLinearGradient(), createRadialGradient(), createConicalGradient(), createBoxGradient(), createBoxShadow(), createPattern(), createGridPattern(), and fillStyle.

### textAlign : string

Holds the current text alignment settings. The possible values are:

Constant | Description
--- | ---
`"start"` | (default) Align to the start edge of the text (left side in left-to-right text, right side in right-to-left text).
`"end"` | Align to the end edge of the text (right side in left-to-right text, left side in right-to-left text).
`"left"` | Align to the left.
`"right"` | Align to the right.
`"center"` | Center the text.

     ctx.font = "22px 'Titillium Web'";
     ctx.fillRect(100, 0, 1, 200);
     ctx.textAlign = "left";
     ctx.fillText("Left", 100, 40);
     ctx.textAlign = "center";
     ctx.fillText("Center", 100, 70);
     ctx.textAlign = "right";
     ctx.fillText("Right", 100, 100);
     ctx.textAlign = "start";
     ctx.fillText("Start", 100, 130);
     ctx.textAlign = "end";
     ctx.fillText("End", 100, 160);

See also textBaseline.

### textAntialias : real

Holds the current text antialias amount. The value is a multiplier to normal antialiasing, meaning that `0.0` disables antialiasing and `2.0` doubles it. The default value `is` 1.0.

Note: Due to the text antialiasing technique used (SDF), the maximum antialiasing amount is quite limited and this affects less when the font size is small.

     ctx.font = "22px 'Titillium Web'";
     ctx.textAntialias = 1.0;
     ctx.fillText("Antialiasing: 1.0", 100, 25);
     ctx.textAntialias = 2.0;
     ctx.fillText("Antialiasing: 2.0", 100, 75);
     ctx.textAntialias = 3.0;
     ctx.fillText("Antialiasing: 3.0", 100, 125);
     ctx.textAntialias = 4.0;
     ctx.fillText("Antialiasing: 4.0", 100, 175);

### textBaseline : string

Holds the current baseline alignment settings. The possible values are:

Constant | Description
--- | ---
`"top"` | The top of the em square
`"hanging"` | The hanging baseline
`"middle"` | The middle of the em square
`"alphabetic"` | (default) The alphabetic baseline
`"bottom"` | The bottom of the em square

     ctx.font = "22px 'Titillium Web'";
     ctx.fillRect(0, 60, 200, 1);
     ctx.fillRect(0, 140, 200, 1);
     ctx.textBaseline = "bottom";
     ctx.fillText("Bottom", 40, 60);
     ctx.textBaseline = "middle";
     ctx.fillText("Middle", 100, 60);
     ctx.textBaseline = "top";
     ctx.fillText("Top", 160, 60);
     ctx.textBaseline = "alphabetic";
     ctx.fillText("Alphabetic", 50, 140);
     ctx.textBaseline = "hanging";
     ctx.fillText("Hanging", 150, 140);

See also textAlign.

### textLineHeight : real

Holds the current text line height adjustment amount in pixels. The default line height is `0`.

     ctx.strokeRect(40, 5, 120, 60);
     ctx.strokeRect(40, 70, 120, 60);
     ctx.strokeRect(40, 135, 120, 60);
     ctx.textLineHeight = -10;
     ctx.fillText("Text with line height: -10",
                   40, 5, 120, 60);
     ctx.textLineHeight = 0;
     ctx.fillText("Text with line height: 0",
                   40, 70, 120, 60);
     ctx.textLineHeight = 10;
     ctx.fillText("Text with line height: 10",
                   40, 135, 120, 60);

### textWrapMode : string

Holds the current text wrap mode, so how the text is wrapped to multiple lines. The possible values are:

Constant | Description
--- | ---
`"nowrap"` | (default) No wrapping will be performed. If the text contains insufficient newlines, then contentWidth will exceed a set width.
`"wrap"` | If possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
`"wordwrap"` | Wrapping is done on word boundaries only. If a word is too long, content width will exceed a set width.
`"wrapanywhere"` | Wrapping is done at any point on a line, even if it occurs in the middle of a word.

The default wrap mode is `"nowrap"`.

     ctx.strokeRect(50, 5, 100, 60);
     ctx.strokeRect(50, 70, 100, 60);
     ctx.strokeRect(50, 135, 100, 60);
     let s = "This is a long string.";
     ctx.textWrapMode = "nowrap";
     ctx.fillText(s, 50, 5, 100, 60);
     ctx.textWrapMode = "wrap";
     ctx.fillText(s, 50, 70, 100, 60);
     ctx.textWrapMode = "wrapanywhere";
     ctx.fillText(s, 50, 135, 100, 60);

### windingEnforce : bool

Holds the current winding enforcing enabling status. Setting this to `false` disables enforcing of path winding to match what has been set into setPathWinding(). Disabling allows e.g. creating holes into paths by adding the points in clock wise order. Disabling can also increase the performance. The default value is `true`.

     ctx.windingEnforce = false;
     ctx.beginPath();
     // Outer shape, counterclockwise
     ctx.moveTo(20, 20);
     ctx.lineTo(100, 180);
     ctx.lineTo(180, 20);
     ctx.closePath();
     // Inner shape, clockwise
     ctx.moveTo(100, 40);
     ctx.lineTo(125, 90);
     ctx.lineTo(75, 90);
     ctx.closePath();
     ctx.fill();
     ctx.stroke();

## Method Documentation

### void addPath(path2d path, transform2d transform)

Adds path into the current path, optionally using transform to alter the path points. When transform is not provided (or it is identity matrix), this operation is very fast as it reuses the path data.

     // myPath is path2d property
     if (myPath.isEmpty())
         myPath.circle(60, 60, 40);
     ctx.beginPath();
     ctx.addPath(myPath);
     let t = ctx.createTransform2D();
     t.translate(80, 80);
     ctx.addPath(myPath, t);
     ctx.fill();
     ctx.stroke();

### void addPath(path2d path, int start, int count, transform2d transform)

Adds path into the current path, starting from the command at start and including count amount of commands. Optionally using transform to alter the path points. The range of start and count is checked, so that commands are not accessed more than the path has commands. In case the path shouldn't continue from the current path position, call first moveTo().

     // myPath is QCanvasPath
     if (myPath.isEmpty()) {
         myPath.moveTo(20, 60);
         for (let i = 1; i < 160; i++) {
             myPath.lineTo(20 + i,
                 60 + 20 * Math.sin(0.1 * i));
         }
     }
     ctx.stroke(myPath);
     ctx.beginPath();
     let t = ctx.createTransform2D();
     t.translate(0, 80);
     ctx.addPath(myPath, 20, 100, t);
     ctx.stroke();

### void arc(real x, real y, real radius, real startAngle, real endAngle, bool anticlockwise)

Creates a new circle arc shaped sub-path. The arc center is at x, y, with radius, and the arc is drawn from angle startAngle to endAngle. The default curve direction is clockwise. To change direction to the opposite, set anticlockwise to true. Angles are specified in radians.

     ctx.beginPath();
     ctx.moveTo(100, 100);
     ctx.arc(100, 100, 80, 0, 1.5 * Math.PI);
     ctx.closePath();
     ctx.fill();
     ctx.stroke();

Note: While HTML canvas 2D context uses arc() for painting circles, with Canvas2D it is recommended to use circle() or ellipse() for those.

See also arcTo and W3C's 2D Context Standard for arc().

### void arcTo(real x1, real y1, real x2, real y2, real radius)

Adds an arc segment at the corner defined by the last path point, and two specified points (x1, y1 and x2, y2) with radius. The arc is automatically connected to the path's latest point with a straight line if necessary.

     ctx.beginPath();
     ctx.moveTo(20, 20);
     ctx.arcTo(240, 20, 20, 220, 50);
     ctx.arcTo(20, 220, 20, 20, 30);
     ctx.stroke();

See also arc and W3C's 2D Context Standard for arcTo().

### void beginHoleSubPath()

Start a hole subpath. This is equivalent to `setPathWinding("clockwise")`

     ctx.beginPath();
     ctx.circle(100, 100, 80);
     ctx.beginHoleSubPath();
     ctx.rect(60, 60, 80, 80);
     ctx.beginSolidSubPath();
     ctx.circle(100, 100, 20);
     ctx.fill();
     ctx.stroke();

See also beginSolidSubPath().

### void beginPath()

Begins drawing a new path while clearing the current path.

### void beginSolidSubPath()

Start a solid subpath. This is equivalent to `setPathWinding("counterclockwise")`

See also beginHoleSubPath().

### void bezierCurveTo(real cp1x, real cp1y, real cp2x, real cp2y, real x, real y)

Adds a cubic bezier segment from last point in the path via two control points (cp1x, cp1y and cp2x, cp2y) to the specified point (x, y).

     ctx.beginPath();
     ctx.moveTo(20, 20);
     ctx.bezierCurveTo(150, 50, 50, 250, 180, 120);
     ctx.stroke();

See also W3C 2d context standard for bezierCurveTo.

### void circle(real centerX, real centerY, real radius)

Creates a new circle shaped sub-path centered at ( centerX, centerY) with radius.

     ctx.beginPath();
     ctx.circle(100, 100, 80);
     ctx.fill();
     ctx.stroke();

Note: Compared to arc(), this method does not add a straight line from the last point in the subpath to the start point of the circle.

### void cleanupResources()

Schedules dropping unused textures from the cache.

Additionally, other caches and pools may get shrunk upon calling this function, in order to minimize memory usage. This may potentially lead to more expensive drawing calls afterwards.

### void clearRect(real x, real y, real width, real height)

Erases the pixels in a rectangular area by filling the rectangle specified by x, y, width, height with transparent black. As clearing does not need blending, it can be faster than fillRect().

     ctx.beginPath();
     ctx.circle(100, 100, 80);
     ctx.fill();
     ctx.stroke();
     ctx.clearRect(60, 0, 80, 120);

### void closePath()

Closes the current subpath by drawing a line to the beginning of the subpath, automatically starting a new path. The current point of the new path is the previous subpath's first point.

See also W3C 2d context standard for closePath.

### boxgradient2d createBoxGradient(real x, real y, real width, real height, real feather, real radius)

Returns a boxgradient2d object that represents a box gradient that covers the rectangle area (x, y, width, height) with feather (smoothing) feather and corner radius radius.

     const bg = ctx.createBoxGradient(20, 20, 160, 160, 20, 50);
     bg.addColorStop(0.0, "#1a2a6c");
     bg.addColorStop(0.2, "#fdbb2d");
     bg.addColorStop(1.0, "transparent");
     ctx.fillStyle = bg;
     ctx.fillRect(20, 20, 160, 160);

See also boxgradient2d::addColorStop(), fillStyle, and strokeStyle.

### boxshadow2d createBoxShadow(real x, real y, real width, real height, real blur, string color, real radius)

Returns a boxshadow2d object with color color that represents a box shadow that covers the rectangle area (x, y, width, height) with blur blur and corner radius radius.

     let offsetX = -2;
     let offsetY = 4;
     let shadow = ctx.createBoxShadow(40 + offsetX,
                                      40 + offsetY,
                                      120, 120,
                                      30, "black", 0);
     ctx.drawBoxShadow(shadow);
     ctx.beginPath();
     ctx.roundRect(40, 40, 120, 120, 30);
     ctx.fillStyle = "#2CDE85";
     ctx.fill();

See also drawBoxShadow().

### boxshadow2d createBoxShadow(real x, real y, real width, real height, real blur, string color, real radiusTopLeft, real radiusTopRight, real radiusBottomRight, real radiusBottomLeft)

Returns a boxshadow2d object with color color that represents a box shadow that covers the rectangle area (x, y, width, height) with blur blur and corner radius (radiusTopLeft, radiusTopRight, radiusBottomRight, radiusBottomLeft).

See also drawBoxShadow().

### conicalgradient2d createConicalGradient(real x, real y, real angle)

Returns a conicalgradient2d object that represents a conical gradient that interpolates colors counter-clockwise around a center point (x, y) with a start angle angle in units of radians.

     const cg = ctx.createConicalGradient(100, 100, 1.75 * Math.PI);
     cg.addColorStop(0.0, "#fdbb2d");
     cg.addColorStop(0.5, "#1a2a6c");
     cg.addColorStop(1.0, "#fdbb2d");
     ctx.fillStyle = cg;
     ctx.beginPath();
     ctx.ellipseRect(20, 20, 160, 160);
     ctx.fill();

See also conicalgradient2d::addColorStop(), createLinearGradient(), createRadialGradient(), createPattern(), fillStyle, and strokeStyle.

### gridpattern2d createGridPattern(real x, real y, real width, real height, string lineColor, string backgroundColor, real lineWidth, real feather, real angle)

Returns a gridpattern2d object that covers the rectangle area (x, y, width, height). The grid uses lineColor for lines and backgroundColor for the background. The line width is lineWidth, line feather is feather and the rotation angle is angle in radians.

     const grid = ctx.createGridPattern(0, 0, 10, 10,
                         "#404040", "#202020");
     ctx.fillStyle = grid;
     ctx.fillRect(0, 0, 200, 200);

### lineargradient2d createLinearGradient(real x0, real y0, real x1, real y1)

Returns a lineargradient2d object that represents a linear gradient that transitions the color along a line between the start point (x0, y0) and the end point (x1, y1).

Gradients must have two or more color stops, representing color shifts positioned from 0 to 1 between the gradient's starting and end points.

     const lg = ctx.createLinearGradient(0, 0, 200, 200);
     lg.addColorStop(0.0, "#1a2a6c");
     lg.addColorStop(0.5, "#b21f1f");
     lg.addColorStop(1.0, "#fdbb2d");
     ctx.fillStyle = lg;
     ctx.fillRect(0, 0, 200, 200);

See also lineargradient2d::addColorStop(), createRadialGradient(), createConicalGradient(), createPattern(), fillStyle, and strokeStyle.

### path2d createPath2D()

Returns a new path2d object. Calling this is equal to HTML canvas "new Path2D()" command.

See also fill() and stroke().

### path2d createPath2D(path2d path)

Returns a new path2d object, with the copy of path. Calling this is equal to HTML canvas "new Path2D(path)" command.

See also fill() and stroke().

### path2d createPath2D(string svgPath)

Returns a new path2d object, with the content of svgPath. Calling this is equal to HTML canvas "new Path2D(d)" command.

See also fill() and stroke().

### imagepattern2d createPattern(Image image, string repetition)

Returns an imagepattern2d object that uses the given image and repeats in the direction(s) given by the repetition argument.

The image parameter must be a valid Image item or a loaded image url. If there is no image data, this function throws an INVALID_STATE_ERR exception.

The allowed values for repetition are:

Constant | Description
--- | ---
`"repeat"` | both directions
`"repeat-x` | horizontal only
`"repeat-y"` | vertical only
`"no-repeat"` | neither

If the repetition argument is empty or null, the value "repeat" is used.

     let ip1 = ctx.createPattern("pattern2.png", "repeat");
     let ip2 = ctx.createPattern("pattern3.png", "repeat");
     ip1.setImageSize(64, 64);
     ip2.setImageSize(32, 32);
     ctx.beginPath();
     ctx.roundRect(20, 20, 160, 160, 40);
     ctx.fillStyle = ip1;
     ctx.strokeStyle = ip2;
     ctx.fill();
     ctx.lineWidth = 20;
     ctx.stroke();

See also strokeStyle and fillStyle.

### radialgradient2d createRadialGradient(real x0, real y0, real r0, real x1, real y1, real r1)

Returns a radialgradient2d object that represents a radial gradient that paints along the cone given by the start circle with origin (x0, y0) and radius r0, and the end circle with origin (x1, y1) and radius r1.

With only 4 parameters, the parameters are used as (x, y, r0, r1), where the center position is the same for both inner and outer radius.

     const rg = ctx.createRadialGradient(100, 100, 0, 100);
     rg.addColorStop(0.0, "#fdbb2d");
     rg.addColorStop(0.6, "#b21f1f");
     rg.addColorStop(1.0, "#1a2a6c");
     ctx.fillStyle = rg;
     ctx.fillRect(0, 0, 200, 200);

     const rg = ctx.createRadialGradient(50, 50, 0,
                                         100, 100, 90);
     rg.addColorStop(0.0, "black");
     rg.addColorStop(1.0, "white");
     ctx.fillStyle = rg;
     ctx.fillRect(0, 0, 200, 200);

See also radialgradient2d::addColorStop(), createLinearGradient(), createConicalGradient(), createPattern(), fillStyle, and strokeStyle.

### transform2d createTransform2D()

Returns a new transform2d object, initialized to identity matrix.

See also getTransform().

### void drawBoxShadow(boxshadow2d shadow)

Draws a given box shadow. The shadow will be painted with position, size, color, blur etc. defined by shadow. Calling beginPath() before this method is not required.

     let offsetX = -2;
     let offsetY = 4;
     let shadow = ctx.createBoxShadow(40 + offsetX,
                                      40 + offsetY,
                                      120, 120,
                                      30, "black", 0);
     ctx.drawBoxShadow(shadow);
     ctx.beginPath();
     ctx.roundRect(40, 40, 120, 120, 30);
     ctx.fillStyle = "#2CDE85";
     ctx.fill();

See also createBoxShadow().

### void drawImage(variant image, real dx, real dy)

Draws the given image on the canvas at position (dx, dy). Note: The image type can be an Image item or an image url. When given as Image item, if the image isn't fully loaded, this method draws nothing. When given as url string, the image should be loaded by calling Canvas item's Canvas2D::loadImage() method first. This drawing is subject to the current context clip path.

     ctx.drawImage("qt_logo.png", 36, 36);

See also Image, Canvas2D::loadImage, Canvas2D::isImageLoaded, Canvas2D::imageLoaded, and W3C 2d context standard for drawImage.

### void drawImage(variant image, real dx, real dy, real dw, real dh)

This is an overloaded function. Draws the given item as image onto the canvas at point (dx, dy) and with width dw, height dh.

     ctx.drawImage("qt_logo.png", 50, 0, 100, 200);

See also Image, Canvas2D::loadImage(), Canvas2D::isImageLoaded, Canvas2D::imageLoaded, and W3C 2d context standard for drawImage.

### void drawImage(variant image, real sx, real sy, real sw, real sh, real dx, real dy, real dw, real dh)

This is an overloaded function. Draws the given item as image from source point (sx, sy) and source width sw, source height sh onto the canvas at point (dx, dy) and with width dw, height dh.

     ctx.drawImage("qt_logo.png",
                    20, 30, 54, 76,
                    0, 0, 200, 200);

See also Image, Canvas2D::loadImage(), Canvas2D::isImageLoaded, Canvas2D::imageLoaded, and W3C 2d context standard for drawImage.

### void ellipse(real centerX, real centerY, real radiusX, real radiusY)

Creates a new ellipse shaped sub-path centered at ( centerX, centerY) with radiusX and radiusY.

     ctx.beginPath();
     ctx.ellipse(100, 100, 80, 60);
     ctx.fill();
     ctx.stroke();

### void ellipseRect(real x, real y, real width, real height)

Creates a new ellipse shaped sub-path into rect x, y, width, height. This ellipse will cover the rect area.

     ctx.fillRect(40, 20, 120, 160);
     ctx.beginPath();
     ctx.ellipseRect(40, 20, 120, 160);
     ctx.stroke();

Note: This method matches to QtQuick::Context2D::ellipse()

### void fill()

Fills the current path with the current fill style, and the current fill rule.

     ctx.beginPath();
     ctx.rect(20, 20, 40, 160);
     ctx.rect(140, 20, 40, 160);
     ctx.circle(100, 100, 60);
     ctx.fill();

See also fillStyle, fillRule, and W3C 2d context standard for fill.

### void fill(string fillRule)

Fills the current path with the current fill style, and fill rule fillRule.

See also fillStyle and fillRule.

### void fill(path2d path, int pathGroup)

Fills the path with the current fill style and fill rule, and belonging into optional pathGroup. Painting through QCanvasPath is optimal when the path contains more commands and is mostly static.

When pathGroup is `-1`, the path will not be cached on the GPU side. This is the default. To request caching of path data, pass a value equal or greater than `0`. More information about using path cache groups can be found in the QCanvasPath documentation.

Calling beginPath() before this method is not required.

     // myPath is path2d
     if (myPath.isEmpty()) {
         for (let i = 0; i < 16; i++) {
             let w = 100 + 60 * Math.sin(i);
             myPath.rect(100 - w * 0.5,
                         22 + i * 10,
                         w, 6);
         }
     }
     ctx.fill(myPath);

See also fillStyle and path2d.

### void fill(path2d path, string fillRule, int pathGroup)

Fills the path with the current fill style and using fillRule. The cache group parameter pathGroup is optional.

See also fillStyle, fillRule, and path2d.

### void fillRect(real x, real y, real width, real height)

Draws a filled rectangle into the specified position ( x, y) with size width, height.

Note: This is provided for convenience. When filling more than just a single rect, prefer using rect().

     ctx.fillRect(20, 20, 160, 160);
     // The above code does same as:
     // ctx.beginPath();
     // ctx.rect(20, 20, 160, 160);
     // ctx.fill();

See also fillStyle.

### void fillText(text, x, y, maxWidth)

Draws text string at the specified location ( x, y), with current textAlign and textBaseline. To make the text wrap into multiple lines, set the text wrap mode using textWrapMode to something else than the default `"nowrap"`. Optional maxWidth parameter defaults to `0`. Meaning that when e.g. `"wordwrap"` has been set, text is wrapped on every word. Set the maxWidth parameter to preferred row width in pixels.

     ctx.textAlign = "center";
     ctx.textBaseline = "middle";
     const text = "Qt Canvas Painter";
     ctx.fillText(text, 100, 30);
     ctx.textWrapMode = "wordwrap";
     ctx.fillText(text, 100, 90);
     ctx.fillText(text, 100, 160, 120);

See also font, textAlign, textBaseline, and textWrapMode.

### void fillText(text, x, y, width, height)

Draws text string inside rect (x, y, width, height), with current textAlign and textBaseline. Width of the rect parameter is used as maxWidth.

It is often useful to set the text baseline to TextBaseline::Top or TextBaseline::Middle when painting text with this method.

     ctx.textAlign = "center";
     ctx.textBaseline = "middle";
     const text = "Qt Canvas Painter";
     ctx.strokeRect(10, 20, 180, 50);
     ctx.fillText(text, 10, 20, 180, 50);
     ctx.textWrapMode = "wordwrap";
     ctx.strokeRect(60, 90, 80, 90);
     ctx.fillText(text, 60, 90, 80, 90);

See also font, textAlign, textBaseline, and textWrapMode.

### transform2d getTransform()

Returns the current transformation matrix.

See also setTransform().

### void lineTo(real x, real y)

Draws a line from the current position to the point at (x, y).

     ctx.beginPath();
     ctx.moveTo(20, 20);
     ctx.lineTo(140, 180);
     ctx.lineTo(180, 120);
     ctx.stroke();

### object measureText(text)

Returns an object with a `width` property, whose value is equivalent to calling QFontMetricsF::horizontalAdvance() with the given text in the current font.

### void moveTo(real x, real y)

Creates a new subpath with a point at (x, y).

### void quadraticCurveTo(real cpx, real cpy, real x, real y)

Adds a quadratic bezier segment from last point in the path via a control point (cpx, cpy) to the specified point (x, y).

     ctx.beginPath();
     ctx.moveTo(20, 20);
     ctx.quadraticCurveTo(150, 50, 180, 180);
     ctx.quadraticCurveTo(20, 220, 20, 20);
     ctx.fill();
     ctx.stroke();

See also W3C 2d context standard for quadraticCurveTo.

### void rect(real x, real y, real width, real height)

Creates a new rectangle shaped sub-path in position x, y with size width, height.

     ctx.beginPath();
     ctx.rect(20, 20, 160, 160);
     ctx.fill();
     ctx.stroke();

### void removePathGroup(int pathGroup)

Removes pathGroup from the painter cache. Calling fill() or stroke() for pathGroup after this, will regenerate the path into the group cache.

Note: This does not need to be normally called as paths are removed in the painter destructor. Only use this to reduce memory usage when pathGroup is not needed anymore or e.g. when the path has a lot less commands that it has had in the past and buffer size should be reduced.

See also fill() and stroke().

### void reset()

Resets the current painter state to default values.

Note: This method differs from the HTML canvas 2D context reset() method so that it doesn't visually clear the canvas buffers.

     // Adjust the paint state
     ctx.strokeStyle = "#00414A";
     ctx.fillStyle = "#2CDE85";
     ctx.lineWidth = 10;
     ctx.translate(100, 65);
     ctx.rotate(-0.4);
     ctx.translate(-100, -65);
     ctx.beginPath();
     ctx.roundRect(20, 40, 160, 50, 20);
     ctx.fill();
     ctx.stroke();
     // Reset to default paint state
     ctx.reset();
     ctx.fillRect(20, 140, 60, 40);
     ctx.strokeRect(120, 140, 60, 40);

See also save() and restore().

### void resetClipping()

Resets and disables clipping.

See also setClipRect().

### void resetTransform()

Reset the transformation matrix to the default value (equivalent to calling setTransform(`1`, `0`, `0`, `1`, `0`, `0`)).

See also transform(), setTransform(), and reset().

### void restore()

Pops and restores the current render state. So previously saved state will be restored. If save() has not been called and the state stack is empty, calling this does nothing.

See also save().

### void rotate(real angle)

Rotates the current coordinate system clockwise by angle.

The angle is specified in radians.

     ctx.translate(100, 100);
     ctx.rotate(Math.PI / 4);
     ctx.translate(-100, -100);
     ctx.beginPath();
     ctx.roundRect(20, 70, 160, 60, 10);
     ctx.fill();
     ctx.stroke();
     ctx.fillStyle = "black";
     ctx.fillText("Cute!", 100, 100);

### void roundRect(real x, real y, real width, real height, real radius)

Creates a new rounded rectangle shaped sub-path in position x, y with size width, height. Corners rounding will be radius.

     ctx.beginPath();
     ctx.roundRect(20, 20, 160, 160, 30);
     ctx.fill();
     ctx.stroke();

### void roundRect(real x, real y, real width, real height, real radiusTopLeft, real radiusTopRight, real radiusBottomRight, real radiusBottomLeft)

Creates a new rounded rectangle shaped sub-path in position x, y with size width, height. Corners rounding can be varying per-corner, with radiusTopLeft, radiusTopRight, radiusBottomRight, radiusBottomLeft.

     ctx.beginPath();
     ctx.roundRect(20, 20, 160, 160,
                   0, 40, 20, 80);
     ctx.fill();
     ctx.stroke();

### void save()

Pushes and saves the current render state into a state stack. A matching restore() must be used to restore the state.

Note: The current path is NOT part of the drawing state. The path can be reset by invoking the beginPath() method.

     ctx.strokeRect(20, 20, 160, 40);
     // Save and adjust the paint state
     ctx.save();
     ctx.strokeStyle = "black";
     ctx.lineWidth = 3;
     ctx.rotate(0.1);
     ctx.strokeRect(20, 80, 180, 20);
     // Restore the saved paint state
     ctx.restore();
     ctx.strokeRect(20, 140, 160, 40);

See also restore().

### void scale(real scale)

Scales the current coordinate system by scale. Both x and y coordinates are scaled evenly.

     for (let i = 0; i < 20; i++) {
         ctx.beginPath();
         ctx.roundRect(20, 20, 160, 160, 10);
         ctx.stroke();
         ctx.translate(100, 100);
         ctx.scale(0.8);
         ctx.translate(-100, -100);
     }

### void scale(real sx, real sy)

Increases or decreases the size of each unit in the canvas grid by multiplying the scale factors to the current tranform matrix. sx is the scale factor in the horizontal direction and sy is the scale factor in the vertical direction.

The following code doubles the horizontal size of an object drawn on the canvas and halves its vertical size:

     ctx.scale(2.0, 0.5);

### void setClipRect(real x, real y, real width, real height)

Sets the current scissor rectangle to (x, y, width, height). The scissor rectangle is transformed by the current transform.

Note: Clipping has some performance cost and it should only be used when needed.

     ctx.setClipRect(20, 20, 160, 160);
     ctx.beginPath();
     ctx.circle(40, 40, 110);
     ctx.fill();
     ctx.fillStyle = "black";
     ctx.fillText("Clip me...", 45, 100);
     ctx.strokeRect(20, 20, 160, 160);

See also resetClipping().

### void setPathWinding(string winding)

Sets the current sub-path winding to either "counterclockwise" (default) or "clockwise". "counterclockwise" draws solid subpaths while "clockwise" draws holes.

     ctx.beginPath();
     ctx.roundRect(20, 20, 160, 160, 40);
     ctx.setPathWinding("clockwise");
     ctx.circle(140, 60, 20);
     ctx.rect(60, 120, 80, 30);
     ctx.fill();
     ctx.stroke();

See also beginHoleSubPath() and beginSolidSubPath().

### void setTransform(transform2d transform)

Resets the current transform and uses transform instead.

     ctx.beginPath();
     ctx.roundRect(80, 20, 40, 40, 10);
     ctx.fill();
     ctx.stroke();
     let t = ctx.createTransform2D();
     t.translate(100, 20);
     t.rotate(45);
     t.scale(2.0, 2.0);
     ctx.setTransform(t);
     ctx.beginPath();
     ctx.roundRect(20, 20, 40, 40, 10);
     ctx.fill();
     ctx.stroke();

See also transform() and getTransform().

### void setTransform(real a, real b, real c, real d, real e, real f)

Changes the transformation matrix to the matrix given by the arguments as described below.

Modifying the transformation matrix directly enables you to perform scaling, rotating, and translating transformations in a single step.

Each point on the canvas is multiplied by the matrix before anything is drawn. The HTML Canvas 2D Context specification defines the transformation matrix where:

- a is the scale factor in the horizontal (x) direction
- c is the skew factor in the x direction
- e is the translation in the x direction
- b is the skew factor in the y (vertical) direction
- d is the scale factor in the y direction
- f is the translation in the y direction
- the last row remains constant

The scale factors and skew factors are multiples; e and f are coordinate space units, just like the units in the translate(x,y) method.

See also transform().

### void skew(real angleX, real angleY)

Skews (shears) the current coordinate system along X axis by angleX and along Y axis by angleY. The default value of angleY is `0` when only a single parameter is provided. Angles are specified in radians.

     ctx.translate(100, 100);
     ctx.skew(-0.6);
     ctx.translate(-100, -100);
     ctx.beginPath();
     ctx.roundRect(40, 70, 120, 60, 10);
     ctx.fill();
     ctx.stroke();
     ctx.fillStyle = "black";
     ctx.fillText("Cute!", 100, 100);

### void stroke()

Strokes the current path with the current stroke style.

     ctx.beginPath();
     ctx.rect(20, 20, 40, 160);
     ctx.rect(140, 20, 40, 160);
     ctx.circle(100, 100, 60);
     ctx.stroke();

See also strokeStyle and W3C 2d context standard for stroke.

### void stroke(path2d path, int pathGroup)

Strokes the path with the current stroke style and belonging into pathGroup. Painting through QCanvasPath is optimal when the path contains more commands and is mostly static.

When pathGroup is `-1`, the path's rendering-related data will not be cached. This is the default. To request caching of path data, pass a value equal or greater to `0`. More information about using path cache groups can be found in the QCanvasPath documentation.

Calling beginPath() before this method is not required.

     // myPath is path2d
     if (myPath.isEmpty()) {
         for (let i = 0; i < 16; i++) {
             let h = 100 + 60 * Math.sin(i);
             myPath.rect(22 + i * 10,
                         180 - h,
                         6, h);
         }
     }
     ctx.stroke(myPath);

See also strokeStyle, path2d, and W3C 2d context standard for stroke.

### void strokeRect(real x, real y, real width, real height)

Draws a stroked rectangle into the specified position ( x, y) with size width, height.

Note: This is provided for convenience. When stroking more than just a single rect, prefer using rect().

     ctx.strokeRect(20, 20, 160, 160);
     // The above code does same as:
     // ctx.beginPath();
     // ctx.rect(20, 20, 160, 160);
     // ctx.stroke();

See also strokeStyle, lineWidth, lineJoin, and miterLimit.

### void transform(transform2d transform)

Multiplies the current coordinate system by specified transform.

     let t = ctx.createTransform2D();
     t.translate(100, 100);
     t.rotate(36);
     t.translate(-100, -100);
     for (let i = 0; i < 10; i++) {
         ctx.transform(t);
         ctx.beginPath();
         ctx.roundRect(80, 15, 40, 20, 10);
         ctx.fill();
         ctx.stroke();
     }

See also setTransform().

### void transform(real a, real b, real c, real d, real e, real f)

Multiplies the current coordinate system by the specified transform (a, b, c, d, e, f).

This method is similar to setTransform(), but instead of replacing the old transform matrix, this method applies the given transform matrix to the current matrix by multiplying to it.

See also setTransform().

### void translate(real x, real y)

Translates the current coordinate system by x and y.

     function paintRect() {
         ctx.beginPath();
         ctx.roundRect(20, 20, 160, 60, 10);
         ctx.fill();
         ctx.stroke();
     };
     paintRect();
     ctx.translate(0, 100);
     paintRect();