Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert lines home to z #1821

Closed
KTibow opened this issue Nov 5, 2023 · 0 comments · Fixed by #1822
Closed

Convert lines home to z #1821

KTibow opened this issue Nov 5, 2023 · 0 comments · Fixed by #1822

Comments

@KTibow
Copy link
Contributor

KTibow commented Nov 5, 2023

Paths like m 0 0 h 5 v 5 h -5 v -5 should be converted to m 0 0 h 5 v 5 h -5 z for better minification. That is, convert the line home to z.
(To follow up on that, you could also convert m 0 0 a 2.5 2.5 0 0 0 0 5 a 2.5 2.5 0 0 0 0 -5 z to m 0 0 a 2.5 2.5 0 0 0 0 5 a 2.5 2.5 0 0 0 0 -5. That is, remove a redundant z.)

I already made a plugin that does the first one, but it should probably be rewritten to fit in to the existing path transformer better. And the second one requires disabling on stroke. Anyway, code of the plugin, in case it helps:

	const processPath: Visitor = {
		element: {
			enter(element) {
				const path =
					'pathJS' in element && (element.pathJS as PathDataItem[]);
				if (!path) return;

				const start = [0, 0];
				const cursor = [0, 0];

				for (let i = 0; i < path.length; i += 1) {
					const pathItem = path[i];
					const { command, args } = pathItem;

					// moveto (x y)
					if (command === 'm') {
						cursor[0] += args[0];
						cursor[1] += args[1];
						start[0] = cursor[0];
						start[1] = cursor[1];
					}
					if (command === 'M') {
						cursor[0] = args[0];
						cursor[1] = args[1];
						start[0] = cursor[0];
						start[1] = cursor[1];
					}

					// lineto (x y)
					if (command === 'l') {
						cursor[0] += args[0];
						cursor[1] += args[1];
					}
					if (command === 'L') {
						cursor[0] = args[0];
						cursor[1] = args[1];
					}

					// horizontal lineto (x)
					if (command === 'h') {
						cursor[0] += args[0];
					}
					if (command === 'H') {
						cursor[0] = args[0];
					}

					// vertical lineto (y)
					if (command === 'v') {
						cursor[1] += args[0];
					}
					if (command === 'V') {
						cursor[1] = args[0];
					}

					if (['l', 'L', 'h', 'H', 'v', 'V'].includes(command)) { // !! the part that does stuff
						if (start[0] == cursor[0] && start[1] == cursor[1])
							path[i] = { command: 'z', args: [] };
					}

					// curveto (x1 y1 x2 y2 x y)
					if (command === 'c') {
						cursor[0] += args[4];
						cursor[1] += args[5];
					}
					if (command === 'C') {
						cursor[0] = args[4];
						cursor[1] = args[5];
					}

					// smooth curveto (x2 y2 x y)
					if (command === 's') {
						cursor[0] += args[2];
						cursor[1] += args[3];
					}
					if (command === 'S') {
						cursor[0] = args[2];
						cursor[1] = args[3];
					}

					// quadratic Bézier curveto (x1 y1 x y)
					if (command === 'q') {
						cursor[0] += args[2];
						cursor[1] += args[3];
					}
					if (command === 'Q') {
						cursor[0] = args[2];
						cursor[1] = args[3];
					}

					// smooth quadratic Bézier curveto (x y)
					if (command === 't') {
						cursor[0] += args[0];
						cursor[1] += args[1];
					}
					if (command === 'T') {
						cursor[0] = args[0];
						cursor[1] = args[1];
					}

					// elliptical arc (rx ry x-axis-rotation large-arc-flag sweep-flag x y)
					if (command === 'a') {
						cursor[0] += args[5];
						cursor[1] += args[6];
					}
					if (command === 'A') {
						cursor[0] = args[5];
						cursor[1] = args[6];
					}

					// closepath
					if (command === 'Z' || command === 'z') {
						// reset cursor
						cursor[0] = start[0];
						cursor[1] = start[1];
					}
				}
				element.attributes.d = stringifyPathData({
					pathData: path,
				});
			},
		},
	};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant