Skip to content

Commit

Permalink
feat(convertPathData): convert c to q (#1892)
Browse files Browse the repository at this point in the history
  • Loading branch information
KTibow authored Jan 1, 2024
1 parent 2661dac commit 8644cf3
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 1 deletion.
3 changes: 3 additions & 0 deletions docs/03-plugins/convert-path-data.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ svgo:
straightCurves:
description: If to convert curve commands that are effectively straight lines to line commands.
default: true
convertToQ:
description: If to convert cubic beziers to quadratic beziers when they effectively are.
default: true
lineShorthands:
description: If to convert regular lines to an explicit horizontal or vertical line where possible.
default: true
Expand Down
41 changes: 41 additions & 0 deletions plugins/convertPathData.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ let arcTolerance;
* tolerance: number,
* },
* straightCurves: boolean,
* convertToQ: boolean,
* lineShorthands: boolean,
* convertToZ: boolean,
* curveSmoothShorthands: boolean,
Expand Down Expand Up @@ -86,6 +87,7 @@ exports.fn = (root, params) => {
tolerance: 0.5, // percentage of radius
},
straightCurves = true,
convertToQ = true,
lineShorthands = true,
convertToZ = true,
curveSmoothShorthands = true,
Expand All @@ -109,6 +111,7 @@ exports.fn = (root, params) => {
applyTransformsStroked,
makeArcs,
straightCurves,
convertToQ,
lineShorthands,
convertToZ,
curveSmoothShorthands,
Expand Down Expand Up @@ -674,6 +677,44 @@ function filters(
}
}

// degree-lower c to q when possible
// m 0 12 C 4 4 8 4 12 12 → M 0 12 Q 6 0 12 12
if (params.convertToQ && command == 'c') {
const x1 =
// @ts-ignore
0.75 * (item.base[0] + data[0]) - 0.25 * item.base[0];
const x2 =
// @ts-ignore
0.75 * (item.base[0] + data[2]) - 0.25 * (item.base[0] + data[4]);
if (Math.abs(x1 - x2) < error * 2) {
const y1 =
// @ts-ignore
0.75 * (item.base[1] + data[1]) - 0.25 * item.base[1];
const y2 =
// @ts-ignore
0.75 * (item.base[1] + data[3]) - 0.25 * (item.base[1] + data[5]);
if (Math.abs(y1 - y2) < error * 2) {
const newData = data.slice();
newData.splice(
0,
4,
// @ts-ignore
x1 + x2 - item.base[0],
// @ts-ignore
y1 + y2 - item.base[1],
);
roundData(newData);
const originalLength = cleanupOutData(data, params).length,
newLength = cleanupOutData(newData, params).length;
if (newLength < originalLength) {
command = 'q';
data = newData;
if (next && next.command == 's') makeLonghand(next, data); // fix up next curve
}
}
}
}

// horizontal and vertical line shorthands
// l 50 0 → h 50
// l 0 50 → v 50
Expand Down
1 change: 1 addition & 0 deletions plugins/plugins-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type DefaultPlugins = {
tolerance: number;
};
straightCurves?: boolean;
convertToQ?: boolean;
lineShorthands?: boolean;
convertToZ?: boolean;
curveSmoothShorthands?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion test/plugins/convertPathData.16.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions test/plugins/convertPathData.35.svg
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 8644cf3

Please sign in to comment.