def unwrap_transforms(svg): 'Undo global coordinate transformation, if there is one.' groups = svg.findall('g') if len(groups) != 1: return False group = groups[0] if not set(group.attrib.keys()) <= {'id', 'transform'}: return False if not group.attrib.get('transform'): return False mat = simpletransform.parse_transform(group.attrib['transform']) # Recognize pdf coordinate transformation if not (almost_zero(mat[0][0] - 4/3) and almost_zero(mat[1][1] + 4/3) and almost_zero(mat[0][1]) and almost_zero(mat[1][0]) and almost_zero(mat[0][2])): return False mat = [[1, 0, 0], [0, -1, mat[1][2]*3/4]] for child in group: child_mat = simpletransform.parse_transform( child.attrib.get('transform', ''), mat) child.attrib['transform'] = simpletransform.format_transform(child_mat) svg.append(child) group.drop_tree() simplify_transforms(svg) return True
def simplify_transforms(svg): 'Re-format transform attributes to save characters.' for elt in svg.xpath('//*[@transform]'): mat = simpletransform.parse_transform(elt.attrib['transform']) # Recognize identity / translation if (almost_zero(mat[0][0] - 1) and almost_zero(mat[1][1] - 1) and almost_zero(mat[0][1]) and almost_zero(mat[1][0])): if almost_zero(mat[1][2]): if almost_zero(mat[0][2]): del elt.attrib['transform'] continue elt.attrib['transform'] = 'translate({})'.format( smart_round(mat[0][2])) continue elt.attrib['transform'] = 'translate({} {})'.format( smart_round(mat[0][2]), smart_round(mat[1][2])) continue # Recognize scale if (almost_zero(mat[0][1]) and almost_zero(mat[0][2]) and almost_zero(mat[1][0]) and almost_zero(mat[1][2])): if almost_zero(mat[0][0] - mat[1][1]): elt.attrib['transform'] = 'scale({})'.format( smart_round(mat[0][0])) continue elt.attrib['transform'] = 'scale({} {})'.format( smart_round(mat[0][0]), smart_round(mat[1][1])) continue elt.attrib['transform'] = "matrix({},{},{},{},{},{})".format( smart_round(mat[0][0]), smart_round(mat[1][0]), smart_round(mat[0][1]), smart_round(mat[1][1]), smart_round(mat[0][2]), smart_round(mat[1][2]))