Skip to content

Commit

Permalink
Fix error computing some quadratic Bézier curves cases (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
mondeja authored Mar 13, 2024
1 parent 743d1b2 commit 5683e6a
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 46 deletions.
35 changes: 17 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
node-version: [18.x, 20.x]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Use NodeJS v${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install
Expand All @@ -29,20 +29,20 @@ jobs:
- name: Test
run: npm test
- name: Coverage
uses: coverallsapp/github-action@v1.1.2
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./tests/coverage/lcov.info
file: ./tests/coverage/lcov.info

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use NodeJS v16
uses: actions/setup-node@v3
- uses: actions/checkout@v4
- name: Use NodeJS v20
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: Install
run: npm ci
- name: Lint
Expand All @@ -57,19 +57,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Use NodeJS v16
uses: actions/setup-node@v3
uses: actions/checkout@v4
- name: Use NodeJS v20
uses: actions/setup-node@v4
with:
node-version: 16.x
node-version: 20.x
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Test
run: npm test
- name: Deploy to NPM
uses: JS-DevTools/npm-publish@v1.4.3
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}

Expand All @@ -78,7 +78,7 @@ jobs:
needs: npm
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Get tag metadata
id: tag
run: |
Expand All @@ -93,11 +93,10 @@ jobs:
TAG_BODY="${TAG_BODY//$'\r'/'%0D'}"
echo ::set-output name=body::$TAG_BODY
- name: Create Release
uses: actions/create-release@v1.1.4
id: create-release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.title }}
release_name: ${{ steps.tag.outputs.title }}
name: ${{ steps.tag.outputs.title }}
body: ${{ steps.tag.outputs.body }}
draft: false
prerelease: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
action-update-license-year:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: FantasticFiasco/action-update-license-year@v2
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.2.5 - 2024-03-13

- Fixed error computing some quadratic Bézier curves cases.

## 1.2.4 - 2023-02-09

- Optimized proccesing of segments based on [Simple Icons] data.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SVG paths bounding box calculator.

## Install

```
```sh
npm install svg-path-bbox
```

Expand Down Expand Up @@ -58,7 +58,7 @@ console.log(svgPathBbox(cases[0]));

### Reference

<a name="svgPathBbox" href="#svgPathBbox">#</a> <b>svgPathBbox</b>(d : <em>string</em>) ⇒ [minX: <em>number</em>, minY: <em>number</em>, maxX: <em>number</em>, maxY: <em>number</em>]
<a name="svgPathBbox" href="#svgPathBbox">#</a> **svgPathBbox**(d : _string_) ⇒ [minX: _number_, minY: _number_, maxX: _number_, maxY: _number_]

Computes the bounding box of SVG path following the [SVG 1.1 specification](https://www.w3.org/TR/SVG/paths.html).

Expand Down
2 changes: 1 addition & 1 deletion dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var CBEZIER_MINMAX_EPSILON = 0.00000001;
// https://github.com/kpym/SVGPathy/blob/acd1a50c626b36d81969f6e98e8602e128ba4302/lib/box.js#L89
function minmaxQ(A) {
var min = Math.min(A[0], A[2]), max = Math.max(A[0], A[2]);
if (A[1] > A[0] ? A[2] >= A[1] : A[2] <= A[1]) {
if (A[1] >= A[0] ? A[2] >= A[1] : A[2] <= A[1]) {
// if no extremum in ]0,1[
return [min, max];
}
Expand Down
2 changes: 1 addition & 1 deletion lib/index.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function minmaxQ(A: [number, number, number]): minMax {
const min = Math.min(A[0], A[2]),
max = Math.max(A[0], A[2]);

if (A[1] > A[0] ? A[2] >= A[1] : A[2] <= A[1]) {
if (A[1] >= A[0] ? A[2] >= A[1] : A[2] <= A[1]) {
// if no extremum in ]0,1[
return [min, max];
}
Expand Down
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svg-path-bbox",
"version": "1.2.4",
"version": "1.2.5",
"description": "Compute bounding boxes of SVG paths.",
"keywords": [
"svg",
Expand Down Expand Up @@ -32,7 +32,7 @@
"dist:create": "mkdir dist",
"dist:clean": "rimraf dist",
"test": "jest",
"prepare": "is-ci || husky install"
"prepare": "is-ci || husky"
},
"author": {
"name": "Álvaro Mondéjar Rubio",
Expand All @@ -55,7 +55,7 @@
"eslint": "8.15.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-prettier": "4.0.0",
"husky": "8.0.1",
"husky": "9.0.11",
"is-ci": "3.0.1",
"jest": "28.1.0",
"jest-puppeteer": "6.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function minmaxQ(A: [number, number, number]): minMax {
const min = Math.min(A[0], A[2]),
max = Math.max(A[0], A[2]);

if (A[1] > A[0] ? A[2] >= A[1] : A[2] <= A[1]) {
if (A[1] >= A[0] ? A[2] >= A[1] : A[2] <= A[1]) {
// if no extremum in ]0,1[
return [min, max];
}
Expand Down
22 changes: 14 additions & 8 deletions tests/cases/bbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ export const pathologicalCases: CasesTuple = [
[
// Microsoft Excel
"M23 1.5q.41 0 .7.3.3.29.3.7v19q0 .41-.3.7-.29.3-.7.3H7q-.41 0-.7-.3-.3-.29-.3-.7V18H1q-.41 0-.7-.3-.3-.29-.3-.7V7q0-.41.3-.7Q.58 6 1 6h5V2.5q0-.41.3-.7.29-.3.7-.3zM6 13.28l1.42 2.66h2.14l-2.38-3.87 2.34-3.8H7.46l-1.3 2.4-.05.08-.04.09-.64-1.28-.66-1.29H2.59l2.27 3.82-2.48 3.85h2.16zM14.25 21v-3H7.5v3zm0-4.5v-3.75H12v3.75zm0-5.25V7.5H12v3.75zm0-5.25V3H7.5v3zm8.25 15v-3h-6.75v3zm0-4.5v-3.75h-6.75v3.75zm0-5.25V7.5h-6.75v3.75zm0-5.25V3h-6.75v3Z",
[5.551115123125783e-17, 1.5, 24, 22.5],
// svg-path-bounding-box: [ 5.551115123125783e-17, 1.5, 24, 22.769499273762435 ]
[5.551115123125783e-17, 1.5, 24.000000000000096, 22.5],
// svg-path-bounding-box (outdated): [ 5.551115123125783e-17, 1.5, 24, 22.769499273762435 ]
],
[
// Microsoft Exchange
"M24 7.875q0 .293-.117.58t-.317.486L20.496 12l3.07 3.059q.2.199.317.486.117.287.117.58V21q0 .316-.117.586-.117.27-.322.475-.206.205-.475.322-.27.117-.586.117h-4.875q-.293 0-.58-.117t-.486-.317l-3.059-3.07-3.059 3.07q-.199.2-.486.317-.287.117-.58.117H4.5q-.316 0-.586-.117-.27-.117-.475-.322-.205-.206-.322-.475Q3 21.316 3 21v-3H.996q-.41 0-.703-.293T0 17.004V6.996q0-.41.293-.703T.996 6H3V3q0-.316.117-.586.117-.27.322-.475.206-.205.475-.322.27-.117.586-.117h4.875q.293 0 .58.117t.486.317l3.059 3.07 3.059-3.07q.199-.2.486-.317.287-.117.58-.117H22.5q.316 0 .586.117.27.117.475.322.205.206.322.475Q24 2.684 24 3zM4.5 3v3h6.504q.41 0 .703.293t.293.703V5.625L9.375 3zM3.375 15.938h5.25v-1.583h-3.41v-1.593h3.047V11.18H5.215V9.656H8.46V8.062H3.375zm19.125.187L19.875 13.5h-3.691q-.247 0-.463.094-.217.094-.375.252-.159.158-.252.375-.094.216-.094.463v3.691L17.625 21H22.5zm0-8.25V3h-4.875L13.5 7.125v2.191q0 .774-.404 1.424-.405.65-1.096.99v5.274q0 .41-.293.703t-.703.293H4.5v3h4.875l4.125-4.125v-2.191q0-.563.21-1.05.212-.486.575-.849t.85-.574Q15.62 12 16.184 12h2.191Z",
[0, 1.4999999999999962, 24, 22.5],
[0, 1.4999999999999998, 24, 22.5],
// svg-path-bouding-box: [ 0, 1.4999999999999998, 24, 22.67233909145166 ]
],
[
Expand All @@ -83,22 +83,22 @@ export const pathologicalCases: CasesTuple = [
[
// Microsoft OneNote
"M23 1.5Q23.41 1.5 23.7 1.8 24 2.09 24 2.5V21.5Q24 21.91 23.7 22.2 23.41 22.5 23 22.5H7Q6.59 22.5 6.3 22.2 6 21.91 6 21.5V18H1Q0.59 18 0.3 17.7 0 17.41 0 17V7Q0 6.59 0.3 6.3 0.58 6 1 6H6V2.5Q6 2.09 6.3 1.8 6.59 1.5 7 1.5ZM4.56 11 7.39 15.93H9.18V8.07H7.44V13.1L4.71 8.07H2.82V15.93H4.56ZM22.5 21V18H19.5V21ZM22.5 16.5V13.5H19.5V16.5ZM22.5 12V9H19.5V12ZM22.5 7.5V3H7.5V6H11Q11.41 6 11.7 6.3 12 6.59 12 7V17Q12 17.41 11.7 17.7 11.41 18 11 18H7.5V21H18V7.5Z",
[0, 1.5, 24, 22.5],
// svg-path-bounding-box: [ 0, 1.5, 24, 22.769499273762435 ]
[0, 1.5, 24.000000000000096, 22.5],
// svg-path-bounding-box (outdated): [ 0, 1.5, 24, 22.769499273762435 ]
],
[
// Microsoft Outlook
"M7.88 12.04q0 .45-.11.87-.1.41-.33.74-.22.33-.58.52-.37.2-.87.2t-.85-.2q-.35-.21-.57-.55-.22-.33-.33-.75-.1-.42-.1-.86t.1-.87q.1-.43.34-.76.22-.34.59-.54.36-.2.87-.2t.86.2q.35.21.57.55.22.34.31.77.1.43.1.88zM24 12v9.38q0 .46-.33.8-.33.32-.8.32H7.13q-.46 0-.8-.33-.32-.33-.32-.8V18H1q-.41 0-.7-.3-.3-.29-.3-.7V7q0-.41.3-.7Q.58 6 1 6h6.5V2.55q0-.44.3-.75.3-.3.75-.3h12.9q.44 0 .75.3.3.3.3.75V10.85l1.24.72h.01q.1.07.18.18.07.12.07.25zm-6-8.25v3h3v-3zm0 4.5v3h3v-3zm0 4.5v1.83l3.05-1.83zm-5.25-9v3h3.75v-3zm0 4.5v3h3.75v-3zm0 4.5v2.03l2.41 1.5 1.34-.8v-2.73zM9 3.75V6h2l.13.01.12.04v-2.3zM5.98 15.98q.9 0 1.6-.3.7-.32 1.19-.86.48-.55.73-1.28.25-.74.25-1.61 0-.83-.25-1.55-.24-.71-.71-1.24t-1.15-.83q-.68-.3-1.55-.3-.92 0-1.64.3-.71.3-1.2.85-.5.54-.75 1.3-.25.74-.25 1.63 0 .85.26 1.56.26.72.74 1.23.48.52 1.17.81.69.3 1.56.3zM7.5 21h12.39L12 16.08V17q0 .41-.3.7-.29.3-.7.3H7.5zm15-.13v-7.24l-5.9 3.54Z",
[
5.551115123125783e-17, 1.499999999999999, 24.000000000000004,
5.551115123125783e-17, 1.4999999999999998, 24.000000000000004,
22.500000000000004,
],
// svg-path-bounding-box: [ 5.551115123125783e-17, 1.4999999999999998, 24.000000000000004, 22.727227619294418 ]
// svg-path-bounding-box: [ 5.551115123125783e-17, 1.499999999999999, 24.000000000000004, 22.727227619294418 ]
],
[
// Microsoft Word
"M23.004 1.5q.41 0 .703.293t.293.703v19.008q0 .41-.293.703t-.703.293H6.996q-.41 0-.703-.293T6 21.504V18H.996q-.41 0-.703-.293T0 17.004V6.996q0-.41.293-.703T.996 6H6V2.496q0-.41.293-.703t.703-.293zM6.035 11.203l1.442 4.735h1.64l1.57-7.876H9.036l-.937 4.653-1.325-4.5H5.38l-1.406 4.523-.938-4.675H1.312l1.57 7.874h1.641zM22.5 21v-3h-15v3zm0-4.5v-3.75H12v3.75zm0-5.25V7.5H12v3.75zm0-5.25V3h-15v3Z",
[0, 1.4999999999999996, 24, 22.499999999999996],
[0, 1.5, 24, 22.499999999999996],
// svg-path-bounding-box: [ 0, 1.5, 24, 22.772661142370712 ]
],
[
Expand Down Expand Up @@ -165,6 +165,12 @@ export const pathologicalCases: CasesTuple = [
[0.17800000000000005, -0.00016249501660449533, 23.82066666666666, 24],
// svg-path-bounding-box: [ 0.17800000000000005, -0.00016249501660449477, 23.82066666666666, 24 ]
],

// https://github.com/mondeja/svg-path-bbox/issues/112
["M90 100Q109 100 110 110L100 90", [90, 90, 110, 110]],
["M90 100Q101 100 110 110L100 90", [90, 90, 110, 110]],
["M90 100Q90 110 110 110L100 90", [90, 90, 110, 110]],
// svg-path-bounding-box: [ 90, 90, 110, 110 ]
];

export default [...linealCases, ...pathologicalCases];

0 comments on commit 5683e6a

Please sign in to comment.