diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fea411e..91a11d8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -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
@@ -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
@@ -57,11 +57,11 @@ 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
@@ -69,7 +69,7 @@ jobs:
- 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 }}
@@ -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: |
@@ -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
diff --git a/.github/workflows/update-copyright-years-in-license-file.yml b/.github/workflows/update-copyright-years-in-license-file.yml
index de7f25a..c6ee7e4 100644
--- a/.github/workflows/update-copyright-years-in-license-file.yml
+++ b/.github/workflows/update-copyright-years-in-license-file.yml
@@ -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
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec946cc..8881ca7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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.
diff --git a/README.md b/README.md
index 0fefbb6..1099713 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ SVG paths bounding box calculator.
## Install
-```
+```sh
npm install svg-path-bbox
```
@@ -58,7 +58,7 @@ console.log(svgPathBbox(cases[0]));
### Reference
-# svgPathBbox(d : string) ⇒ [minX: number, minY: number, maxX: number, maxY: number]
+# **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).
diff --git a/dist/index.js b/dist/index.js
index cdb2933..e9821e4 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -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];
}
diff --git a/lib/index.template.ts b/lib/index.template.ts
index 0815b77..0450bf8 100644
--- a/lib/index.template.ts
+++ b/lib/index.template.ts
@@ -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];
}
diff --git a/package-lock.json b/package-lock.json
index bb463a3..f81a1a9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "svg-path-bbox",
- "version": "1.2.4",
+ "version": "1.2.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "svg-path-bbox",
- "version": "1.2.4",
+ "version": "1.2.5",
"license": "BSD-3-Clause",
"dependencies": {
"svgpath": "^2.2.0"
@@ -26,7 +26,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",
@@ -4521,15 +4521,15 @@
}
},
"node_modules/husky": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz",
- "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==",
+ "version": "9.0.11",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
+ "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
"dev": true,
"bin": {
- "husky": "lib/bin.js"
+ "husky": "bin.mjs"
},
"engines": {
- "node": ">=14"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/typicode"
@@ -12686,9 +12686,9 @@
"dev": true
},
"husky": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz",
- "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==",
+ "version": "9.0.11",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
+ "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
"dev": true
},
"ieee754": {
diff --git a/package.json b/package.json
index f7d785d..b2bed13 100644
--- a/package.json
+++ b/package.json
@@ -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",
@@ -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",
@@ -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",
diff --git a/src/index.ts b/src/index.ts
index 865bdfb..b5164e3 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -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];
}
diff --git a/tests/cases/bbox.ts b/tests/cases/bbox.ts
index 1680816..e20f340 100644
--- a/tests/cases/bbox.ts
+++ b/tests/cases/bbox.ts
@@ -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 ]
],
[
@@ -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 ]
],
[
@@ -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];