Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@ivan-the-terrible
Copy link

@ivan-the-terrible ivan-the-terrible commented Feb 24, 2025

Bugs tackled:

  • Parsing units string for scaling
  • Division by Zero error when scaling

Transform_styles parsing issue

Within svg2mod > svg > svg.py | transform_styles function
Problem: Regex parsing doesn't capture full values
Solution: Expand the regex pattern using "+" to capture more than one value

has_units = re.search(r"\D",

re.search just matches the first character in the string and the \D will only catch the first non-digit.

Something like 1px will return p, which won't match the appropriate key in unit_convert.

image
I suspect this will resolve the posted Issue:
Path width export doesn't match Inkscape value · Issue #61 · svg2mod/svg2mod

The user reports an issue with scaling and in the post screenshot uses 'mm' (millimeters), which due to the re.search(r"\D" would not have gotten matched and scaled properly.

Additionally, the same problem occurs a few lines later here:

float(re.search(r"\d", self.style[style]).group())
* unit_convert.get(unit, 1)
* ((matrix.xscale() + matrix.yscale()) / 2)

re.search(r"\d", self.style[style]).group() to grab the digits in front of the unit would only grab the first value. If it was a two digit number, "22px" for example would only return 2 as the value.

So this calculation would subsequently be wrong due to the first line.

The solution was just to add the "+" metacharacter for the regex to match more characters:
\D+ and \d+ respectively.

Matrix xscale() and yscale() issues

Within svg2mod > svg > svg.py | xscale and yscale functions within Matrix class
Problem: ZeroDivisionError when denominator in formula is zero
Solution: Add an if check to return the default value in this case

def xscale(self):
	"""Return the rotated x scalar value"""
	return (
		self.vect[0]
		/ abs(self.vect[0])
		* math.sqrt(self.vect[0] ** 2 + self.vect[2] ** 2)
	)

def yscale(self):
	"""Return the rotated y scalar value"""
	return (
		self.vect[3]
		/ abs(self.vect[3])
		* math.sqrt(self.vect[1] ** 2 + self.vect[3] ** 2)
	)

The issue is immediately apparent: the denominator in the calculation can throw a ZeroDivisionError if not properly handled.

I've encountered the exact issue when attempting to add a path to my SVG that has been mirrored along the X-axis and Y-axis, thus inputting a matrix of [0.0, -1.0, -1.0, 0.0, 0.0, 0.0]
Pasted image 20250224115436

The solution was to simply add a check for this case. For example:
image
This is the formula for the logic and you can see that for the default case (where the identity matrix is used vect = [1, 0, 0, 1, 0, 0]) we pass a value of one in and get the positive value of c.

For more context to describe the problem,

The Inkscape SVG code is:

inkscape:label="whoami"
transform="matrix(0,-1,-1,0,0,0)"

matrix(a, b, c, d, e, f) is a way to represent a 2D transformation in SVG. Each parameter in the matrix plays a role in transforming the element.

  • a = 0: No horizontal scaling.
  • b = -1: Reflects over the x-axis and performs a 90-degree clockwise rotation.
  • c = -1: Reflects over the y-axis and performs a 90-degree counterclockwise rotation.
  • d = 0: No vertical scaling.
  • e = 0: No horizontal translation.
  • f = 0: No vertical translation.
class Matrix:
    """SVG transformation matrix and its operations
    a SVG matrix is represented as a list of 6 values [a, b, c, d, e, f]
    (named vect hereafter) which represent the 3x3 matrix
    ((a, c, e)
     (b, d, f)
     (0, 0, 1))
    see http://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace"""

This URL pointing to the W3 documentation isn't very helpful here.
The SVG documentation and definition for transform points to the CSS standard of the same thing:
Coordinate Systems, Transformations and Units — SVG 2
points to
CSS Transforms Module Level 1

These are pretty technical documents but do not concisely point out the implementation.
matrix() - CSS: Cascading Style Sheets | MDN
MDN has a clearer representation.

I suggest updating the docstring here to replace the last line to say:
SVGs implement the same transform that CSS does
see https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix#values

@Sodium-Hydrogen
Copy link
Member

Sodium-Hydrogen commented Feb 24, 2025

Looks good!

Thanks for catching the regex issue!

We can ignore the failed check. That is only for readme checking.

I do have one critique:

  • instead of returning default value of 1 can you update your pull request to return the absolute value of the c value for xscale and b for yscale?

Thanks for contributing to this project.

@ivan-the-terrible
Copy link
Author

Happy to contribute! I've been using svg2mod for quite a bit and really love the tool.

Good catch on the logic. I should have written the math out to see that ultimately the default case outputs what you said.
I've updated the PR description to fix the logic and committed the changes.

@Sodium-Hydrogen Sodium-Hydrogen merged commit db0ecfe into svg2mod:main Feb 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants