mirror of
https://github.com/Mibew/simple-icons.git
synced 2025-03-21 21:51:24 +03: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');
|
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) {
|
if (updateIgnoreFile) {
|
||||||
process.on('exit', () => {
|
process.on('exit', () => {
|
||||||
// ensure object output order is consistent due to async svglint processing
|
// 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) {
|
function(reporter, $, ast) {
|
||||||
reporter.name = "extraneous";
|
reporter.name = "extraneous";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user