File size: 3,510 Bytes
966ae59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# -*- coding: utf-8 -*-
# Author: ximing
# Description: process
# Copyright (c) 2023, XiMing Xing.
# License: MIT License

import xml.etree.ElementTree as ET
from typing import Tuple

import omegaconf

from .shape import circle_tag, rect_tag
from .type import is_valid_svg

def delete_empty_path(input_svg: str, output_svg: str):
    is_valid_svg(input_svg)

    # read svg
    tree = ET.parse(input_svg)
    root = tree.getroot()

    group = ET.Element('g')
    for i, element in enumerate(root.iter()):
        element.tag = element.tag.split('}')[-1]
        if element.tag == 'path':
            if element.get('d') == 'C  NaN NaN' or element.get('d') == '':
                continue
            group.append(element)

    # new svg
    svg = ET.Element('svg',
                     xmlns="http://www.w3.org/2000/svg",
                     version='1.1',
                     width=root.get('width'),
                     height=root.get('height'),
                     viewBox=root.get('viewBox'))
    svg.append(group)
    tree = ET.ElementTree(svg)
    tree.write(output_svg, encoding='utf-8', xml_declaration=True)


def add_clipPath2def(mounted_node: ET.Element, tag_name: str, attrs: omegaconf.DictConfig):
    # add defs node
    defs = ET.SubElement(mounted_node, 'defs')  # parent=mounted_node, tag='defs'
    if tag_name == 'none':
        return None
    # add clipPath node
    id = 'def_clip'
    _circleClip = ET.SubElement(defs, 'clipPath', id='def_clip')  # parent=defs, tag='clipPath'
    # add ops
    if tag_name == 'circle_clip':
        _circleClip.append(
            circle_tag(cx=attrs.cx, cy=attrs.cy, r=attrs.r)
        )
    elif tag_name == 'rect_clip':
        _circleClip.append(
            rect_tag(x=attrs.x, y=attrs.y, rx=attrs.rx, ry=attrs.ry, width=attrs.width, height=attrs.height)
        )
    else:
        raise NotImplementedError(f'{tag_name} is not exist!')
    return id


def add_def_tag(
        svg_path: str,
        def_tag_plan: str,
        out_size: Tuple[int, int],  # e.g.: (600, 600)
):
    is_valid_svg(svg_path)

    width, height = out_size[0], out_size[1]

    # set def tag
    if def_tag_plan == 'circle_clip':
        def_cfg = omegaconf.DictConfig({
            'name': 'circle_clip',
            'attrs': {'cx': width // 2, 'cy': height // 2, 'r': int(height * 0.5)}
        })
    elif def_tag_plan == 'rect_clip':
        def_cfg = omegaconf.DictConfig({
            'name': 'rect_clip',
            'attrs': {'x': 0, 'y': 0, 'rx': 70, 'ry': 70, 'width': width, 'height': height}
        })
    else:
        def_cfg = None

    # load SVG
    tree = ET.parse(svg_path)
    root = tree.getroot()
    # new group, and add paths form svg_path_1
    group = ET.Element('g')
    for i, element in enumerate(root.iter()):
        element.tag = element.tag.split('}')[-1]
        if element.tag in ['path', 'polygon']:
            group.append(element)

    # new svg
    svg = ET.Element('svg',
                     xmlns="http://www.w3.org/2000/svg",
                     version='1.1',
                     width=str(out_size[0]),
                     height=str(out_size[1]))
    # add def tag to the SVG
    clip_id = add_clipPath2def(mounted_node=svg,
                               tag_name=def_cfg.name,
                               attrs=def_cfg.attrs)
    group.set('clip-path', f'url(#{clip_id})')
    svg.append(group)
    # write svg
    tree = ET.ElementTree(svg)
    tree.write(svg_path, encoding='utf-8', xml_declaration=True)