Socket
Socket
Sign inDemoInstall

skia-canvas

Package Overview
Dependencies
64
Maintainers
1
Versions
25
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.9.23 to 0.9.24

src/texture.rs

44

lib/index.js

@@ -21,3 +21,3 @@ "use strict"

let obj = internal(Object.create(type.prototype), ø, struct)
return internal(obj, 'native', neon[type.name])
return struct && internal(obj, 'native', neon[type.name])
},

@@ -28,3 +28,3 @@ neon = Object.entries(require('./v6')).reduce( (api, [name, fn]) => {

slot = getset ? (cls[attr] || (cls[attr] = {})) : cls
slot[getset ?? attr] = fn
slot[getset || attr] = fn
return api

@@ -231,2 +231,18 @@ }, {})

class CanvasTexture extends RustClass{
constructor(spacing, {path, line, color, angle, offset=0}={}){
super(CanvasTexture)
let [x, y] = typeof offset=='number' ? [offset, offset] : offset.slice(0, 2)
let [h, v] = typeof spacing=='number' ? [spacing, spacing] : spacing.slice(0, 2)
path = core(path)
line = line != null ? line : (path ? 0 : 1)
angle = angle != null ? angle : (path ? 0 : -Math.PI / 4)
this.alloc(path, color, line, angle, h, v, x, y)
}
[REPR](depth, options) {
return `CanvasTexture (${this.ƒ("repr")})`
}
}
class CanvasRenderingContext2D extends RustClass{

@@ -304,2 +320,6 @@ constructor(canvas){

createTexture(spacing, options){
return new CanvasTexture(spacing, options)
}
// -- fill & stroke ---------------------------------------------------------

@@ -311,3 +331,3 @@ fillRect(x, y, width, height){ this.ƒ('fillRect', ...arguments) }

set fillStyle(style){
let isShader = style instanceof CanvasPattern || style instanceof CanvasGradient,
let isShader = style instanceof CanvasPattern || style instanceof CanvasGradient || style instanceof CanvasTexture,
[ref, val] = isShader ? [style, core(style)] : [null, style]

@@ -324,3 +344,3 @@ this.ref('fill', ref)

set strokeStyle(style){
let isShader = style instanceof CanvasPattern || style instanceof CanvasGradient,
let isShader = style instanceof CanvasPattern || style instanceof CanvasGradient || style instanceof CanvasTexture,
[ref, val] = isShader ? [style, core(style)] : [null, style]

@@ -341,2 +361,6 @@ this.ref('stroke', ref)

set lineCap(style){ this.prop("lineCap", style) }
get lineDashFit(){ return this.prop("lineDashFit") }
set lineDashFit(style){ this.prop("lineDashFit", style) }
get lineDashMarker(){ return wrap(Path2D, this.prop("lineDashMarker")) }
set lineDashMarker(path){ this.prop("lineDashMarker", path instanceof Path2D ? core(path) : path) }
get lineDashOffset(){ return this.prop("lineDashOffset") }

@@ -592,2 +616,4 @@ set lineDashOffset(offset){ this.prop("lineDashOffset", offset) }

get edges(){ return this.ƒ("edges") }
get d(){ return this.prop("d") }
set d(svg){ return this.prop("d", svg) }
contains(x, y){ return this.ƒ("contains", x, y)}

@@ -634,3 +660,4 @@

jitter(len, amt, seed){ return Path2D.effect("jitter", this, ...arguments) }
simplify(){ return Path2D.effect("simplify", this) }
simplify(rule){ return Path2D.effect("simplify", this, rule) }
unwind(){ return Path2D.effect("unwind", this) }
round(radius){ return Path2D.effect("round", this, radius) }

@@ -653,2 +680,7 @@ offset(dx, dy){ return Path2D.effect("offset", this, dx, dy) }

}
[REPR](depth, options) {
let {d, bounds, edges} = this
return `Path2D ${inspect({d, bounds, edges}, options)}`
}
}

@@ -685,5 +717,5 @@

module.exports = {
Canvas, CanvasGradient, CanvasPattern, CanvasRenderingContext2D,
Canvas, CanvasGradient, CanvasPattern, CanvasRenderingContext2D, CanvasTexture,
TextMetrics, Image, ImageData, Path2D, loadImage, ...geometry,
FontLibrary:new FontLibrary()
}

4

package.json
{
"name": "skia-canvas",
"version": "0.9.23",
"version": "0.9.24",
"description": "A canvas environment for Node",

@@ -35,3 +35,3 @@ "author": "Christian Swinehart <drafting@samizdat.co>",

"devDependencies": {
"aws-sdk": "^2.943.0",
"aws-sdk": "^2.967.0",
"cargo-cp-artifact": "^0.1",

@@ -38,0 +38,0 @@ "express": "^4.17.1",

@@ -15,2 +15,3 @@ # Skia Canvas

- can [simplify][p2d_simplify], [blunt][p2d_round], [combine][bool-ops], [excerpt][p2d_trim], and [atomize][p2d_points] bézier paths using [efficient](https://www.youtube.com/watch?v=OmfliNQsk88) boolean operations or point-by-point [interpolation][p2d_interpolate]
- can fill shapes with vector-based [Textures][createTexture()] in addition to bitmap-based [Patterns][createPattern()] and supports line-drawing with custom [markers][lineDashMarker]
- fully supports the [CSS filter effects][filter] image processing operators

@@ -226,3 +227,3 @@ - offers rich typographic control including:

#### `saveAs(filename, {page, format, density=1, quality=0.92, outline=false})`
#### `saveAs(filename, {page, format, matte, density=1, quality=0.92, outline=false})`

@@ -238,2 +239,5 @@ The `saveAs` method takes a file path and writes the canvas’s current contents to disk. If the filename ends with an extension that makes its format clear, the second argument is optional. If the filename is ambiguous, you can pass an options object with a `format` string using names like `"png"` and `"jpeg"` or a full mime type like `"application/pdf"`.

##### matte
The optional `matte` argument accepts a color-string specifying the background that should be drawn *behind* the canvas in the exported image. Any transparent portions of the image will be filled with the matte color.
##### density

@@ -267,28 +271,29 @@ By default, the images will be at a 1:1 ratio with the canvas's `width` and `height` dimensions (i.e., a 72 × 72 canvas will yield a 72 pixel × 72 pixel bitmap). But with screens increasingly operating at higher densities, you’ll frequently want to generate images where an on-canvas 'point' may occupy multiple pixels. The optional `density` argument allows you to specify this magnification factor using an integer ≥1. As a shorthand, you can also select a density by choosing a filename using the `@nx` naming convention:

| Canvas State | Drawing Primitives | Stroke & Fill Style | Compositing Effects |
|------------------------------------------|----------------------------------------------|--------------------------------------|----------------------------------------------------------|
| [**canvas**][canvas_attr] ⧸[⚡](#canvas) | [drawImage()][drawImage()] | [**fillStyle**][fillStyle] | [**filter**][filter] |
| [beginPath()][beginPath()] | [clearRect()][clearRect()] | [**lineCap**][lineCap] | [**globalAlpha**][globalAlpha] |
| [isPointInPath()][isPointInPath()] | [fillRect()][fillRect()] | [**lineDashOffset**][lineDashOffset] | [**globalCompositeOperation**][globalCompositeOperation] |
| [isPointInStroke()][isPointInStroke()] | [strokeRect()][strokeRect()] | [**lineJoin**][lineJoin] | [**shadowBlur**][shadowBlur] |
| [save()][save()] | [fillText()][fillText()] ⧸[⚡][drawText] | [**lineWidth**][lineWidth] | [**shadowColor**][shadowColor] |
| [restore()][restore()] | [strokeText()][strokeText()] ⧸[⚡][drawText] | [**miterLimit**][miterLimit] | [**shadowOffsetX**][shadowOffsetX] |
| [clip()][clip()] | [fill()][fill()] | [**strokeStyle**][strokeStyle] | [**shadowOffsetY**][shadowOffsetY] |
| | [stroke()][stroke()] | [getLineDash()][getLineDash()] | |
| | | [setLineDash()][setLineDash()] | |
| Canvas State | Drawing | Pattern & Color | Line Style | Transform |
|------------------------------------------|----------------------------------------------|---------------------------------------------------|-----------------------------------------|------------------------------------------|
| [**canvas**][canvas_attr] ⧸[⚡](#canvas) | [clearRect()][clearRect()] | [**fillStyle**][fillStyle] | [**lineCap**][lineCap] | [**currentTransform**][currentTransform] |
| [beginPath()][beginPath()] | [fillRect()][fillRect()] | [**strokeStyle**][strokeStyle] | [**lineDashFit** ⚡][lineDashFit] | [getTransform()][getTransform()] |
| [isPointInPath()][isPointInPath()] | [strokeRect()][strokeRect()] | [createConicGradient()][createConicGradient()] | [**lineDashMarker** ⚡][lineDashMarker] | [setTransform()][setTransform()] |
| [isPointInStroke()][isPointInStroke()] | [fillText()][fillText()] ⧸[⚡][drawText] | [createLinearGradient()][createLinearGradient()] | [**lineDashOffset**][lineDashOffset] | [resetTransform()][resetTransform()] |
| [save()][save()] | [strokeText()][strokeText()] ⧸[⚡][drawText] | [createRadialGradient()][createRadialGradient()] | [**lineJoin**][lineJoin] | [transform()][transform()] |
| [restore()][restore()] | [fill()][fill()] | [createPattern()][createPattern()] | [**lineWidth**][lineWidth] | [translate()][translate()] |
| [clip()][clip()] | [stroke()][stroke()] | [createTexture() ⚡][createTexture()] | [**miterLimit**][miterLimit] | [rotate()][rotate()] |
| | | | [getLineDash()][getLineDash()] | [scale()][scale()] |
| | | | [setLineDash()][setLineDash()] | |
| Bezier Paths | Typography | Pattern & Image | Transform |
|------------------------------------------|-------------------------------------------------------------|----------------------------------------------------|------------------------------------------|
| [moveTo()][moveTo()] | [**direction**][direction] | [**imageSmoothingEnabled**][imageSmoothingEnabled] | [**currentTransform**][currentTransform] |
| [lineTo()][lineTo()] | [**font**][font] ⧸[⚡](#font) | [**imageSmoothingQuality**][imageSmoothingQuality] | [getTransform()][getTransform()] |
| [arcTo()][arcTo()] | [**fontVariant** ⚡](#fontvariant) | [createPattern()][createPattern()] | [setTransform()][setTransform()] |
| [bezierCurveTo()][bezierCurveTo()] | [**textAlign**][textAlign] | [createConicGradient()][createConicGradient()] | [resetTransform()][resetTransform()] |
| [conicCurveTo() ⚡][conicCurveTo] | [**textBaseline**][textBaseline] | [createLinearGradient()][createLinearGradient()] | [transform()][transform()] |
| [quadraticCurveTo()][quadraticCurveTo()] | [**textTracking** ⚡](#texttracking) | [createRadialGradient()][createRadialGradient()] | [translate()][translate()] |
| [closePath()][closePath()] | [**textWrap** ⚡](#textwrap) | [createImageData()][createImageData()] | [rotate()][rotate()] |
| [arc()][arc()] | [measureText()][measureText()] ⧸[⚡](#measuretextstr-width) | [getImageData()][getImageData()] | [scale()][scale()] |
| [ellipse()][ellipse()] | [outlineText() ⚡][outlineText()] | [putImageData()][putImageData()] | |
| [rect()][rect()] |
| Bezier Paths | Typography | Images | Compositing Effects |
|------------------------------------------|-------------------------------------------------------------|----------------------------------------------------|----------------------------------------------------------|
| [moveTo()][moveTo()] | [**direction**][direction] | [**imageSmoothingEnabled**][imageSmoothingEnabled] | [**filter**][filter] |
| [lineTo()][lineTo()] | [**font**][font] ⧸[⚡](#font) | [**imageSmoothingQuality**][imageSmoothingQuality] | [**globalAlpha**][globalAlpha] |
| [arcTo()][arcTo()] | [**fontVariant** ⚡](#fontvariant) | [createImageData()][createImageData()] | [**globalCompositeOperation**][globalCompositeOperation] |
| [bezierCurveTo()][bezierCurveTo()] | [**textAlign**][textAlign] | [getImageData()][getImageData()] | [**shadowBlur**][shadowBlur] |
| [conicCurveTo() ⚡][conicCurveTo] | [**textBaseline**][textBaseline] | [putImageData()][putImageData()] | [**shadowColor**][shadowColor] |
| [quadraticCurveTo()][quadraticCurveTo()] | [**textTracking** ⚡](#texttracking) | [drawImage()][drawImage()] | [**shadowOffsetX**][shadowOffsetX] |
| [closePath()][closePath()] | [**textWrap** ⚡](#textwrap) | | [**shadowOffsetY**][shadowOffsetY] |
| [arc()][arc()] | [measureText()][measureText()] ⧸[⚡](#measuretextstr-width) | | |
| [ellipse()][ellipse()] | [outlineText() ⚡][outlineText()] | | |
| [rect()][rect()] | | |
##### PROPERTIES

@@ -314,2 +319,59 @@

#### `.lineDashMarker`
If a Path2D object is assigned to the context’s `lineDashMarker` property, it will be used instead of the default dash pattern when [`setLineDash`][setLineDash()] has been set to a non-empty value. The marker will be drawn at evenly spaced intervals along the path with the distance controlled by the first number in the `setLineDash` array—any subsequent values are ignored.
The marker should be a Path2D object centered on (0, 0). Points to the right of the origin will run parallel to the path being stroked. If the marker path ends with a [`closePath()`][p2d_closePath], the marker will be filled using the current [`strokeStyle`][strokeStyle]. if the path is not closed, it will be stroked using the current [`lineWidth`][lineWidth]/[`join`][lineJoin]/[`cap`][lineCap], [`miterLimit`][miterLimit], and [`strokeStyle`][strokeStyle].
```js
// define marker paths
let caret = new Path2D()
caret.moveTo(-8,-8)
caret.lineTo( 0, 0)
caret.lineTo(-8, 8)
let dot = new Path2D()
dot.arc(0, 0, 4, 0, 2*Math.PI)
dot.closePath() // use fill rather than stroke
let cross = new Path2D()
cross.moveTo(-6,-6)
cross.lineTo( 6, 6)
cross.moveTo(-6, 6)
cross.lineTo( 6,-6)
// draw arcs using different markers
function drawArc(x, color){
ctx.strokeStyle = color
ctx.lineWidth = 4
ctx.beginPath()
ctx.arc(x + 120, 120, 100, -Math.PI, -Math.PI/2)
ctx.stroke()
}
ctx.setLineDash([20])
drawArc(0, "orange")
ctx.lineDashMarker = caret
drawArc(100, "deepskyblue")
ctx.lineDashMarker = dot
drawArc(200, "limegreen")
ctx.lineDashMarker = cross
drawArc(300, "red")
ctx.setLineDash([])
drawArc(400, "#aaa")
```
![custom dash markers](/test/assets/path/lineDashMarker@2x.png)
#### `.lineDashFit`
The `lineDashFit` attribute can be set to `"move"`, `"turn"`, or `"follow"` and controls how the marker is transformed with each repetition along the path. `"move"` and `"turn"` use simple translation and rotation, whereas `"follow"` will bend the marker to match the dashed path's contours.
##### METHODS

@@ -321,2 +383,30 @@

#### `createTexture(spacing, {path, line, color, angle, offset=0})`
The `createTexture()` method returns a `CanvasTexture` object that can be assigned to the context’s `strokeStyle` or `fillStyle` property. Similar to a `CanvasPattern`, a `CanvasTexture` defines a repeating pattern that will be drawn instead of a flat color, but textures define their content using *vectors* rather than bitmaps.
Textures can be based on a user-provided Path2D object or will draw a stripe pattern of parallel lines if a path isn’t provided.
##### `spacing`
The `spacing` argument is required and defines the rectangular area that each repeating ‘tile’ in the pattern will occupy. It can either be a single number (which will be used for both dimensions) or an array with two numbers (width and height). When creating a stripe pattern, the `spacing` argument defines the distance between neighboring lines, so providing more than one value is unnecessary.
**The optional second argument can be an object with one or more of the following attributes:**
##### `path`
If set to a Path2D object, the `path` will be drawn once per tile with its origin in the upper left corner of each tile. Note that the path will not be clipped even if it extends beyond the bounds of the current tile, allowing you to overlap the texture with neighboring tiles.
##### `line`
If set to a positive number, the path will be stroked rather than filled and the `line` value will set the width of the stroke.
##### `color`
By default the texture will be drawn in black (filled if `line` is undefined, stroked otherwise). The `color` argument can be set to a string defining the stroke/fill color to be used instead.
##### `angle`
The rectangle defined by the `spacing` argument will be aligned with the canvas’s horizontal and vertical axes by default. Specifying an `angle` value (in radians) allows you to rotate this tile grid clockwise relative to its default orientation.
##### `offset`
As with `CanvasPattern` objects, textures are positioned globally relative to the upper left corner of the canvas—not the corner of the object currently being filled or stroked. To fine-tune the texture’s alignment with individual objects, set the `offset` argument to an `[x, y]` array with two numbers that will shift the texture relative to its origin.
#### `fillText(str, x, y, [width])` & `strokeText(str, x, y, [width])`

@@ -368,3 +458,3 @@

The `Path2D` class allows you to create paths independent of a given [Canvas](#canvas) or [graphics context](#canvasrenderingcontext2d). These paths can be modified over time and drawn repeatedly (potentially on multiple canvases).
The `Path2D` class allows you to create paths independent of a given [Canvas](#canvas) or [graphics context](#canvasrenderingcontext2d). These paths can be modified over time and drawn repeatedly (potentially on multiple canvases). `Path2D` objects can also be used as [lineDashMarker][lineDashMarker]s or as the repeating pattern in a [CanvasTexture][createTexture()].

@@ -374,12 +464,13 @@

| -- | -- | -- | -- | -- |
| [moveTo()][p2d_moveTo] | [addPath()][p2d_addPath] | [complement()][bool-ops] | [interpolate()][p2d_interpolate] | [**bounds**](#bounds) |
| [lineTo()][p2d_lineTo] | [arc()][p2d_arc] | [difference()][bool-ops] | [jitter()][p2d_jitter] | [**edges**](#edges) |
| [bezierCurveTo()][p2d_bezierCurveTo] | [arcTo()][p2d_arcTo] | [intersect()][bool-ops] | [round()][p2d_round] | [contains()][p2d_contains] |
| [conicCurveTo() ⚡][conicCurveTo] | [ellipse()][p2d_ellipse] | [union()][bool-ops] | [simplify()][p2d_simplify] | [points()][p2d_points] |
| [quadraticCurveTo()][p2d_quadraticCurveTo] | [rect()][p2d_rect] | [xor()][bool-ops] | [trim()][p2d_trim] | [offset()][p2d_offset] |
| [closePath()][p2d_closePath] | | | | [transform()][p2d_transform] |
| [**d** ⚡](#d) | [addPath()][p2d_addPath] | [complement()][bool-ops] | [interpolate()][p2d_interpolate] | [**bounds**](#bounds) |
| [moveTo()][p2d_moveTo] | [arc()][p2d_arc] | [difference()][bool-ops] | [jitter()][p2d_jitter] | [**edges**](#edges) |
| [lineTo()][p2d_lineTo] | [arcTo()][p2d_arcTo] | [intersect()][bool-ops] | [round()][p2d_round] | [contains()][p2d_contains] |
| [bezierCurveTo()][p2d_bezierCurveTo] | [ellipse()][p2d_ellipse] | [union()][bool-ops] | [simplify()][p2d_simplify] | [points()][p2d_points] |
| [conicCurveTo() ⚡][conicCurveTo] | [rect()][p2d_rect] | [xor()][bool-ops] | [trim()][p2d_trim] | [offset()][p2d_offset] |
| [quadraticCurveTo()][p2d_quadraticCurveTo] | | | [unwind()][p2d_unwind] | [transform()][p2d_transform] |
| [closePath()][p2d_closePath] |
#### Creating `Path2D` objects
Its constructor can be called without any arguments to create a new, empty path object. It can also accept a string using [SVG syntax][SVG_path_commands] or a reference to an existing `Path2D` object (which it will return a clone of):
Its constructor can be called without any arguments to create a new, empty path object. It can also accept a string using [SVG syntax][SVG_path_commands] or a reference to an existing `Path2D` object (which it will return a clone of):
```js

@@ -399,3 +490,2 @@ // three identical (but independent) paths

##### PROPERTIES

@@ -412,2 +502,6 @@

#### `.d`
Contains a string describing the path’s edges using [SVG syntax][SVG_path_commands]. This property is both readable and writeable (and can be appended to using the `+=` operator).
#### `.edges`

@@ -554,5 +648,5 @@

#### `simplify()`
#### `simplify(rule="nonzero")`
In cases where the contours of a single path overlap one another, it’s often useful to have a way of effectively applying a `union` operation *within* the path itself. The `simplify` method traces the path and returns a new copy that removes any overlapping segments:
In cases where the contours of a single path overlap one another, it’s often useful to have a way of effectively applying a `union` operation *within* the path itself. The `simplify` method traces the path and returns a new copy that removes any overlapping segments. When called with no arguments it defaults to the `"nonzero"` winding rule, but can also be called with `"evenodd"` to preserve overlap regions while still removing edge-crossings.

@@ -590,2 +684,18 @@ ```js

#### `unwind()`
The `unwind()` method interprets the current path using the `"evenodd"` winding rule then returns a new path that covers an equivalent area when filled using the `"nonzero"` rule (i.e., the default behavior of the context’s [`fill()`][fill()] method).
This conversion can be useful in situations where a single path contains multiple, overlapping contours and the resulting shape depends on the [nesting-depth and direction](https://oreillymedia.github.io/Using_SVG/extras/ch06-fill-rule.html) of the contours.
```js
let orig = new Path2D(`
M 0 0 h 100 v 100 h -100 Z
M 50 30 l 20 20 l -20 20 l -20 -20 Z
`)
let unwound = orig.unwind()
```
![convert winding rule subpaths](/test/assets/path/effect-unwind@2x.png)
## Utilities

@@ -709,3 +819,4 @@

[p2d_interpolate]: #interpolateotherpath-weight
[p2d_simplify]: #simplify
[p2d_simplify]: #simplifyrulenonzero
[p2d_unwind]: #unwind
[p2d_points]: #pointsstep1

@@ -720,2 +831,5 @@ [p2d_contains]: #containsx-y

[outlineText()]: #outlinetextstr
[createTexture()]: #createtexturespacing-path-line-color-angle-offset0
[lineDashMarker]: #linedashmarker
[lineDashFit]: #linedashfit

@@ -722,0 +836,0 @@ [Buffer]: https://nodejs.org/api/buffer.html

@@ -364,3 +364,3 @@ const _ = require('lodash'),

let c = a.xor(b)
ctx.fill(c.simplify(), 'nonzero')
ctx.fill(c.simplify('evenodd'))
expect(top()).toEqual(BLACK)

@@ -372,6 +372,20 @@ expect(left()).toEqual(BLACK)

ctx.fill(c)
ctx.fill(c.simplify())
expect(center()).toEqual(BLACK)
})
test("unwind", () => {
let d = new Path2D()
d.rect(0,0,30,30)
d.rect(10,10,10,10)
ctx.fill(d.offset(50,40))
expect(pixel(65, 55)).toEqual(BLACK)
ctx.fill(d.offset(100,40), 'evenodd')
expect(pixel(115, 55)).toEqual(CLEAR)
ctx.fill(d.simplify().offset(150,40), 'evenodd')
expect(pixel(165, 55)).toEqual(BLACK)
ctx.fill(d.unwind().offset(200,40))
expect(pixel(215, 55)).toEqual(CLEAR)
})
test("interpolate", () => {

@@ -378,0 +392,0 @@ let start = new Path2D()

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc