From c6af883bb335817e606278bd66d795f2f3b08c0c Mon Sep 17 00:00:00 2001 From: LongYinan Date: Sat, 8 Jun 2024 18:14:08 +0800 Subject: [PATCH 1/2] feat: chrome/m116 --- .github/workflows/CI.yaml | 2 +- .github/workflows/skia.yaml | 14 +++++----- README-zh.md | 2 +- README.md | 2 +- __test__/pathkit.spec.ts | 39 ++++++++++------------------ __test__/pathkit.spec.ts.md | 30 +++++++++++++++++++++ __test__/pathkit.spec.ts.snap | Bin 225 -> 2808 bytes __test__/svg-canvas.spec.ts.md | 4 +-- __test__/svg-canvas.spec.ts.snap | Bin 8351 -> 10533 bytes __test__/svg.spec.ts | 7 ++++- __test__/text-to-path.svg | 18 ++++++------- rust-toolchain.toml | 2 +- scripts/__test__/utils.spec.ts.snap | Bin 448 -> 449 bytes skia | 2 +- 14 files changed, 72 insertions(+), 50 deletions(-) diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 96371b70..12643d8d 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -178,7 +178,7 @@ jobs: - uses: goto-bus-stop/setup-zig@v2 if: ${{ matrix.settings.target == 'armv7-unknown-linux-gnueabihf' }} with: - version: 0.11.0 + version: 0.13.0 - name: Set env if: matrix.settings.host == 'windows-latest' diff --git a/.github/workflows/skia.yaml b/.github/workflows/skia.yaml index ba28560b..96d66170 100644 --- a/.github/workflows/skia.yaml +++ b/.github/workflows/skia.yaml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-14, windows-latest] + os: [ubuntu-latest, macos-latest, windows-latest] name: stable - ${{ matrix.os }} - build skia runs-on: ${{ matrix.os }} @@ -49,7 +49,7 @@ jobs: - name: Install tools on macOS run: brew install ninja llvm - if: matrix.os == 'macos-14' + if: matrix.os == 'macos-latest' - name: Install tools on Windows if: matrix.os == 'windows-latest' @@ -79,7 +79,7 @@ jobs: docker run --user "$(id -u):$(id -g)" -e PYTHONHTTPSVERIFY=0 -e SKIP_SYNC_SK_DEPS=0 --rm -v $(pwd):/canvas -w /canvas builder node ./scripts/build-skia.js - name: Compile skia - if: matrix.os == 'macos-14' + if: matrix.os == 'macos-latest' env: PYTHONHTTPSVERIFY: 0 run: | @@ -107,7 +107,7 @@ jobs: if: "!contains(github.event.head_commit.message, 'skip skia')" name: stable - apple-silicon - build skia - runs-on: macos-14 + runs-on: macos-latest steps: - uses: actions/checkout@v4 @@ -313,9 +313,9 @@ jobs: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes docker buildx build --load --platform linux/arm/v7 -t ubuntu:jammy-armv7 . -f jammy-armv7.Dockerfile docker run --rm -dt --name ubuntu-jammy-armv7 ubuntu:jammy-armv7 - sudo mkdir -p /usr/arm-linux-gnueabihf/lib/llvm-14 - sudo docker cp ubuntu-jammy-armv7:/usr/lib/llvm-14/lib /usr/arm-linux-gnueabihf/lib/llvm-14/lib - sudo docker cp ubuntu-jammy-armv7:/usr/lib/llvm-14/include /usr/arm-linux-gnueabihf/lib/llvm-14/include + sudo mkdir -p /usr/arm-linux-gnueabihf/lib/llvm-18 + sudo docker cp ubuntu-jammy-armv7:/usr/lib/llvm-18/lib /usr/arm-linux-gnueabihf/lib/llvm-18/lib + sudo docker cp ubuntu-jammy-armv7:/usr/lib/llvm-18/include /usr/arm-linux-gnueabihf/lib/llvm-18/include docker stop ubuntu-jammy-armv7 - name: Compile skia diff --git a/README-zh.md b/README-zh.md index 4cb9d49c..6103d643 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,7 +1,7 @@ # `skr canvas` ![CI](https://github.com/Brooooooklyn/canvas/workflows/CI/badge.svg) -![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm125-hotpink) +![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm126-hotpink) [![install size](https://packagephobia.com/badge?p=@napi-rs/canvas)](https://packagephobia.com/result?p=@napi-rs/canvas) [![Downloads](https://img.shields.io/npm/dm/@napi-rs/canvas.svg?sanitize=true)](https://npmcharts.com/compare/@napi-rs/canvas?minimal=true) diff --git a/README.md b/README.md index 30d9f38b..d781d452 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # `skr canvas` ![CI](https://github.com/Brooooooklyn/canvas/workflows/CI/badge.svg) -![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm125-hotpink) +![Skia Version](https://img.shields.io/badge/Skia-chrome%2Fm126-hotpink) [![install size](https://packagephobia.com/badge?p=@napi-rs/canvas)](https://packagephobia.com/result?p=@napi-rs/canvas) [![Downloads](https://img.shields.io/npm/dm/@napi-rs/canvas.svg?sanitize=true)](https://npmcharts.com/compare/@napi-rs/canvas?minimal=true) diff --git a/__test__/pathkit.spec.ts b/__test__/pathkit.spec.ts index 75b5b409..f237fcd9 100644 --- a/__test__/pathkit.spec.ts +++ b/__test__/pathkit.spec.ts @@ -30,10 +30,7 @@ test('Union boolean operation', (t) => { 'M58 0H142C146.418 0 150 3.58172 150 8V92C150 96.4183 146.418 100 142 100H58C53.5817 100 50 96.4183 50 92V8C50 3.58172 53.5817 0 58 0Z', ) - t.is( - pathOne.op(pathTwo, PathOp.Union).toSVGString(), - 'M142 0L58 0C53.5817 0 50 3.58172 50 8L50 50L8 50C3.58172 50 0 53.5817 0 58L0 142C0 146.418 3.58172 150 8 150L92 150C96.4183 150 100 146.418 100 142L100 100L142 100C146.418 100 150 96.4183 150 92L150 8C150 3.58172 146.418 0 142 0Z', - ) + t.snapshot(pathOne.op(pathTwo, PathOp.Union).toSVGString()) }) test('Difference boolean operation', (t) => { @@ -46,7 +43,7 @@ test('Difference boolean operation', (t) => { t.is( pathOne.op(pathTwo, PathOp.Difference).toSVGString(), - 'M50 50L8 50C3.58172 50 0 53.5817 0 58L0 142C0 146.418 3.58172 150 8 150L92 150C96.4183 150 100 146.418 100 142L100 100L58 100C53.5817 100 50 96.4183 50 92L50 50Z', + 'M50 50L8 50C3.5817201 50 0 53.581699 0 58L0 142C0 146.418 3.5817201 150 8 150L92 150C96.418297 150 100 146.418 100 142L100 100L58 100C53.581699 100 50 96.418297 50 92L50 50Z', ) }) @@ -60,7 +57,7 @@ test('ReverseDifference boolean operation', (t) => { t.is( pathOne.op(pathTwo, PathOp.ReverseDifference).toSVGString(), - 'M142 0L58 0C53.5817 0 50 3.58172 50 8L50 50L92 50C96.4183 50 100 53.5817 100 58L100 100L142 100C146.418 100 150 96.4183 150 92L150 8C150 3.58172 146.418 0 142 0Z', + 'M142 0L58 0C53.581699 0 50 3.5817201 50 8L50 50L92 50C96.418297 50 100 53.581699 100 58L100 100L142 100C146.418 100 150 96.418297 150 92L150 8C150 3.5817201 146.418 0 142 0Z', ) }) @@ -74,7 +71,7 @@ test('Intersect boolean operation', (t) => { t.is( pathOne.op(pathTwo, PathOp.Intersect).toSVGString(), - 'M100 100L58 100C53.5817 100 50 96.4183 50 92L50 50L92 50C96.4183 50 100 53.5817 100 58L100 100Z', + 'M100 100L58 100C53.581699 100 50 96.418297 50 92L50 50L92 50C96.418297 50 100 53.581699 100 58L100 100Z', ) }) @@ -86,10 +83,7 @@ test('Xor boolean operation', (t) => { 'M58 0H142C146.418 0 150 3.58172 150 8V92C150 96.4183 146.418 100 142 100H58C53.5817 100 50 96.4183 50 92V8C50 3.58172 53.5817 0 58 0Z', ) - t.is( - pathOne.op(pathTwo, PathOp.Xor).toSVGString(), - 'M142 0L58 0C53.5817 0 50 3.58172 50 8L50 50L8 50C3.58172 50 0 53.5817 0 58L0 142C0 146.418 3.58172 150 8 150L92 150C96.4183 150 100 146.418 100 142L100 100L142 100C146.418 100 150 96.4183 150 92L150 8C150 3.58172 146.418 0 142 0ZM100 100L100 58C100 53.5817 96.4183 50 92 50L50 50L50 92C50 96.4183 53.5817 100 58 100L100 100Z', - ) + t.snapshot(pathOne.op(pathTwo, PathOp.Xor).toSVGString()) }) test('FillType must be Winding after conversion by AsWinding()', (t) => { @@ -117,7 +111,7 @@ test('Use .asWinding() to convert filltype evenodd to nonzero', (t) => { '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 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' + 'M24.297899 13.6364L129.394 13.6364L129.394 40.9091L24.297899 40.9091L14.6278 27.272699L24.297899 13.6364ZM21.9592 0C19.024599 0 16.271601 1.42436 14.571 3.82251L1.67756 22.004299C-0.55918598 25.158501 -0.55918598 29.386999 1.67756 32.5411L14.571 50.722698C16.271601 53.120899 19.024599 54.545502 21.9592 54.545502L70.4673 54.545502L70.4673 68.181801L16.073 68.181801C11.0661 68.181801 7.0072799 72.251801 7.0072799 77.272697L7.0072799 113.636C7.0072799 118.657 11.0661 122.727 16.073 122.727L70.4673 122.727L70.4673 150L84.065804 150L84.065804 122.727L128.041 122.727C130.97501 122.727 133.729 121.303 135.429 118.905L148.323 100.723C150.55901 97.568604 150.55901 93.3405 148.323 90.186401L135.429 72.004501C133.729 69.6064 130.97501 68.181801 128.041 68.181801L84.065804 68.181801L84.065804 54.545502L133.927 54.545502C138.93401 54.545502 142.993 50.475498 142.993 45.454498L142.993 9.09091C142.993 4.0701399 138.93401 0 133.927 0L21.9592 0ZM125.702 109.091L20.605801 109.091L20.605801 81.818199L125.702 81.818199L135.37199 95.454498L125.702 109.091Z' evenOddPath.setFillType(FillType.EvenOdd) // The FillType of the original path is evenodd @@ -130,7 +124,7 @@ test('Use .asWinding() and .simplify() to convert cubic Bezier curve to quadrati ) // Quadratic bezier curve const quadraticPath = - 'M0 10C0 4.47715 4.47715 0 10 0L90 0C95.5229 0 100 4.47715 100 10C100 15.5228 95.5229 20 90 20L10 20C4.47715 20 0 15.5228 0 10Z' + 'M0 10C0 4.47715 4.47715 0 10 0L90 0C95.522903 0 100 4.47715 100 10C100 15.5228 95.522903 20 90 20L10 20C4.47715 20 0 15.5228 0 10Z' t.is(path.asWinding().simplify().toSVGString(), quadraticPath) }) @@ -142,14 +136,14 @@ test('Use .simplify() to remove overlapping paths', (t) => { t.is( path.simplify().toSVGString(), - 'M89.005 3.818L2.933 89.89Q1.526 91.296 0.765 93.134Q0.004 94.972 0.004 96.961Q0.004 98.95 0.765 100.788Q1.526 102.625 2.933 104.032Q4.339 105.439 6.177 106.2Q8.015 106.961 10.004 106.961Q11.993 106.961 13.831 106.2Q15.668 105.439 17.075 104.032L96.076 25.031L175.077 104.032Q176.484 105.439 178.322 106.2Q180.159 106.961 182.148 106.961Q184.138 106.961 185.975 106.2Q187.813 105.439 189.219 104.032Q190.626 102.625 191.387 100.788Q192.148 98.95 192.148 96.961Q192.148 94.972 191.387 93.134Q190.626 91.296 189.22 89.89L103.147 3.818Q101.741 2.411 99.903 1.65Q98.065 0.889 96.076 0.889Q94.087 0.889 92.249 1.65Q90.412 2.411 89.005 3.818Z', + 'M89.004997 3.8180001L2.9330001 89.889999Q1.526 91.295998 0.76499999 93.134003Q0.0040000002 94.972 0.0040000002 96.960999Q0.0040000002 98.949997 0.76499999 100.788Q1.526 102.625 2.9330001 104.032Q4.3390002 105.439 6.177 106.2Q8.0150003 106.961 10.004 106.961Q11.993 106.961 13.831 106.2Q15.668 105.439 17.075001 104.032L96.075996 25.031002L175.077 104.032Q176.48399 105.439 178.32201 106.2Q180.159 106.961 182.14799 106.961Q184.138 106.961 185.97501 106.2Q187.813 105.439 189.21899 104.032Q190.62601 102.625 191.38699 100.788Q192.14799 98.949997 192.14799 96.960999Q192.14799 94.972 191.38699 93.134003Q190.62601 91.295998 189.22 89.889999L103.147 3.8180001Q101.741 2.411 99.903 1.65Q98.065002 0.889 96.075996 0.889Q94.086998 0.889 92.249001 1.65Q90.412003 2.411 89.004997 3.8180001Z', ) }) test('Convert fill-type to nonzero and cubic Bezier curve to quadratic', (t) => { const pathTriangle = new Path2D('M70 0L0.717957 120H139.282L70 0ZM70 30L26.6987 105H113.301L70 30Z') // Quadratic bezier curve - const quadraticPath = 'M0.717957 120L70 0L139.282 120L0.717957 120ZM113.301 105L70 30L26.6987 105L113.301 105Z' + const quadraticPath = 'M0.71795702 120L70 0L139.282 120L0.71795702 120ZM113.301 105L70 30L26.6987 105L113.301 105Z' pathTriangle.setFillType(FillType.EvenOdd) t.is(pathTriangle.asWinding().simplify().toSVGString(), quadraticPath) @@ -170,18 +164,14 @@ test('Convert stroke to path', (t) => { ) path.stroke({ width: 10, miterLimit: 1 }).simplify().asWinding() - const expected = `M57.6458 39.75L37.2942 4.5Q34.6962 -2.38419e-06 29.5 -2.38419e-06Q24.3038 -2.90573e-06 21.7058 4.5L1.35417 39.75Q-1.2439 44.25 1.35418 48.75Q3.95226 53.25 9.14841 53.25L49.8516 53.25Q55.0478 53.25 57.6458 48.75Q60.2439 44.25 57.6458 39.75ZM29.5 11L48.1195 43.25L10.8805 43.25L29.5 11Z` - - t.is(path.toSVGString(), expected) + t.snapshot(path.toSVGString()) }) test('Convert stroke to path 2', (t) => { const path = new Path2D('M4 23.5L22.5 5L41 23.5') path.stroke({ width: 10, join: StrokeJoin.Round, miterLimit: 1 }).simplify() - const svg = `` - const expected = `` - t.is(svg, expected) + t.snapshot(path.toSVGString()) }) // 直角 @@ -211,10 +201,7 @@ test('StrokeJoin.Round', (t) => { box.rect(0, 0, 100, 100) box.stroke({ width: 20, join: StrokeJoin.Round }) - t.is( - box.toSVGString(), - 'M-10 100L-10 0Q-10 -0.245486 -9.98796 -0.490677Q-9.97591 -0.735867 -9.95185 -0.980171Q-9.92779 -1.22448 -9.89176 -1.4673Q-9.85574 -1.71013 -9.80785 -1.9509Q-9.75996 -2.19167 -9.70031 -2.4298Q-9.64067 -2.66793 -9.5694 -2.90285Q-9.49814 -3.13776 -9.41544 -3.3689Q-9.33274 -3.60003 -9.2388 -3.82683Q-9.14485 -4.05363 -9.03989 -4.27555Q-8.93493 -4.49747 -8.81921 -4.71397Q-8.70349 -4.93047 -8.57729 -5.14103Q-8.45108 -5.35159 -8.3147 -5.5557Q-8.17831 -5.75982 -8.03208 -5.95699Q-7.88584 -6.15417 -7.73011 -6.34393Q-7.57437 -6.5337 -7.40951 -6.71559Q-7.24465 -6.89748 -7.07107 -7.07107Q-6.89748 -7.24465 -6.71559 -7.40951Q-6.5337 -7.57437 -6.34393 -7.7301Q-6.15417 -7.88584 -5.95699 -8.03207Q-5.75982 -8.17831 -5.5557 -8.3147Q-5.35159 -8.45108 -5.14103 -8.57729Q-4.93047 -8.70349 -4.71397 -8.81921Q-4.49747 -8.93493 -4.27555 -9.03989Q-4.05363 -9.14485 -3.82683 -9.23879Q-3.60003 -9.33274 -3.3689 -9.41544Q-3.13776 -9.49814 -2.90285 -9.5694Q-2.66793 -9.64067 -2.4298 -9.70031Q-2.19167 -9.75996 -1.9509 -9.80785Q-1.71013 -9.85574 -1.4673 -9.89176Q-1.22448 -9.92778 -0.980171 -9.95185Q-0.735867 -9.97591 -0.490677 -9.98796Q-0.245486 -10 0 -10L100 -10Q100.245 -10 100.491 -9.98795Q100.736 -9.97591 100.98 -9.95185Q101.224 -9.92779 101.467 -9.89176Q101.71 -9.85574 101.951 -9.80785Q102.192 -9.75996 102.43 -9.70031Q102.668 -9.64067 102.903 -9.5694Q103.138 -9.49814 103.369 -9.41544Q103.6 -9.33274 103.827 -9.2388Q104.054 -9.14485 104.276 -9.03989Q104.497 -8.93493 104.714 -8.81921Q104.93 -8.70349 105.141 -8.57729Q105.352 -8.45108 105.556 -8.3147Q105.76 -8.17831 105.957 -8.03208Q106.154 -7.88584 106.344 -7.73011Q106.534 -7.57437 106.716 -7.40951Q106.897 -7.24465 107.071 -7.07107Q107.245 -6.89748 107.41 -6.71559Q107.574 -6.5337 107.73 -6.34393Q107.886 -6.15417 108.032 -5.95699Q108.178 -5.75982 108.315 -5.5557Q108.451 -5.35159 108.577 -5.14103Q108.703 -4.93047 108.819 -4.71397Q108.935 -4.49747 109.04 -4.27555Q109.145 -4.05363 109.239 -3.82683Q109.333 -3.60003 109.415 -3.3689Q109.498 -3.13776 109.569 -2.90285Q109.641 -2.66793 109.7 -2.4298Q109.76 -2.19167 109.808 -1.9509Q109.856 -1.71013 109.892 -1.4673Q109.928 -1.22448 109.952 -0.980171Q109.976 -0.735867 109.988 -0.490677Q110 -0.245486 110 0L110 100Q110 100.245 109.988 100.491Q109.976 100.736 109.952 100.98Q109.928 101.224 109.892 101.467Q109.856 101.71 109.808 101.951Q109.76 102.192 109.7 102.43Q109.641 102.668 109.569 102.903Q109.498 103.138 109.415 103.369Q109.333 103.6 109.239 103.827Q109.145 104.054 109.04 104.276Q108.935 104.497 108.819 104.714Q108.703 104.93 108.577 105.141Q108.451 105.352 108.315 105.556Q108.178 105.76 108.032 105.957Q107.886 106.154 107.73 106.344Q107.574 106.534 107.41 106.716Q107.245 106.897 107.071 107.071Q106.897 107.245 106.716 107.41Q106.534 107.574 106.344 107.73Q106.154 107.886 105.957 108.032Q105.76 108.178 105.556 108.315Q105.352 108.451 105.141 108.577Q104.93 108.703 104.714 108.819Q104.497 108.935 104.276 109.04Q104.054 109.145 103.827 109.239Q103.6 109.333 103.369 109.415Q103.138 109.498 102.903 109.569Q102.668 109.641 102.43 109.7Q102.192 109.76 101.951 109.808Q101.71 109.856 101.467 109.892Q101.224 109.928 100.98 109.952Q100.736 109.976 100.491 109.988Q100.245 110 100 110L0 110Q-0.245486 110 -0.490677 109.988Q-0.735867 109.976 -0.980171 109.952Q-1.22448 109.928 -1.4673 109.892Q-1.71013 109.856 -1.9509 109.808Q-2.19167 109.76 -2.4298 109.7Q-2.66793 109.641 -2.90285 109.569Q-3.13776 109.498 -3.3689 109.415Q-3.60003 109.333 -3.82683 109.239Q-4.05363 109.145 -4.27555 109.04Q-4.49747 108.935 -4.71397 108.819Q-4.93047 108.703 -5.14103 108.577Q-5.35159 108.451 -5.5557 108.315Q-5.75982 108.178 -5.95699 108.032Q-6.15417 107.886 -6.34393 107.73Q-6.5337 107.574 -6.71559 107.41Q-6.89748 107.245 -7.07107 107.071Q-7.24465 106.897 -7.40951 106.716Q-7.57437 106.534 -7.7301 106.344Q-7.88584 106.154 -8.03207 105.957Q-8.17831 105.76 -8.3147 105.556Q-8.45108 105.352 -8.57729 105.141Q-8.70349 104.93 -8.81921 104.714Q-8.93493 104.497 -9.03989 104.276Q-9.14485 104.054 -9.23879 103.827Q-9.33274 103.6 -9.41544 103.369Q-9.49814 103.138 -9.5694 102.903Q-9.64067 102.668 -9.70031 102.43Q-9.75996 102.192 -9.80785 101.951Q-9.85574 101.71 -9.89176 101.467Q-9.92778 101.224 -9.95185 100.98Q-9.97591 100.736 -9.98796 100.491Q-10 100.245 -10 100ZM10 10L10 90L90 90L90 10L10 10Z', - ) + t.snapshot(box.toSVGString()) }) test('computeTightBounds', (t) => { @@ -254,7 +241,7 @@ test('dash', (t) => { ctx.stroke(phased) t.is( c.getContent().toString('utf8'), - ``, + ``, ) }) diff --git a/__test__/pathkit.spec.ts.md b/__test__/pathkit.spec.ts.md index 64fbaed8..7394636d 100644 --- a/__test__/pathkit.spec.ts.md +++ b/__test__/pathkit.spec.ts.md @@ -4,6 +4,36 @@ The actual snapshot is saved in `pathkit.spec.ts.snap`. Generated by [AVA](https://avajs.dev). +## Union boolean operation + +> Snapshot 1 + + 'M142 0L58 0C53.581699 0 50 3.5817201 50 8L50 50L8 50C3.5817201 50 0 53.581699 0 58L0 142C0 146.418 3.5817201 150 8 150L92 150C96.418297 150 100 146.418 100 142L100 100L142 100C146.418 100 150 96.418297 150 92L150 8C150 3.5817201 146.418 0 142 0Z' + +## Xor boolean operation + +> Snapshot 1 + + 'M142 0L58 0C53.581699 0 50 3.5817201 50 8L50 50L8 50C3.5817201 50 0 53.581699 0 58L0 142C0 146.418 3.5817201 150 8 150L92 150C96.418297 150 100 146.418 100 142L100 100L142 100C146.418 100 150 96.418297 150 92L150 8C150 3.5817201 146.418 0 142 0ZM100 100L100 58C100 53.581699 96.418297 50 92 50L50 50L50 92C50 96.418297 53.581699 100 58 100L100 100Z' + +## Convert stroke to path + +> Snapshot 1 + + 'M57.645828 39.75L37.294228 4.5Q34.696152 -2.3841858e-06 29.5 -2.3841858e-06Q24.303848 -2.9057264e-06 21.705772 4.5000029L1.3541732 39.75Q-1.2438966 44.250042 1.3541794 48.750019Q3.9522581 53.25 9.1484098 53.25L49.851601 53.25Q55.047752 53.25 57.645824 48.750015Q60.243893 44.250038 57.645828 39.75ZM29.5 11.000004L48.119549 43.25L10.880453 43.25L29.5 11.000004Z' + +## Convert stroke to path 2 + +> Snapshot 1 + + 'M18.964466 1.4644661L0.46446609 19.964466L7.5355339 27.035534L22.5 12.071068L37.464466 27.035534L44.535534 19.964466L26.035534 1.4644661Q25.948742 1.3776736 25.857796 1.2952443Q25.76685 1.212815 25.671968 1.1349478Q25.577085 1.0570803 25.478497 0.9839623Q25.379906 0.91084433 25.277849 0.84265184Q25.175793 0.77445948 25.070513 0.71135694Q24.965233 0.64825439 24.856983 0.59039366Q24.748732 0.53253293 24.637772 0.48005348Q24.526814 0.42757404 24.413414 0.3806023Q24.300014 0.33363056 24.184444 0.29227966Q24.068878 0.25092876 23.95142 0.21529832Q23.833961 0.17966788 23.714897 0.14984374Q23.595833 0.12001958 23.475449 0.09607359Q23.355064 0.072127596 23.23365 0.054117445Q23.112236 0.036107294 22.990086 0.024076367Q22.867931 0.012045437 22.745337 0.0060227187Q22.622742 0 22.499998 0Q22.377254 0 22.254662 0.0060227187Q22.132067 0.012045437 22.009916 0.024076367Q21.887764 0.036107294 21.76635 0.054117449Q21.644932 0.072127596 21.524548 0.09607359Q21.404163 0.12001958 21.285099 0.14984372Q21.166035 0.17966788 21.048576 0.21529832Q20.931118 0.25092876 20.81555 0.29227966Q20.699982 0.33363056 20.58658 0.3806023Q20.473181 0.42757404 20.362223 0.48005348Q20.251265 0.53253293 20.143015 0.59039366Q20.034763 0.64825439 19.929483 0.71135694Q19.824203 0.77445948 19.722147 0.84265184Q19.62009 0.91084433 19.521502 0.9839623Q19.422913 1.0570803 19.328033 1.1349478Q19.23315 1.212815 19.142204 1.2952443Q19.051258 1.3776736 18.964466 1.4644661Z' + +## StrokeJoin.Round + +> Snapshot 1 + + 'M-10 100L-10 0Q-10 -0.24548623 -9.9879551 -0.49067676Q-9.9759102 -0.73586726 -9.951848 -0.98017144Q-9.9277859 -1.2244756 -9.8917646 -1.4673047Q-9.8557444 -1.7101339 -9.8078527 -1.9509032Q-9.7599602 -2.1916723 -9.7003126 -2.4298017Q-9.6406651 -2.6679311 -9.5694036 -2.9028468Q-9.4981422 -3.1377625 -9.4154406 -3.3688984Q-9.3327389 -3.6000345 -9.2387953 -3.8268342Q-9.1448517 -4.0536337 -9.0398932 -4.2755508Q-8.9349346 -4.497468 -8.8192129 -4.7139673Q-8.7034912 -4.9304667 -8.5772867 -5.141027Q-8.4510813 -5.3515878 -8.3146963 -5.5557022Q-8.1783113 -5.7598162 -8.0320759 -5.9569926Q-7.8858395 -6.1541691 -7.7301054 -6.3439331Q-7.5743704 -6.5336962 -7.4095116 -6.7155895Q-7.2446527 -6.8974829 -7.0710678 -7.0710678Q-6.8974829 -7.2446527 -6.7155895 -7.4095111Q-6.5336962 -7.5743694 -6.3439331 -7.7301044Q-6.1541691 -7.8858385 -5.9569926 -8.032074Q-5.7598162 -8.1783104 -5.5557022 -8.3146954Q-5.3515878 -8.4510803 -5.1410275 -8.5772858Q-4.9304667 -8.7034912 -4.7139673 -8.8192129Q-4.497468 -8.9349337 -4.2755508 -9.0398922Q-4.0536337 -9.1448507 -3.8268342 -9.2387943Q-3.6000345 -9.3327389 -3.3688984 -9.4154406Q-3.1377625 -9.4981422 -2.9028468 -9.5694036Q-2.6679311 -9.6406651 -2.4298017 -9.7003126Q-2.1916723 -9.7599602 -1.9509032 -9.8078518Q-1.7101339 -9.8557434 -1.4673047 -9.8917637Q-1.2244756 -9.9277849 -0.98017144 -9.951848Q-0.73586726 -9.9759092 -0.49067676 -9.9879551Q-0.24548623 -10 0 -10L100 -10Q100.24548 -10 100.49068 -9.9879541Q100.73587 -9.9759092 100.98018 -9.951848Q101.22448 -9.9277859 101.4673 -9.8917646Q101.71013 -9.8557444 101.9509 -9.8078527Q102.19167 -9.7599602 102.42979 -9.7003126Q102.66793 -9.6406651 102.90285 -9.5694036Q103.13776 -9.4981422 103.3689 -9.4154406Q103.60002 -9.3327389 103.82682 -9.2387953Q104.05362 -9.1448517 104.27554 -9.0398932Q104.49747 -8.9349346 104.71397 -8.8192129Q104.93047 -8.7034912 105.14102 -8.5772867Q105.35158 -8.4510813 105.55569 -8.3146963Q105.75981 -8.1783113 105.95699 -8.0320759Q106.15417 -7.8858395 106.34393 -7.7301054Q106.53369 -7.5743704 106.71558 -7.4095116Q106.89748 -7.2446527 107.07106 -7.0710678Q107.24464 -6.8974829 107.4095 -6.7155895Q107.57436 -6.5336962 107.7301 -6.3439331Q107.88583 -6.1541691 108.03207 -5.9569926Q108.1783 -5.7598162 108.31468 -5.5557022Q108.45107 -5.3515878 108.57726 -5.1410275Q108.70348 -4.9304667 108.8192 -4.7139673Q108.93492 -4.497468 109.03987 -4.2755508Q109.14484 -4.0536337 109.23878 -3.8268342Q109.33272 -3.6000345 109.41542 -3.3688984Q109.49813 -3.1377625 109.5694 -2.9028468Q109.64066 -2.6679311 109.7003 -2.4298017Q109.75995 -2.1916723 109.80785 -1.9509032Q109.85574 -1.7101339 109.89175 -1.4673047Q109.92778 -1.2244756 109.95184 -0.98017144Q109.97591 -0.73586726 109.98795 -0.49067676Q110 -0.24548623 110 0L110 100Q110 100.24548 109.98795 100.49068Q109.97591 100.73587 109.95185 100.98018Q109.92778 101.22448 109.89176 101.4673Q109.85574 101.71013 109.80785 101.9509Q109.75995 102.19167 109.7003 102.42979Q109.64066 102.66793 109.5694 102.90285Q109.49813 103.13776 109.41543 103.3689Q109.33272 103.60002 109.23878 103.82682Q109.14484 104.05362 109.03987 104.27554Q108.93492 104.49747 108.8192 104.71397Q108.70348 104.93047 108.57726 105.14102Q108.45107 105.35158 108.31468 105.55569Q108.1783 105.75981 108.03207 105.95699Q107.88583 106.15417 107.73009 106.34393Q107.57436 106.53369 107.40951 106.71558Q107.24464 106.89748 107.07106 107.07106Q106.89748 107.24464 106.71558 107.4095Q106.53369 107.57436 106.34393 107.7301Q106.15417 107.88583 105.95699 108.03207Q105.75981 108.1783 105.55569 108.31468Q105.35158 108.45107 105.14102 108.57726Q104.93047 108.70348 104.71396 108.8192Q104.49746 108.93492 104.27554 109.03987Q104.05362 109.14484 103.82682 109.23878Q103.60002 109.33272 103.36888 109.41542Q103.13776 109.49813 102.90285 109.5694Q102.66793 109.64066 102.42979 109.7003Q102.19167 109.75995 101.9509 109.80785Q101.71013 109.85574 101.4673 109.89175Q101.22448 109.92778 100.98018 109.95184Q100.73587 109.97591 100.49068 109.98795Q100.24548 110 100 110L0 110Q-0.24548623 110 -0.49067676 109.98795Q-0.73586726 109.97591 -0.98017144 109.95185Q-1.2244756 109.92778 -1.4673047 109.89176Q-1.7101339 109.85574 -1.9509032 109.80785Q-2.1916723 109.75995 -2.4298017 109.7003Q-2.6679311 109.64066 -2.9028468 109.5694Q-3.1377625 109.49813 -3.3688984 109.41543Q-3.6000345 109.33272 -3.8268342 109.23878Q-4.0536337 109.14484 -4.2755508 109.03987Q-4.497468 108.93492 -4.7139673 108.8192Q-4.9304667 108.70348 -5.141027 108.57726Q-5.3515878 108.45107 -5.5557022 108.31468Q-5.7598162 108.1783 -5.9569926 108.03207Q-6.1541691 107.88583 -6.3439331 107.73009Q-6.5336962 107.57436 -6.7155895 107.40951Q-6.8974829 107.24464 -7.0710678 107.07106Q-7.2446527 106.89748 -7.4095111 106.71558Q-7.5743694 106.53369 -7.7301044 106.34393Q-7.8858385 106.15417 -8.032074 105.95699Q-8.1783104 105.75981 -8.3146954 105.55569Q-8.4510803 105.35158 -8.5772858 105.14102Q-8.7034912 104.93047 -8.8192129 104.71396Q-8.9349337 104.49746 -9.0398922 104.27554Q-9.1448507 104.05362 -9.2387943 103.82682Q-9.3327389 103.60002 -9.4154406 103.36888Q-9.4981422 103.13776 -9.5694036 102.90285Q-9.6406651 102.66793 -9.7003126 102.42979Q-9.7599602 102.19167 -9.8078518 101.9509Q-9.8557434 101.71013 -9.8917637 101.4673Q-9.9277849 101.22448 -9.951848 100.98018Q-9.9759102 100.73587 -9.9879551 100.49068Q-10 100.24548 -10 100ZM10 10L10 90L90 90L90 10L10 10Z' + ## trim > Snapshot 1 diff --git a/__test__/pathkit.spec.ts.snap b/__test__/pathkit.spec.ts.snap index 758d71ffa1ec7cd7688a2615e1e294ad4529ddc4..4ee30cae90e12acd91a09db37effbd69c76ea7d6 100644 GIT binary patch literal 2808 zcmV`nY^(y^V+k(ruT5cR=*t+q zV=#+mkspf)00000000B!nZ1r(#|?m`Bu450E>a$Bf5#+;9Fl;fBHIObi<2OLW2BLz zwY9LaD@beEZJM-sg8)w6APo__M=7eD#WlN)4O;4HSlwd5p*#eIQAV5#4f0OO0DC4^^N1g@uF zV41G7Gc3q-9j_%Z+OQ7BLh*WbinnX88su7kLg*K5pXprR0nV{a1h}4l7g**MoX+(g z*EsF}xTr36&1E4;CaNBLBNt-Mp{J#ogb2w{LaQixu>})mc2)~5 zQH81oqF|6ikJZ?9f#jCGP+cvnJCu+i7;~^okCsN;T4#i9@gaS^cWuZugikn0z@^++ zt6&mhVVewyiGi`qrp81j5GCz!3WX+?0`*qieVBkvv`mhM| zf((*aiIUud5fW=g!zpSZM8E^d&=Uw! zl;1|YAEEJq`M1BVbpQ3k-F^Da!?*XZKBoJp|DNdnuTO7IxU~%N4r{!gqAm$rp}d?t zxv7g_h}ofN(XxhE#StjPn#GDzsoG&K3#l8RB6C#^T8b}GZ;4r@>YAe#E+OTj8CXNt zL^MEj!lVcoQWA~<&YW`%Ut)1 z%qFPIi4#aJ0i2U3$ZnC+Cr+dy0=Awkd1lXH9Zu}Z#g>yLLnkB;plFw73Hi@rIK^;SXUE+3t|bWqKLVKE-{zt z_ma$&EzYi6HxXNJAJzs^3itdR!r1N@_b}2b8Wq(or;6g$i@Mg>qOGvYrNJm>V&W&>_0C%gXkMcATe1n3&Vh%+9GcnBjR zZLIepjM$~IH3(ruIgMRJ6?!epot+_+T90yF*l<;$qsrKug|MP!Y~!jh7&NtfRT>TA)E-u8r0vv8;zi3D-{FiK64(8G2W4NO z;c~cFr{%FL>98EO-(h*2voux?_UNeWhC4_(7`TJ7Iig{5a9F2gb8KVe5C9#KN2KIN z$RVOSAbaRFJ`OS3@z{g8(Qyd+4#$=p4UIz*bu#vBYhWDGvU9QLZ^L5G^A5$%gT}-G z936=}VB)dULBxSX9f$|9u=8+0TgPE%VEeSrzxFFOsvaw^^UeAOHcTHRT<5(X=Q+6F z&b`jIXy(}pNweZQTee$!D^1NS>+GrSy~?}h|nQICbKdbXHZ=QuiI>!`;q2G=<* zd#ncOtix};2=hJkkCx%ckabR)o=95{a^%~3k%D_#?mbOQ-t{7(TawovsUdHj@o*sH z=(!s3)(hM;1Z`bhL)Fmd?J$e?bA4Se!8bONeT9!8dZ4v+s111QC7TamAB}HA-g?RV zqX-=BbT`~Z4QYktXwsV_E~-*1RY&LF9D7mcTJbx^i3Y#*qIR}|dJHK&_AcsiE7Hg4 z)1!GT@k7}^#;KMa7d^w?NF3e8kZl)jNb60G!LR4)FuwS<32$TR2>HBsUO|v=YiA1_&oHu$Migae;A&p zwt1hOhe|Sx&QmMCPtHSanmYNRy+0nPG&Zio+}!Ed$L67Y4pZ|qhU`Q0P>?UCm^RuR zPm~%W*NefZO-sjfs@^kP3|nmiJDz^^Cgfs(Yg64mEcd2n7?tNaahsHTlQhi9^W?cb z{p(HF@St#>W%q}Qy^T9fjo$t({-e3nk$G`A`|-L-u>B|U)#JOnKYjGD^Ygz=&pQA5 zKIeq_E=hcg6_5WmF-MxA9 z{OZd$-`-v=ubyAsAVdtuzu#nmv+pl1=luoFr~T#7LXa=6UOf9OmV5E+v-cmqe(_&+ K5$fF|AOHY;v2{9ZjGy7ZnU;^S2 z5k}ByFCU8t00000000A9n3j~2pPXIXxG1$Gvm_@qrKBh`H?ue|v7k63zofWvVM_DO%boHoY?TZY z3>1JOAgp9(Q;=Aap^%oDlVhutlvA3jq>y5(␊ - ␊ + ␊ ` ## should be able to export text @@ -22,5 +22,5 @@ Generated by [AVA](https://avajs.dev). `␊ - ␊ + ` diff --git a/__test__/svg-canvas.spec.ts.snap b/__test__/svg-canvas.spec.ts.snap index fffa9a03d8797a979df2cb9941daf5f497c279fd..b269a7849b10bcc4ee5f27c503f4c0dec607d437 100644 GIT binary patch literal 10533 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 diff --git a/__test__/svg.spec.ts b/__test__/svg.spec.ts index 2419e1aa..00726a9e 100644 --- a/__test__/svg.spec.ts +++ b/__test__/svg.spec.ts @@ -16,6 +16,11 @@ test('convertSVGTextToPath should work', async (t) => { if (process.platform === 'win32') { t.pass('Skip on windows') } else { - t.deepEqual(result.toString('utf8'), output) + result + .toString('utf8') + .split('\n') + .forEach((line, index) => { + t.deepEqual(line.trim(), output.split('\n')[index]?.trim()) + }) } }) diff --git a/__test__/text-to-path.svg b/__test__/text-to-path.svg index 0ac789e9..bf680afb 100644 --- a/__test__/text-to-path.svg +++ b/__test__/text-to-path.svg @@ -1,12 +1,12 @@ - - - - - - - - - + + + + + + + + + diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 0c7fa949..831159a1 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-02-04" +channel = "nightly-2024-06-05" profile = "default" diff --git a/scripts/__test__/utils.spec.ts.snap b/scripts/__test__/utils.spec.ts.snap index 28b043a8061a29adba6c6a146b4ba08cea74a570..4c821610cab48344856a2a7339a8464a803b66c6 100644 GIT binary patch literal 449 zcmV;y0Y3ggRzViN*4Q+u zO}f_e4t|dLNo83&OlK5ovA4pn@AE#trd>>Y%7a+Ee}s}q8m1{^B6JGEE-#!EWJCmm zR76~g`2u5*F!HxLJDug#-R|smA0jDJaf8s5$SC){fG6lSexGz1X} zgn7Xz2aNjtJ`ynjSHawJIB*j&3p`4EO*%732P%ztF44UNNdk5MC4Oqe_ie*XQ%YD~ z{(~tczS>9e)IL*|d!R`@gLJrIs-Irx>#CONTJ?3MiXkfqv$&3piFd8Iu7JyR8jBtq z`MqyPYs>Ovr3sJ)(Qx4AEM~l5x|1o(E#?ygF>3KGSDXChO`jY2qn`*>4?W#Omdvg; zTL{4?(Ztfli$QyCvkSG&n%}q&&&WH!QEF$SydI7>jz*FTYUv{|Xpb%b0hZv#Mbv+e rw((U1j`?-yz8KCp!4`XLAf8&W*Tm}NHrB7_t@A$taWY_0;syW!KatU~ literal 448 zcmV;x0YCmhRzVM)adMu^!ar=V=i}WiF!g$+sYiyd- zCf(}UgP&u5Qrj#YrZWn)*jwS(_j#XR(=H|+<$fgIKLSZ44Uz;>5jbi883>dHGyo9@ zg!!CN4j2sv10*5>eFf|1!;5|_X1+^_r%5LUX-}mQ&m_8&Ac?Q;zr>G?_^xfZX-Wyp z@_#Tbz-k}GQ~OL==7J{m4ATCZseXEuud7<7Yt@&fDu%RZ!{RzNCf>HLduaI&P=Xs5QU5vG q##aqE=GUS7VmRdlTkNrccx=U96RVTkSihdP&i@2)GGI~S1^@tP0o6bN diff --git a/skia b/skia index ec3813ea..be621ea0 160000 --- a/skia +++ b/skia @@ -1 +1 @@ -Subproject commit ec3813eabd24854a1b82457064e9e3031ccc06d7 +Subproject commit be621ea04206d8fae23952783d1d588d6ce0d9b3 From f313c3ffadc766cd7ea548fae3476560ac8add72 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Sat, 8 Jun 2024 20:20:21 +0800 Subject: [PATCH 2/2] fix [skip skia] --- .cargo/config.toml | 2 +- .github/workflows/CI.yaml | 4 +++- src/filter.rs | 8 ++++---- src/pattern.rs | 1 + src/sk.rs | 9 +++++---- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 04c53e22..3b754dde 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,5 +1,5 @@ [target.x86_64-pc-windows-msvc] -rustflags = ["-C", "link-args=/NODEFAULTLIB:libcmt.lib", "-C", "target-feature=+crt-static"] +rustflags = ["-C", "target-feature=+crt-static"] [target.aarch64-apple-darwin] rustflags = ["-C", "target-cpu=apple-a14"] diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 12643d8d..7df90331 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -77,6 +77,8 @@ jobs: yarn build --target x86_64-apple-darwin downloadTarget: '' - host: windows-latest + setup: | + choco upgrade llvm build: yarn build --target x86_64-pc-windows-msvc target: 'x86_64-pc-windows-msvc' downloadTarget: '' @@ -150,7 +152,7 @@ jobs: export LDFLAGS="--target=aarch64-linux-android24" yarn build --target aarch64-linux-android - name: stable - ${{ matrix.settings.target }} - node@18 + name: stable - ${{ matrix.settings.target }} - node@20 runs-on: ${{ matrix.settings.host }} steps: diff --git a/src/filter.rs b/src/filter.rs index daf5c4d6..46bb018c 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -312,7 +312,7 @@ pub(crate) fn css_filters_to_image_filter(filters: Vec) -> Option { - let amt = 1.0 - amt.max(0.0).min(1.0); + let amt = 1.0 - amt.clamp(0.0, 1.0); ImageFilter::make_image_filter( 0.2126 + 0.7874 * amt, 0.7152 - 0.7152 * amt, @@ -345,7 +345,7 @@ pub(crate) fn css_filters_to_image_filter(filters: Vec) -> Option { - let amt = amt.max(0.0).min(1.0); + let amt = amt.clamp(0.0, 1.0); let mut ramp = [0u8; 256]; ramp .iter_mut() @@ -360,7 +360,7 @@ pub(crate) fn css_filters_to_image_filter(filters: Vec) -> Option { - let opacity = opacity.max(0.0).min(1.0); + let opacity = opacity.clamp(0.0, 1.0); ImageFilter::make_image_filter( 1.0, 0.0, @@ -392,7 +392,7 @@ pub(crate) fn css_filters_to_image_filter(filters: Vec) -> Option { - let amt = 1.0 - amt.max(0.0).min(1.0); + let amt = 1.0 - amt.clamp(0.0, 1.0); ImageFilter::make_image_filter( 0.393 + 0.607 * amt, 0.769 - 0.769 * amt, diff --git a/src/pattern.rs b/src/pattern.rs index 835f66a4..168effeb 100644 --- a/src/pattern.rs +++ b/src/pattern.rs @@ -12,6 +12,7 @@ use crate::{CanvasElement, SVGCanvas}; #[derive(Debug, Clone)] pub enum Pattern { + #[allow(dead_code)] Color(RGBA, String), Gradient(Gradient), Image(ImagePattern), diff --git a/src/sk.rs b/src/sk.rs index d030c1ba..4efbbe32 100644 --- a/src/sk.rs +++ b/src/sk.rs @@ -1,7 +1,7 @@ use std::convert::TryFrom; use std::f32::consts::PI; use std::ffi::{c_void, CStr, CString, NulError}; -use std::fmt; +use std::fmt::{self, Display}; use std::ops::{Deref, DerefMut}; use std::os::raw::c_char; use std::ptr; @@ -222,6 +222,7 @@ pub mod ffi { pub type SkiacFontCollectionGetFamily = Option; + #[allow(clippy::duplicated_attributes)] // https://github.com/rust-lang/rust/issues/96192 #[link( name = "svg", @@ -1480,9 +1481,9 @@ impl TextBaseline { } } -impl ToString for TextBaseline { - fn to_string(&self) -> String { - self.as_str().to_owned() +impl Display for TextBaseline { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) } }