import { Point, SvgPath, SvgItem } from "./svg"; import { reversePath } from "./reverse-path"; const toStr = (pt: Point) => { return [String(pt.x), String(pt.y)]; }; const optimizeRelativeAbsolute = (svg: SvgPath) => { let length = svg.asString(4, true).length; const o = new Point(0,0); for(let i=0 ; i0 ? svg.path[i-1] : null; const comp = svg.path[i]; if(comp.getType(true) === 'Z') { continue; } comp.setRelative(!comp.relative); const newLength = svg.asString(4, true).length; if(newLength < length) { length = newLength; comp.refresh(o, previous); } else { comp.setRelative(!comp.relative); } } } export const optimizePath = (svg: SvgPath, { removeUselessCommands = false, removeOrphanDots = false, useShorthands = false, useHorizontalAndVerticalLines = false, useRelativeAbsolute = false, useReverse = false, useClosePath = false, }: { removeUselessCommands?: boolean; removeOrphanDots? : boolean; // Can have an impact on stroked paths useShorthands?: boolean; useHorizontalAndVerticalLines?: boolean; useRelativeAbsolute?: boolean; useReverse?: boolean; useClosePath?: boolean; }) => { const path = svg.path; const o = new Point(0,0); let initialPt = new Point(0,0); for(let i=1 ; i0 && path[path.length - 1].getType(true) === 'M') { path.splice(path.length - 1, 1); } // With removeUselessCommands, links to previous items may become dirty: svg.refreshAbsolutePositions(); } if(useRelativeAbsolute) { optimizeRelativeAbsolute(svg); } if(useReverse) { const length = svg.asString(4, true).length; const nonReversed = svg.path; reversePath(svg); if(useRelativeAbsolute) { optimizeRelativeAbsolute(svg); } const afterLength = svg.asString(4, true).length; if(afterLength >= length) { svg.path = nonReversed; } } }