mirror of
				https://github.com/Mibew/simple-icons.git
				synced 2025-10-31 18:41:07 +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'); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * 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