mirror of
https://github.com/simple-icons/simple-icons.git
synced 2025-01-05 01:20:39 +02:00
Lint collinear coordinates inside straight lines (#4589)
This commit is contained in:
parent
5b0d1d3e49
commit
45130ca86a
File diff suppressed because one or more lines are too long
110
.svglintrc.js
110
.svglintrc.js
@ -38,6 +38,14 @@ function removeLeadingZeros(number) {
|
||||
return number.toString().replace(/^(-?)(0)(\.?.+)/, '$1$3');
|
||||
}
|
||||
|
||||
/**
|
||||
* Given three points, returns if the middle one (x2, y2) is collinear
|
||||
* to the line formed by the two limit points.
|
||||
**/
|
||||
function collinear(x1, y1, x2, y2, x3, y3) {
|
||||
return (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) === 0;
|
||||
}
|
||||
|
||||
if (updateIgnoreFile) {
|
||||
process.on('exit', () => {
|
||||
// ensure object output order is consistent due to async svglint processing
|
||||
@ -300,6 +308,108 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
},
|
||||
function(reporter, $, ast) {
|
||||
reporter.name = "collinear-segments";
|
||||
|
||||
const iconPath = $.find("path").attr("d");
|
||||
if (!updateIgnoreFile && isIgnored(reporter.name, iconPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts collinear coordinates from SVG path straight lines
|
||||
* (does not extracts collinear coordinates from curves).
|
||||
**/
|
||||
const getCollinearSegments = (path) => {
|
||||
const { segments } = svgPath(path).unarc().unshort(),
|
||||
collinearSegments = [],
|
||||
straightLineCommands = 'HhVvLlMm',
|
||||
zCommands = 'Zz';
|
||||
let currLine = [],
|
||||
currAbsCoord = [undefined, undefined],
|
||||
_inStraightLine = false,
|
||||
_nextInStraightLine = false;
|
||||
|
||||
for (let s = 0; s < segments.length; s++) {
|
||||
let seg = segments[s],
|
||||
cmd = seg[0],
|
||||
nextCmd = s + 1 < segments.length ? segments[s + 1][0] : null;
|
||||
|
||||
if ('LM'.includes(cmd)) {
|
||||
currAbsCoord[0] = seg[1];
|
||||
currAbsCoord[1] = seg[2];
|
||||
} else if ('lm'.includes(cmd)) {
|
||||
currAbsCoord[0] = (!currAbsCoord[0] ? 0 : currAbsCoord[0]) + seg[1];
|
||||
currAbsCoord[1] = (!currAbsCoord[1] ? 0 : currAbsCoord[1]) + seg[2];
|
||||
} else if (cmd === 'H') {
|
||||
currAbsCoord[0] = seg[1];
|
||||
} else if (cmd === 'h') {
|
||||
currAbsCoord[0] = (!currAbsCoord[0] ? 0 : currAbsCoord[0]) + seg[1];
|
||||
} else if (cmd === 'V') {
|
||||
currAbsCoord[1] = seg[1];
|
||||
} else if (cmd === 'v') {
|
||||
currAbsCoord[1] = (!currAbsCoord[1] ? 0 : currAbsCoord[1]) + seg[1];
|
||||
} else if (cmd === 'C') {
|
||||
currAbsCoord[0] = seg[5];
|
||||
currAbsCoord[1] = seg[6];
|
||||
} else if (cmd === 'c') {
|
||||
currAbsCoord[0] = (!currAbsCoord[0] ? 0 : currAbsCoord[0]) + seg[5];
|
||||
currAbsCoord[1] = (!currAbsCoord[1] ? 0 : currAbsCoord[1]) + seg[6];
|
||||
} else if (cmd === 'Q') {
|
||||
currAbsCoord[0] = seg[3];
|
||||
currAbsCoord[1] = seg[4];
|
||||
} else if (cmd === 'q') {
|
||||
currAbsCoord[0] = (!currAbsCoord[0] ? 0 : currAbsCoord[0]) + seg[3];
|
||||
currAbsCoord[1] = (!currAbsCoord[1] ? 0 : currAbsCoord[1]) + seg[4];
|
||||
} else if (zCommands.includes(cmd)) {
|
||||
// Overlapping in Z should be handled in another rule
|
||||
currAbsCoord = [undefined, undefined];
|
||||
} else {
|
||||
throw new Error(`"${cmd}" command not handled`)
|
||||
}
|
||||
|
||||
_nextInStraightLine = straightLineCommands.includes(nextCmd);
|
||||
let _exitingStraightLine = (_inStraightLine && !_nextInStraightLine);
|
||||
_inStraightLine = straightLineCommands.includes(cmd);
|
||||
|
||||
if (_inStraightLine) {
|
||||
currLine.push([currAbsCoord[0], currAbsCoord[1]]);
|
||||
} else {
|
||||
if (_exitingStraightLine) {
|
||||
if (!zCommands.includes(cmd)) {
|
||||
currLine.push([currAbsCoord[0], currAbsCoord[1]]);
|
||||
}
|
||||
// Get collinear coordinates
|
||||
for (let p = 0; p < currLine.length; p++) {
|
||||
if (p === 0 || p === currLine.length - 1) {
|
||||
continue;
|
||||
}
|
||||
let _collinearCoord = collinear(currLine[p - 1][0],
|
||||
currLine[p - 1][1],
|
||||
currLine[p][0],
|
||||
currLine[p][1],
|
||||
currLine[p + 1][0],
|
||||
currLine[p + 1][1])
|
||||
if (_collinearCoord) {
|
||||
collinearSegments.push(segments[s - currLine.length + p + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
currLine = [];
|
||||
}
|
||||
}
|
||||
|
||||
return collinearSegments;
|
||||
}
|
||||
|
||||
getCollinearSegments(iconPath).forEach((segment) => {
|
||||
let segmentString = `${segment[0]}${segment[1]}`;
|
||||
if ('LlMm'.includes(segment[0])) {
|
||||
segmentString += ` ${segment[2]}`
|
||||
}
|
||||
reporter.error(`Collinear segment "${segmentString}" in path (should be removed)`);
|
||||
});
|
||||
},
|
||||
function(reporter, $, ast) {
|
||||
reporter.name = "extraneous";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user