Skip to content

Commit

Permalink
Merge pull request #317 from Brooooooklyn/fix-encode
Browse files Browse the repository at this point in the history
  • Loading branch information
Brooooooklyn authored Jul 21, 2021
2 parents 580146b + f9f0d2b commit 8c758c7
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 32 deletions.
28 changes: 15 additions & 13 deletions README-zh.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# `@napi-rs/canvas`
# `skr canvas`

![CI](https://github.com/Brooooooklyn/canvas/workflows/CI/badge.svg)

> 🚀 帮助我成为全职开源开发者: [Sponsoring me on Github](https://github.com/sponsors/Brooooooklyn)
Google Skia binding to Node.js via [Node-API](https://napi.rs). **零系统依赖**.
通过 [Node-API](https://napi.rs) 将 Google Skia 绑定到 Node.js。 **零系统依赖**

> ⚠️ 这个项目还处于早期开发阶段.<br/>
> 在这里可以找到此项目的具体开发计划和路线图 [Roadmap](https://github.com/Brooooooklyn/canvas/issues/113).
> ⚠️ 这个项目还处于早期开发阶段。<br/>
> 在这里可以找到此项目的具体开发计划和路线图 [Roadmap](https://github.com/Brooooooklyn/canvas/issues/113)
[English](./README.md)

# 安装

Expand Down Expand Up @@ -35,24 +37,22 @@ npm install @napi-rs/canvas
```js
const { promises } = require('fs')
const { join } = require('path')

const { createCanvas } = require('@napi-rs/canvas')

const canvas = createCanvas(1024, 768)

const canvas = createCanvas(300, 320)
const ctx = canvas.getContext('2d')

ctx.lineWidth = 10
ctx.strokeStyle = '#03a9f4'
ctx.fillStyle = '#03a9f4'

// Wall
//
ctx.strokeRect(75, 140, 150, 110)

// Door
//
ctx.fillRect(130, 190, 40, 60)

// Roof
// 屋顶
ctx.beginPath()
ctx.moveTo(50, 140)
ctx.lineTo(150, 60)
Expand All @@ -61,7 +61,7 @@ ctx.closePath()
ctx.stroke()

async function main() {
const pngData = await canvas.encode('png') // 也支持 jpegwebp
const pngData = await canvas.encode('png') // 也支持 JPEGWebP
// encoding in libuv thread pool, non-blocking
await promises.writeFile(join(__dirname, 'simple.png'), pngData)
}
Expand Down Expand Up @@ -221,13 +221,15 @@ pathOne.op(pathTwo, PathOp.Intersect).toSVGString()
可以把 SVG 中的 `fill-rule="evenodd"` 转换为 `fill-rule="nonzero"`
这对 OpenType 字体相关工具非常有用,因为 OpenType 字体中只支持 `fill-rule="nonzero"`

![SVG fill-rule](./docs/imgs/asWinding@2x.png)

```js
const pathCircle = new Path2D(
'M50 87.5776C70.7536 87.5776 87.5776 70.7536 87.5776 50C87.5776 29.2464 70.7536 12.4224 50 12.4224C29.2464 12.4224 12.4224 29.2464 12.4224 50C12.4224 70.7536 29.2464 87.5776 50 87.5776ZM50 100C77.6142 100 100 77.6142 100 50C100 22.3858 77.6142 0 50 0C22.3858 0 0 22.3858 0 50C0 77.6142 22.3858 100 50 100Z',
'M24.2979 13.6364H129.394V40.9091H24.2979L14.6278 27.2727L24.2979 13.6364ZM21.9592 0C19.0246 0 16.2716 1.42436 14.571 3.82251L1.67756 22.0043C-0.559186 25.1585 -0.559186 29.387 1.67756 32.5411L14.571 50.7227C16.2716 53.1209 19.0246 54.5455 21.9592 54.5455H70.4673V68.1818H16.073C11.0661 68.1818 7.00728 72.2518 7.00728 77.2727V113.636C7.00728 118.657 11.0661 122.727 16.073 122.727H70.4673V150H84.0658V122.727H128.041C130.975 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.559 97.5686 150.559 93.3405 148.323 90.1864L135.429 72.0045C133.729 69.6064 130.975 68.1818 128.041 68.1818H84.0658V54.5455H133.927C138.934 54.5455 142.993 50.4755 142.993 45.4545V9.09091C142.993 4.07014 138.934 0 133.927 0H21.9592ZM125.702 109.091H20.6058V81.8182H125.702L135.372 95.4545L125.702 109.091Z',
)
pathCircle.setFillType(FillType.EvenOdd)
pathCircle.asWinding().toSVGString()
// => "M50 87.5776C29.2464 87.5776 12.4224 70.7536 12.4224 50C12.4224 29.2464 29.2464 12.4224 50 12.4224C70.7536 12.4224 87.5776 29.2464 87.5776 50C87.5776 70.7536 70.7536 87.5776 50 87.5776ZM50 100C77.6142 100 100 77.6142 100 50C100 22.3858 77.6142 0 50 0C22.3858 0 0 22.3858 0 50C0 77.6142 22.3858 100 50 100Z"
// => "M24.2979 13.6364L129.394 13.6364L129.394 40.9091L24.2979 40.9091L14.6278 27.2727L24.2979 13.6364ZM21.9592 0C19.0246 0 16.2716 1.42436 14.571 3.82251L1.67756 22.0043C-0.559186 25.1585 -0.559186 29.387 1.67756 32.5411L14.571 50.7227C16.2716 53.1209 19.0246 54.5455 21.9592 54.5455L70.4673 54.5455L70.4673 68.1818L16.073 68.1818C11.0661 68.1818 7.00728 72.2518 7.00728 77.2727L7.00728 113.636C7.00728 118.657 11.0661 122.727 16.073 122.727L70.4673 122.727L70.4673 150L84.0658 150L84.0658 122.727L128.041 122.727C130.975 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.559 97.5686 150.559 93.3405 148.323 90.1864L135.429 72.0045C133.729 69.6064 130.975 68.1818 128.041 68.1818L84.0658 68.1818L84.0658 54.5455L133.927 54.5455C138.934 54.5455 142.993 50.4755 142.993 45.4545L142.993 9.09091C142.993 4.07014 138.934 0 133.927 0L21.9592 0ZM125.702 109.091L20.6058 109.091L20.6058 81.8182L125.702 81.8182L135.372 95.4545L125.702 109.091Z"
```

### 简化 **_Path_**
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,9 @@ npm install @napi-rs/canvas
```js
const { promises } = require('fs')
const { join } = require('path')

const { createCanvas } = require('@napi-rs/canvas')

const canvas = createCanvas(1024, 768)

const canvas = createCanvas(300, 320)
const ctx = canvas.getContext('2d')

ctx.lineWidth = 10
Expand All @@ -63,7 +61,7 @@ ctx.closePath()
ctx.stroke()

async function main() {
const pngData = await canvas.encode('png') // jpeg and webp is also supported
const pngData = await canvas.encode('png') // JPEG and WebP is also supported
// encoding in libuv thread pool, non-blocking
await promises.writeFile(join(__dirname, 'simple.png'), pngData)
}
Expand Down Expand Up @@ -223,13 +221,15 @@ pathOne.op(pathTwo, PathOp.Intersect).toSVGString()
You can convert `fill-rule="evenodd"` to `fill-rule="nonzero"` in SVG.
This is useful for **OpenType** font-related tools, as `fill-rule="nonzero"` is only supported in **OpenType** fonts.

![SVG fill-rule](./docs/imgs/asWinding@2x.png)

```js
const pathCircle = new Path2D(
'M50 87.5776C70.7536 87.5776 87.5776 70.7536 87.5776 50C87.5776 29.2464 70.7536 12.4224 50 12.4224C29.2464 12.4224 12.4224 29.2464 12.4224 50C12.4224 70.7536 29.2464 87.5776 50 87.5776ZM50 100C77.6142 100 100 77.6142 100 50C100 22.3858 77.6142 0 50 0C22.3858 0 0 22.3858 0 50C0 77.6142 22.3858 100 50 100Z',
'M24.2979 13.6364H129.394V40.9091H24.2979L14.6278 27.2727L24.2979 13.6364ZM21.9592 0C19.0246 0 16.2716 1.42436 14.571 3.82251L1.67756 22.0043C-0.559186 25.1585 -0.559186 29.387 1.67756 32.5411L14.571 50.7227C16.2716 53.1209 19.0246 54.5455 21.9592 54.5455H70.4673V68.1818H16.073C11.0661 68.1818 7.00728 72.2518 7.00728 77.2727V113.636C7.00728 118.657 11.0661 122.727 16.073 122.727H70.4673V150H84.0658V122.727H128.041C130.975 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.559 97.5686 150.559 93.3405 148.323 90.1864L135.429 72.0045C133.729 69.6064 130.975 68.1818 128.041 68.1818H84.0658V54.5455H133.927C138.934 54.5455 142.993 50.4755 142.993 45.4545V9.09091C142.993 4.07014 138.934 0 133.927 0H21.9592ZM125.702 109.091H20.6058V81.8182H125.702L135.372 95.4545L125.702 109.091Z',
)
pathCircle.setFillType(FillType.EvenOdd)
pathCircle.asWinding().toSVGString()
// => "M50 87.5776C29.2464 87.5776 12.4224 70.7536 12.4224 50C12.4224 29.2464 29.2464 12.4224 50 12.4224C70.7536 12.4224 87.5776 29.2464 87.5776 50C87.5776 70.7536 70.7536 87.5776 50 87.5776ZM50 100C77.6142 100 100 77.6142 100 50C100 22.3858 77.6142 0 50 0C22.3858 0 0 22.3858 0 50C0 77.6142 22.3858 100 50 100Z"
// => "M24.2979 13.6364L129.394 13.6364L129.394 40.9091L24.2979 40.9091L14.6278 27.2727L24.2979 13.6364ZM21.9592 0C19.0246 0 16.2716 1.42436 14.571 3.82251L1.67756 22.0043C-0.559186 25.1585 -0.559186 29.387 1.67756 32.5411L14.571 50.7227C16.2716 53.1209 19.0246 54.5455 21.9592 54.5455L70.4673 54.5455L70.4673 68.1818L16.073 68.1818C11.0661 68.1818 7.00728 72.2518 7.00728 77.2727L7.00728 113.636C7.00728 118.657 11.0661 122.727 16.073 122.727L70.4673 122.727L70.4673 150L84.0658 150L84.0658 122.727L128.041 122.727C130.975 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.559 97.5686 150.559 93.3405 148.323 90.1864L135.429 72.0045C133.729 69.6064 130.975 68.1818 128.041 68.1818L84.0658 68.1818L84.0658 54.5455L133.927 54.5455C138.934 54.5455 142.993 50.4755 142.993 45.4545L142.993 9.09091C142.993 4.07014 138.934 0 133.927 0L21.9592 0ZM125.702 109.091L20.6058 109.091L20.6058 81.8182L125.702 81.8182L135.372 95.4545L125.702 109.091Z"
```

### Simplify **_Path_**
Expand Down
14 changes: 7 additions & 7 deletions __test__/pathkit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,16 @@ test('getFillTypeString() and setFillType()', (t) => {
t.is(path.getFillTypeString(), 'evenodd')
})

test('Path FillType must be converted from nonzero to evenodd', (t) => {
const pathCircle = new Path2D(
'M50 87.5776C70.7536 87.5776 87.5776 70.7536 87.5776 50C87.5776 29.2464 70.7536 12.4224 50 12.4224C29.2464 12.4224 12.4224 29.2464 12.4224 50C12.4224 70.7536 29.2464 87.5776 50 87.5776ZM50 100C77.6142 100 100 77.6142 100 50C100 22.3858 77.6142 0 50 0C22.3858 0 0 22.3858 0 50C0 77.6142 22.3858 100 50 100Z',
test('Use .asWinding() to convert filltype evenodd to nonzero', (t) => {
const evenOddPath = new Path2D(
'M24.2979 13.6364H129.394V40.9091H24.2979L14.6278 27.2727L24.2979 13.6364ZM21.9592 0C19.0246 0 16.2716 1.42436 14.571 3.82251L1.67756 22.0043C-0.559186 25.1585 -0.559186 29.387 1.67756 32.5411L14.571 50.7227C16.2716 53.1209 19.0246 54.5455 21.9592 54.5455H70.4673V68.1818H16.073C11.0661 68.1818 7.00728 72.2518 7.00728 77.2727V113.636C7.00728 118.657 11.0661 122.727 16.073 122.727H70.4673V150H84.0658V122.727H128.041C130.975 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.559 97.5686 150.559 93.3405 148.323 90.1864L135.429 72.0045C133.729 69.6064 130.975 68.1818 128.041 68.1818H84.0658V54.5455H133.927C138.934 54.5455 142.993 50.4755 142.993 45.4545V9.09091C142.993 4.07014 138.934 0 133.927 0H21.9592ZM125.702 109.091H20.6058V81.8182H125.702L135.372 95.4545L125.702 109.091Z',
)
const nonzeroPathCircle =
'M50 87.5776C29.2464 87.5776 12.4224 70.7536 12.4224 50C12.4224 29.2464 29.2464 12.4224 50 12.4224C70.7536 12.4224 87.5776 29.2464 87.5776 50C87.5776 70.7536 70.7536 87.5776 50 87.5776ZM50 100C77.6142 100 100 77.6142 100 50C100 22.3858 77.6142 0 50 0C22.3858 0 0 22.3858 0 50C0 77.6142 22.3858 100 50 100Z'
const nonzeroPath =
'M24.2979 13.6364L129.394 13.6364L129.394 40.9091L24.2979 40.9091L14.6278 27.2727L24.2979 13.6364ZM21.9592 0C19.0246 0 16.2716 1.42436 14.571 3.82251L1.67756 22.0043C-0.559186 25.1585 -0.559186 29.387 1.67756 32.5411L14.571 50.7227C16.2716 53.1209 19.0246 54.5455 21.9592 54.5455L70.4673 54.5455L70.4673 68.1818L16.073 68.1818C11.0661 68.1818 7.00728 72.2518 7.00728 77.2727L7.00728 113.636C7.00728 118.657 11.0661 122.727 16.073 122.727L70.4673 122.727L70.4673 150L84.0658 150L84.0658 122.727L128.041 122.727C130.975 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.559 97.5686 150.559 93.3405 148.323 90.1864L135.429 72.0045C133.729 69.6064 130.975 68.1818 128.041 68.1818L84.0658 68.1818L84.0658 54.5455L133.927 54.5455C138.934 54.5455 142.993 50.4755 142.993 45.4545L142.993 9.09091C142.993 4.07014 138.934 0 133.927 0L21.9592 0ZM125.702 109.091L20.6058 109.091L20.6058 81.8182L125.702 81.8182L135.372 95.4545L125.702 109.091Z'

pathCircle.setFillType(FillType.EvenOdd) // The FillType of the original path is evenodd
evenOddPath.setFillType(FillType.EvenOdd) // The FillType of the original path is evenodd

t.is(pathCircle.asWinding().toSVGString(), nonzeroPathCircle)
t.is(evenOddPath.asWinding().toSVGString(), nonzeroPath)
})

test('Use .asWinding() and .simplify() to convert cubic Bezier curve to quadratic', (t) => {
Expand Down
Binary file added docs/imgs/asWinding@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion example/image-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async function main() {
const data = new ImageData(u8array, png.width, png.height)
ctx.putImageData(data, 0, 0)

const output = await canvas.png()
const output = await canvas.encode('png')
await promises.writeFile(join(__dirname, 'tiger-tmp.png'), output)
})
}
Expand Down
2 changes: 1 addition & 1 deletion example/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ async function main() {
// fill the canvas with a quarter of the image
// ctx.drawImage(image, 0, 0, w / 2, h / 2, 0, 0, w, h)

const output = await canvas.png()
const output = await canvas.encode('png')
await promises.writeFile(join(__dirname, 'tiger-tmp.png'), output)
}

Expand Down
6 changes: 2 additions & 4 deletions example/simple.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
const { promises } = require('fs')
const { join } = require('path')

const { createCanvas } = require('../index')

const canvas = createCanvas(1024, 768)

const canvas = createCanvas(300, 320)
const ctx = canvas.getContext('2d')

ctx.lineWidth = 10
Expand All @@ -26,7 +24,7 @@ ctx.closePath()
ctx.stroke()

async function main() {
const data = await canvas.png()
const data = await canvas.encode('png')
await promises.writeFile(join(__dirname, 'simple.png'), data)
}

Expand Down
Binary file modified example/simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8c758c7

Please sign in to comment.