Skip to content

Commit 8644cf3

Browse files
authoredJan 1, 2024
feat(convertPathData): convert c to q (#1892)
1 parent 2661dac commit 8644cf3

File tree

5 files changed

+59
-1
lines changed

5 files changed

+59
-1
lines changed
 

‎docs/03-plugins/convert-path-data.mdx

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ svgo:
1515
straightCurves:
1616
description: If to convert curve commands that are effectively straight lines to line commands.
1717
default: true
18+
convertToQ:
19+
description: If to convert cubic beziers to quadratic beziers when they effectively are.
20+
default: true
1821
lineShorthands:
1922
description: If to convert regular lines to an explicit horizontal or vertical line where possible.
2023
default: true

‎plugins/convertPathData.js

+41
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ let arcTolerance;
3535
* tolerance: number,
3636
* },
3737
* straightCurves: boolean,
38+
* convertToQ: boolean,
3839
* lineShorthands: boolean,
3940
* convertToZ: boolean,
4041
* curveSmoothShorthands: boolean,
@@ -86,6 +87,7 @@ exports.fn = (root, params) => {
8687
tolerance: 0.5, // percentage of radius
8788
},
8889
straightCurves = true,
90+
convertToQ = true,
8991
lineShorthands = true,
9092
convertToZ = true,
9193
curveSmoothShorthands = true,
@@ -109,6 +111,7 @@ exports.fn = (root, params) => {
109111
applyTransformsStroked,
110112
makeArcs,
111113
straightCurves,
114+
convertToQ,
112115
lineShorthands,
113116
convertToZ,
114117
curveSmoothShorthands,
@@ -674,6 +677,44 @@ function filters(
674677
}
675678
}
676679

680+
// degree-lower c to q when possible
681+
// m 0 12 C 4 4 8 4 12 12 → M 0 12 Q 6 0 12 12
682+
if (params.convertToQ && command == 'c') {
683+
const x1 =
684+
// @ts-ignore
685+
0.75 * (item.base[0] + data[0]) - 0.25 * item.base[0];
686+
const x2 =
687+
// @ts-ignore
688+
0.75 * (item.base[0] + data[2]) - 0.25 * (item.base[0] + data[4]);
689+
if (Math.abs(x1 - x2) < error * 2) {
690+
const y1 =
691+
// @ts-ignore
692+
0.75 * (item.base[1] + data[1]) - 0.25 * item.base[1];
693+
const y2 =
694+
// @ts-ignore
695+
0.75 * (item.base[1] + data[3]) - 0.25 * (item.base[1] + data[5]);
696+
if (Math.abs(y1 - y2) < error * 2) {
697+
const newData = data.slice();
698+
newData.splice(
699+
0,
700+
4,
701+
// @ts-ignore
702+
x1 + x2 - item.base[0],
703+
// @ts-ignore
704+
y1 + y2 - item.base[1],
705+
);
706+
roundData(newData);
707+
const originalLength = cleanupOutData(data, params).length,
708+
newLength = cleanupOutData(newData, params).length;
709+
if (newLength < originalLength) {
710+
command = 'q';
711+
data = newData;
712+
if (next && next.command == 's') makeLonghand(next, data); // fix up next curve
713+
}
714+
}
715+
}
716+
}
717+
677718
// horizontal and vertical line shorthands
678719
// l 50 0 → h 50
679720
// l 0 50 → v 50

‎plugins/plugins-types.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type DefaultPlugins = {
4141
tolerance: number;
4242
};
4343
straightCurves?: boolean;
44+
convertToQ?: boolean;
4445
lineShorthands?: boolean;
4546
convertToZ?: boolean;
4647
curveSmoothShorthands?: boolean;

‎test/plugins/convertPathData.16.svg

+1-1
Loading

‎test/plugins/convertPathData.35.svg

+13
Loading

0 commit comments

Comments
 (0)
Please sign in to comment.