- added support for virtual units in SVG parser; warning: it may require the support for units which is not implemented yet
This commit is contained in:
@@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta
|
|||||||
|
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
|
23.09.2020
|
||||||
|
|
||||||
|
- added support for virtual units in SVG parser; warning: it may require the support for units which is not implemented yet
|
||||||
|
|
||||||
22.09.2020
|
22.09.2020
|
||||||
|
|
||||||
- fixed an error in importing SVG that has a single line
|
- fixed an error in importing SVG that has a single line
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from lxml import etree as ET
|
|||||||
import ezdxf
|
import ezdxf
|
||||||
|
|
||||||
from appParsers.ParseDXF import *
|
from appParsers.ParseDXF import *
|
||||||
from appParsers.ParseSVG import svgparselength, getsvggeo
|
from appParsers.ParseSVG import svgparselength, getsvggeo, svgparse_viewbox
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
import builtins
|
import builtins
|
||||||
@@ -1812,7 +1812,8 @@ class Gerber(Geometry):
|
|||||||
|
|
||||||
units = self.app.defaults['units'] if units is None else units
|
units = self.app.defaults['units'] if units is None else units
|
||||||
res = self.app.defaults['gerber_circle_steps']
|
res = self.app.defaults['gerber_circle_steps']
|
||||||
geos = getsvggeo(svg_root, 'gerber', units=units, res=res)
|
factor = svgparse_viewbox(svg_root)
|
||||||
|
geos = getsvggeo(svg_root, 'gerber', units=units, res=res, factor=factor)
|
||||||
if flip:
|
if flip:
|
||||||
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ def svgparse_viewbox(root):
|
|||||||
return w / v_w
|
return w / v_w
|
||||||
|
|
||||||
|
|
||||||
def path2shapely(path, object_type, res=1.0, units='MM'):
|
def path2shapely(path, object_type, res=1.0, units='MM', factor=1.0):
|
||||||
"""
|
"""
|
||||||
Converts an svg.path.Path into a Shapely
|
Converts an svg.path.Path into a Shapely
|
||||||
Polygon or LinearString.
|
Polygon or LinearString.
|
||||||
@@ -83,6 +83,8 @@ def path2shapely(path, object_type, res=1.0, units='MM'):
|
|||||||
:param res: Resolution (minimum step along path)
|
:param res: Resolution (minimum step along path)
|
||||||
:param units: FlatCAM units
|
:param units: FlatCAM units
|
||||||
:type units: str
|
:type units: str
|
||||||
|
:param factor: correction factor due of virtual units
|
||||||
|
:type factor: float
|
||||||
:return: Shapely geometry object
|
:return: Shapely geometry object
|
||||||
:rtype : Polygon
|
:rtype : Polygon
|
||||||
:rtype : LineString
|
:rtype : LineString
|
||||||
@@ -102,7 +104,7 @@ def path2shapely(path, object_type, res=1.0, units='MM'):
|
|||||||
if len(points) == 0 or points[-1] != (x, y):
|
if len(points) == 0 or points[-1] != (x, y):
|
||||||
points.append((x, y))
|
points.append((x, y))
|
||||||
end = component.end
|
end = component.end
|
||||||
points.append((end.real, end.imag))
|
points.append((factor * end.real, factor * end.imag))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Arc, CubicBezier or QuadraticBezier
|
# Arc, CubicBezier or QuadraticBezier
|
||||||
@@ -131,9 +133,9 @@ def path2shapely(path, object_type, res=1.0, units='MM'):
|
|||||||
point = component.point(i * frac)
|
point = component.point(i * frac)
|
||||||
x, y = point.real, point.imag
|
x, y = point.real, point.imag
|
||||||
if len(points) == 0 or points[-1] != (x, y):
|
if len(points) == 0 or points[-1] != (x, y):
|
||||||
points.append((x, y))
|
points.append((factor * x, factor * y))
|
||||||
end = component.point(1.0)
|
end = component.point(1.0)
|
||||||
points.append((end.real, end.imag))
|
points.append((factor * end.real, factor * end.imag))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Move
|
# Move
|
||||||
@@ -148,7 +150,7 @@ def path2shapely(path, object_type, res=1.0, units='MM'):
|
|||||||
closed = False
|
closed = False
|
||||||
start = component.start
|
start = component.start
|
||||||
x, y = start.real, start.imag
|
x, y = start.real, start.imag
|
||||||
points = [(x, y)]
|
points = [(factor * x, factor * y)]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
closed = False
|
closed = False
|
||||||
@@ -169,6 +171,7 @@ def path2shapely(path, object_type, res=1.0, units='MM'):
|
|||||||
|
|
||||||
if points:
|
if points:
|
||||||
rings.append(points)
|
rings.append(points)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rings = MultiLineString(rings)
|
rings = MultiLineString(rings)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -198,7 +201,7 @@ def path2shapely(path, object_type, res=1.0, units='MM'):
|
|||||||
return geometry
|
return geometry
|
||||||
|
|
||||||
|
|
||||||
def svgrect2shapely(rect, n_points=32):
|
def svgrect2shapely(rect, n_points=32, factor=1.0):
|
||||||
"""
|
"""
|
||||||
Converts an SVG rect into Shapely geometry.
|
Converts an SVG rect into Shapely geometry.
|
||||||
|
|
||||||
@@ -206,22 +209,27 @@ def svgrect2shapely(rect, n_points=32):
|
|||||||
:type rect: xml.etree.ElementTree.Element
|
:type rect: xml.etree.ElementTree.Element
|
||||||
:param n_points: number of points to approximate rectangles corners when having rounded corners
|
:param n_points: number of points to approximate rectangles corners when having rounded corners
|
||||||
:type n_points: int
|
:type n_points: int
|
||||||
|
:param factor: correction factor due of virtual units
|
||||||
|
:type factor: float
|
||||||
:return: shapely.geometry.polygon.LinearRing
|
:return: shapely.geometry.polygon.LinearRing
|
||||||
"""
|
"""
|
||||||
w = svgparselength(rect.get('width'))[0]
|
w = svgparselength(rect.get('width'))[0]
|
||||||
h = svgparselength(rect.get('height'))[0]
|
h = svgparselength(rect.get('height'))[0]
|
||||||
|
|
||||||
x_obj = rect.get('x')
|
x_obj = rect.get('x')
|
||||||
if x_obj is not None:
|
if x_obj is not None:
|
||||||
x = svgparselength(x_obj)[0]
|
x = svgparselength(x_obj)[0] * factor
|
||||||
else:
|
else:
|
||||||
x = 0
|
x = 0
|
||||||
|
|
||||||
y_obj = rect.get('y')
|
y_obj = rect.get('y')
|
||||||
if y_obj is not None:
|
if y_obj is not None:
|
||||||
y = svgparselength(y_obj)[0]
|
y = svgparselength(y_obj)[0] * factor
|
||||||
else:
|
else:
|
||||||
y = 0
|
y = 0
|
||||||
rxstr = rect.get('rx')
|
|
||||||
rystr = rect.get('ry')
|
rxstr = rect.get('rx') * factor
|
||||||
|
rystr = rect.get('ry') * factor
|
||||||
|
|
||||||
if rxstr is None and rystr is None: # Sharp corners
|
if rxstr is None and rystr is None: # Sharp corners
|
||||||
pts = [
|
pts = [
|
||||||
@@ -268,7 +276,7 @@ def svgrect2shapely(rect, n_points=32):
|
|||||||
# return LinearRing(pts)
|
# return LinearRing(pts)
|
||||||
|
|
||||||
|
|
||||||
def svgcircle2shapely(circle, n_points=64):
|
def svgcircle2shapely(circle, n_points=64, factor=1.0):
|
||||||
"""
|
"""
|
||||||
Converts an SVG circle into Shapely geometry.
|
Converts an SVG circle into Shapely geometry.
|
||||||
|
|
||||||
@@ -282,29 +290,30 @@ def svgcircle2shapely(circle, n_points=64):
|
|||||||
# cx = float(circle.get('cx'))
|
# cx = float(circle.get('cx'))
|
||||||
# cy = float(circle.get('cy'))
|
# cy = float(circle.get('cy'))
|
||||||
# r = float(circle.get('r'))
|
# r = float(circle.get('r'))
|
||||||
cx = svgparselength(circle.get('cx'))[0] # TODO: No units support yet
|
cx = svgparselength(circle.get('cx'))[0] * factor # TODO: No units support yet
|
||||||
cy = svgparselength(circle.get('cy'))[0] # TODO: No units support yet
|
cy = svgparselength(circle.get('cy'))[0] * factor # TODO: No units support yet
|
||||||
r = svgparselength(circle.get('r'))[0] # TODO: No units support yet
|
r = svgparselength(circle.get('r'))[0] * factor # TODO: No units support yet
|
||||||
|
|
||||||
return Point(cx, cy).buffer(r, resolution=n_points)
|
return Point(cx, cy).buffer(r, resolution=n_points)
|
||||||
|
|
||||||
|
|
||||||
def svgellipse2shapely(ellipse, n_points=64):
|
def svgellipse2shapely(ellipse, n_points=64, factor=1.0):
|
||||||
"""
|
"""
|
||||||
Converts an SVG ellipse into Shapely geometry
|
Converts an SVG ellipse into Shapely geometry
|
||||||
|
|
||||||
:param ellipse: Ellipse Element
|
:param ellipse: Ellipse Element
|
||||||
:type ellipse: xml.etree.ElementTree.Element
|
:type ellipse: xml.etree.ElementTree.Element
|
||||||
:param n_points: Number of discrete points in output.
|
:param n_points: Number of discrete points in output.
|
||||||
:return: Shapely representation of the ellipse.
|
:type n_points: int
|
||||||
:rtype: shapely.geometry.polygon.LinearRing
|
:return: Shapely representation of the ellipse.
|
||||||
|
:rtype: shapely.geometry.polygon.LinearRing
|
||||||
"""
|
"""
|
||||||
|
|
||||||
cx = svgparselength(ellipse.get('cx'))[0] # TODO: No units support yet
|
cx = svgparselength(ellipse.get('cx'))[0] * factor # TODO: No units support yet
|
||||||
cy = svgparselength(ellipse.get('cy'))[0] # TODO: No units support yet
|
cy = svgparselength(ellipse.get('cy'))[0] * factor # TODO: No units support yet
|
||||||
|
|
||||||
rx = svgparselength(ellipse.get('rx'))[0] # TODO: No units support yet
|
rx = svgparselength(ellipse.get('rx'))[0] * factor # TODO: No units support yet
|
||||||
ry = svgparselength(ellipse.get('ry'))[0] # TODO: No units support yet
|
ry = svgparselength(ellipse.get('ry'))[0] * factor # TODO: No units support yet
|
||||||
|
|
||||||
t = np.arange(n_points, dtype=float) / n_points
|
t = np.arange(n_points, dtype=float) / n_points
|
||||||
x = cx + rx * np.cos(2 * np.pi * t)
|
x = cx + rx * np.cos(2 * np.pi * t)
|
||||||
@@ -315,32 +324,43 @@ def svgellipse2shapely(ellipse, n_points=64):
|
|||||||
# return LinearRing(pts)
|
# return LinearRing(pts)
|
||||||
|
|
||||||
|
|
||||||
def svgline2shapely(line):
|
def svgline2shapely(line, factor=1.0):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param line: Line element
|
:param line: Line element
|
||||||
:type line: xml.etree.ElementTree.Element
|
:type line: xml.etree.ElementTree.Element
|
||||||
:return: Shapely representation on the line.
|
:param factor: correction factor due of virtual units
|
||||||
:rtype: shapely.geometry.polygon.LinearRing
|
:type factor: float
|
||||||
|
:return: Shapely representation on the line.
|
||||||
|
:rtype: shapely.geometry.polygon.LineString
|
||||||
"""
|
"""
|
||||||
|
|
||||||
x1 = svgparselength(line.get('x1'))[0]
|
x1 = svgparselength(line.get('x1'))[0] * factor
|
||||||
y1 = svgparselength(line.get('y1'))[0]
|
y1 = svgparselength(line.get('y1'))[0] * factor
|
||||||
x2 = svgparselength(line.get('x2'))[0]
|
x2 = svgparselength(line.get('x2'))[0] * factor
|
||||||
y2 = svgparselength(line.get('y2'))[0]
|
y2 = svgparselength(line.get('y2'))[0] * factor
|
||||||
|
|
||||||
return LineString([(x1, y1), (x2, y2)])
|
return LineString([(x1, y1), (x2, y2)])
|
||||||
|
|
||||||
|
|
||||||
def svgpolyline2shapely(polyline):
|
def svgpolyline2shapely(polyline, factor=1.0):
|
||||||
|
"""
|
||||||
|
|
||||||
|
:param polyline: Polyline element
|
||||||
|
:type polyline: xml.etree.ElementTree.Element
|
||||||
|
:param factor: correction factor due of virtual units
|
||||||
|
:type factor: float
|
||||||
|
:return: Shapely representation of the PolyLine
|
||||||
|
:rtype: shapely.geometry.polygon.LineString
|
||||||
|
"""
|
||||||
|
|
||||||
ptliststr = polyline.get('points')
|
ptliststr = polyline.get('points')
|
||||||
points = parse_svg_point_list(ptliststr)
|
points = parse_svg_point_list(ptliststr, factor)
|
||||||
|
|
||||||
return LineString(points)
|
return LineString(points)
|
||||||
|
|
||||||
|
|
||||||
def svgpolygon2shapely(polygon, n_points=64):
|
def svgpolygon2shapely(polygon, n_points=64, factor=1.0):
|
||||||
"""
|
"""
|
||||||
Convert a SVG polygon to a Shapely Polygon.
|
Convert a SVG polygon to a Shapely Polygon.
|
||||||
|
|
||||||
@@ -348,17 +368,19 @@ def svgpolygon2shapely(polygon, n_points=64):
|
|||||||
:type polygon:
|
:type polygon:
|
||||||
:param n_points: circle resolution; nr of points to b e used to approximate a circle
|
:param n_points: circle resolution; nr of points to b e used to approximate a circle
|
||||||
:type n_points: int
|
:type n_points: int
|
||||||
|
:param factor: correction factor due of virtual units
|
||||||
|
:type factor: float
|
||||||
:return: Shapely Polygon
|
:return: Shapely Polygon
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ptliststr = polygon.get('points')
|
ptliststr = polygon.get('points')
|
||||||
points = parse_svg_point_list(ptliststr)
|
points = parse_svg_point_list(ptliststr, factor)
|
||||||
|
|
||||||
return Polygon(points).buffer(0, resolution=n_points)
|
return Polygon(points).buffer(0, resolution=n_points)
|
||||||
# return LinearRing(points)
|
# return LinearRing(points)
|
||||||
|
|
||||||
|
|
||||||
def getsvggeo(node, object_type, root=None, units='MM', res=64):
|
def getsvggeo(node, object_type, root=None, units='MM', res=64, factor=1.0):
|
||||||
"""
|
"""
|
||||||
Extracts and flattens all geometry from an SVG node
|
Extracts and flattens all geometry from an SVG node
|
||||||
into a list of Shapely geometry.
|
into a list of Shapely geometry.
|
||||||
@@ -367,8 +389,9 @@ def getsvggeo(node, object_type, root=None, units='MM', res=64):
|
|||||||
:param object_type:
|
:param object_type:
|
||||||
:param root:
|
:param root:
|
||||||
:param units: FlatCAM units
|
:param units: FlatCAM units
|
||||||
:param res: resolution to be used for circles bufferring
|
:param res: resolution to be used for circles buffering
|
||||||
|
:param factor: correction factor due of virtual units
|
||||||
|
:type factor: float
|
||||||
:return: List of Shapely geometry
|
:return: List of Shapely geometry
|
||||||
:rtype: list
|
:rtype: list
|
||||||
"""
|
"""
|
||||||
@@ -381,61 +404,59 @@ def getsvggeo(node, object_type, root=None, units='MM', res=64):
|
|||||||
# Recurse
|
# Recurse
|
||||||
if len(node) > 0:
|
if len(node) > 0:
|
||||||
for child in node:
|
for child in node:
|
||||||
subgeo = getsvggeo(child, object_type, root=root, units=units, res=res)
|
subgeo = getsvggeo(child, object_type, root=root, units=units, res=res, factor=factor)
|
||||||
if subgeo is not None:
|
if subgeo is not None:
|
||||||
geo += subgeo
|
geo += subgeo
|
||||||
|
# Parse
|
||||||
|
elif kind == 'path':
|
||||||
|
log.debug("***PATH***")
|
||||||
|
P = parse_path(node.get('d'))
|
||||||
|
P = path2shapely(P, object_type, units=units, factor=factor)
|
||||||
|
# for path, the resulting geometry is already a list so no need to create a new one
|
||||||
|
geo = P
|
||||||
|
|
||||||
|
elif kind == 'rect':
|
||||||
|
log.debug("***RECT***")
|
||||||
|
R = svgrect2shapely(node, n_points=res, factor=factor)
|
||||||
|
geo = [R]
|
||||||
|
|
||||||
|
elif kind == 'circle':
|
||||||
|
log.debug("***CIRCLE***")
|
||||||
|
C = svgcircle2shapely(node, n_points=res, factor=factor)
|
||||||
|
geo = [C]
|
||||||
|
|
||||||
|
elif kind == 'ellipse':
|
||||||
|
log.debug("***ELLIPSE***")
|
||||||
|
E = svgellipse2shapely(node, n_points=res, factor=factor)
|
||||||
|
geo = [E]
|
||||||
|
|
||||||
|
elif kind == 'polygon':
|
||||||
|
log.debug("***POLYGON***")
|
||||||
|
poly = svgpolygon2shapely(node, n_points=res, factor=factor)
|
||||||
|
geo = [poly]
|
||||||
|
|
||||||
|
elif kind == 'line':
|
||||||
|
log.debug("***LINE***")
|
||||||
|
line = svgline2shapely(node, factor=factor)
|
||||||
|
geo = [line]
|
||||||
|
|
||||||
|
elif kind == 'polyline':
|
||||||
|
log.debug("***POLYLINE***")
|
||||||
|
pline = svgpolyline2shapely(node, factor=factor)
|
||||||
|
geo = [pline]
|
||||||
|
|
||||||
|
elif kind == 'use':
|
||||||
|
log.debug('***USE***')
|
||||||
|
# href= is the preferred name for this[1], but inkscape still generates xlink:href=.
|
||||||
|
# [1] https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use#Attributes
|
||||||
|
href = node.attrib['href'] if 'href' in node.attrib else node.attrib['{http://www.w3.org/1999/xlink}href']
|
||||||
|
ref = root.find(".//*[@id='%s']" % href.replace('#', ''))
|
||||||
|
if ref is not None:
|
||||||
|
geo = getsvggeo(ref, object_type, root=root, units=units, res=res, factor=factor)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
factor = svgparse_viewbox(node)
|
log.warning("Unknown kind: " + kind)
|
||||||
# Parse
|
geo = None
|
||||||
if kind == 'path':
|
|
||||||
log.debug("***PATH***")
|
|
||||||
P = parse_path(node.get('d'))
|
|
||||||
P = path2shapely(P, object_type, units=units)
|
|
||||||
# for path, the resulting geometry is already a list so no need to create a new one
|
|
||||||
geo = P
|
|
||||||
|
|
||||||
elif kind == 'rect':
|
|
||||||
log.debug("***RECT***")
|
|
||||||
R = svgrect2shapely(node, n_points=res)
|
|
||||||
geo = [R]
|
|
||||||
|
|
||||||
elif kind == 'circle':
|
|
||||||
log.debug("***CIRCLE***")
|
|
||||||
C = svgcircle2shapely(node, n_points=res)
|
|
||||||
geo = [C]
|
|
||||||
|
|
||||||
elif kind == 'ellipse':
|
|
||||||
log.debug("***ELLIPSE***")
|
|
||||||
E = svgellipse2shapely(node, n_points=res)
|
|
||||||
geo = [E]
|
|
||||||
|
|
||||||
elif kind == 'polygon':
|
|
||||||
log.debug("***POLYGON***")
|
|
||||||
poly = svgpolygon2shapely(node, n_points=res)
|
|
||||||
geo = [poly]
|
|
||||||
|
|
||||||
elif kind == 'line':
|
|
||||||
log.debug("***LINE***")
|
|
||||||
line = svgline2shapely(node)
|
|
||||||
geo = [line]
|
|
||||||
|
|
||||||
elif kind == 'polyline':
|
|
||||||
log.debug("***POLYLINE***")
|
|
||||||
pline = svgpolyline2shapely(node)
|
|
||||||
geo = [pline]
|
|
||||||
|
|
||||||
elif kind == 'use':
|
|
||||||
log.debug('***USE***')
|
|
||||||
# href= is the preferred name for this[1], but inkscape still generates xlink:href=.
|
|
||||||
# [1] https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use#Attributes
|
|
||||||
href = node.attrib['href'] if 'href' in node.attrib else node.attrib['{http://www.w3.org/1999/xlink}href']
|
|
||||||
ref = root.find(".//*[@id='%s']" % href.replace('#', ''))
|
|
||||||
if ref is not None:
|
|
||||||
geo = getsvggeo(ref, object_type, root=root, units=units, res=res)
|
|
||||||
|
|
||||||
else:
|
|
||||||
log.warning("Unknown kind: " + kind)
|
|
||||||
geo = None
|
|
||||||
|
|
||||||
# ignore transformation for unknown kind
|
# ignore transformation for unknown kind
|
||||||
if geo is not None:
|
if geo is not None:
|
||||||
@@ -565,13 +586,15 @@ def getsvgtext(node, object_type, units='MM'):
|
|||||||
return geo
|
return geo
|
||||||
|
|
||||||
|
|
||||||
def parse_svg_point_list(ptliststr):
|
def parse_svg_point_list(ptliststr, factor):
|
||||||
"""
|
"""
|
||||||
Returns a list of coordinate pairs extracted from the "points"
|
Returns a list of coordinate pairs extracted from the "points"
|
||||||
attribute in SVG polygons and polyline's.
|
attribute in SVG polygons and polyline's.
|
||||||
|
|
||||||
:param ptliststr: "points" attribute string in polygon or polyline.
|
:param ptliststr: "points" attribute string in polygon or polyline.
|
||||||
:return: List of tuples with coordinates.
|
:param factor: correction factor due of virtual units
|
||||||
|
:type factor: float
|
||||||
|
:return: List of tuples with coordinates.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pairs = []
|
pairs = []
|
||||||
@@ -584,9 +607,9 @@ def parse_svg_point_list(ptliststr):
|
|||||||
val = float(ptliststr[pos:match.start()])
|
val = float(ptliststr[pos:match.start()])
|
||||||
|
|
||||||
if i % 2 == 1:
|
if i % 2 == 1:
|
||||||
pairs.append((last, val))
|
pairs.append((factor * last, factor * val))
|
||||||
else:
|
else:
|
||||||
last = val
|
last = val * factor
|
||||||
|
|
||||||
pos = match.end()
|
pos = match.end()
|
||||||
i += 1
|
i += 1
|
||||||
@@ -594,7 +617,7 @@ def parse_svg_point_list(ptliststr):
|
|||||||
# Check for last element
|
# Check for last element
|
||||||
val = float(ptliststr[pos:])
|
val = float(ptliststr[pos:])
|
||||||
if i % 2 == 1:
|
if i % 2 == 1:
|
||||||
pairs.append((last, val))
|
pairs.append((factor * last, factor * val))
|
||||||
else:
|
else:
|
||||||
log.warning("Incomplete coordinates.")
|
log.warning("Incomplete coordinates.")
|
||||||
|
|
||||||
|
|||||||
@@ -429,7 +429,9 @@ class QRCode(AppTool):
|
|||||||
h = svgparselength(svg_root.get('height'))[0] # TODO: No units support yet
|
h = svgparselength(svg_root.get('height'))[0] # TODO: No units support yet
|
||||||
units = self.app.defaults['units'] if units is None else units
|
units = self.app.defaults['units'] if units is None else units
|
||||||
res = self.app.defaults['geometry_circle_steps']
|
res = self.app.defaults['geometry_circle_steps']
|
||||||
geos = getsvggeo(svg_root, object_type, units=units, res=res)
|
factor = svgparse_viewbox(svg_root)
|
||||||
|
|
||||||
|
geos = getsvggeo(svg_root, object_type, units=units, res=res, factor=factor)
|
||||||
|
|
||||||
if flip:
|
if flip:
|
||||||
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
||||||
|
|||||||
@@ -1116,7 +1116,9 @@ class Geometry(object):
|
|||||||
|
|
||||||
units = self.app.defaults['units'] if units is None else units
|
units = self.app.defaults['units'] if units is None else units
|
||||||
res = self.app.defaults['geometry_circle_steps']
|
res = self.app.defaults['geometry_circle_steps']
|
||||||
geos = getsvggeo(svg_root, object_type, units=units, res=res)
|
factor = svgparse_viewbox(svg_root)
|
||||||
|
|
||||||
|
geos = getsvggeo(svg_root, object_type, units=units, res=res, factor=factor)
|
||||||
if flip:
|
if flip:
|
||||||
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
geos = [translate(scale(g, 1.0, -1.0, origin=(0, 0)), yoff=h) for g in geos]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user