Skip to content

Commit 5b17439

Browse files
committed
handle preserveAspectRatio
1 parent f35eb53 commit 5b17439

File tree

1 file changed

+51
-13
lines changed

1 file changed

+51
-13
lines changed

svgpath/parser.py

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ def rgbFromColor(colorName):
432432
return SVG_COLORS[colorName]
433433

434434

435-
def getPathsFromSVG(svg,yGrowsUp=True):
435+
def getPathsFromSVG(svg):
436436
def updateStateCommand(state,cmd,arg):
437437
if cmd == 'fill':
438438
state.fill = rgbFromColor(arg)
@@ -611,10 +611,7 @@ def getFloat(attribute,default=0.):
611611

612612
def scale(width, height, viewBox, z):
613613
x = (z.real - viewBox[0]) / (viewBox[2] - viewBox[0]) * width
614-
if yGrowsUp:
615-
y = (viewBox[3]-z.imag) / (viewBox[3] - viewBox[1]) * height
616-
else:
617-
y = (z.imag - viewBox[1]) / (viewBox[3] - viewBox[1]) * height
614+
y = (viewBox[3]-z.imag) / (viewBox[3] - viewBox[1]) * height
618615
return complex(x,y)
619616

620617
paths = []
@@ -641,20 +638,61 @@ def scale(width, height, viewBox, z):
641638
if height is None:
642639
height = viewBox[3] * 25.4/96
643640

641+
viewBoxWidth = viewBox[2]
642+
viewBoxHeight = viewBox[3]
643+
644644
viewBox[2] += viewBox[0]
645645
viewBox[3] += viewBox[1]
646646

647-
matrix = [ width/(viewBox[2]-viewBox[0]), 0, -viewBox[0]* width/(viewBox[2]-viewBox[0]), 0 ]
648-
if yGrowsUp:
649-
matrix += [-height/(viewBox[3]-viewBox[1]), viewBox[3]*height/(viewBox[3]-viewBox[1]) ]
650-
else:
651-
matrix += [height/(viewBox[3]-viewBox[1]), -viewBox[1]*height/(viewBox[3]-viewBox[1]) ]
652-
647+
try:
648+
preserve = svg.attrib['preserveAspectRatio'].strip().lower().split()
649+
if len(preserve[0]) != 8:
650+
raise KeyError
651+
if len(preserve)>=2 and preserve[1] == 'slice':
652+
if viewBoxWidth/viewBoxHeight > width/height:
653+
# viewbox is wider than viewport, so scale by height to ensure
654+
# viewbox covers the viewport
655+
rescale = height / viewBoxHeight
656+
else:
657+
rescale = width / viewBoxWidth
658+
else:
659+
if viewBoxWidth/viewBoxHeight > width/height:
660+
# viewbox is wider than viewport, so scale by width to ensure
661+
# viewport covers the viewbox
662+
rescale = width / viewBoxWidth
663+
else:
664+
rescale = height / viewBoxHeight
665+
matrix = [rescale, 0, 0,
666+
0, rescale, 0];
667+
668+
if preserve[0][0:4] == 'xmin':
669+
# viewBox[0] to 0
670+
matrix[2] = -viewBox[0] * rescale
671+
elif preserve[0][0:4] == 'xmid':
672+
# viewBox[0] to width/2
673+
matrix[2] = -viewBox[0] * rescale + width/2
674+
else: # preserve[0][0:4] == 'xmax':
675+
# viewBox[0] to width
676+
matrix[2] = -viewBox[0] * rescale + width
677+
678+
if preserve[0][4:8] == 'ymin':
679+
# viewBox[1] to 0
680+
matrix[5] = -viewBox[1] * rescale
681+
elif preserve[0][4:8] == 'ymid':
682+
# viewBox[0] to width/2
683+
matrix[5] = -viewBox[1] * rescale + height/2
684+
else: # preserve[0][4:8] == 'xmax':
685+
# viewBox[0] to width
686+
matrix[5] = -viewBox[1] * rescale + height
687+
except:
688+
matrix = [ width/viewBoxWidth, 0, -viewBox[0]* width/viewBoxWidth,
689+
0, -height/viewBoxHeight, viewBox[3]*height/viewBoxHeight ]
690+
653691
getPaths(paths, matrix, svg, path.SVGState(), {})
654692

655693
return ( paths, applyMatrix(matrix, complex(viewBox[0], viewBox[1])),
656694
applyMatrix(matrix, complex(viewBox[2], viewBox[3])) )
657695

658-
def getPathsFromSVGFile(filename,yGrowsUp=True):
659-
return getPathsFromSVG(ET.parse(filename).getroot(),yGrowsUp=yGrowsUp)
696+
def getPathsFromSVGFile(filename):
697+
return getPathsFromSVG(ET.parse(filename).getroot())
660698

0 commit comments

Comments
 (0)