-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpolygon.py
More file actions
54 lines (41 loc) · 2.28 KB
/
polygon.py
File metadata and controls
54 lines (41 loc) · 2.28 KB
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
from dataclasses import dataclass
from typing import List, Optional, Tuple
from lxml import etree
from pptx_shapes import units
from pptx_shapes.entities.bbox import BBox
from pptx_shapes.entities.namespace_helper import NamespaceHelper
from pptx_shapes.shapes.shape import Shape
from pptx_shapes.style.fill_style import FillStyle
from pptx_shapes.style.stroke_style import StrokeStyle
@dataclass
class Polygon(Shape):
points: List[Tuple[float, float]]
angle: float = 0
fill: Optional[FillStyle] = None
stroke: Optional[StrokeStyle] = None
def to_xml(self, shape_id: int, ns_helper: NamespaceHelper) -> etree.Element:
node = ns_helper.element("p:sp")
xs, ys = [x for x, _ in self.points], [y for _, y in self.points]
x_min, y_min, x_max, y_max = min(xs), min(ys), max(xs), max(ys)
nvsppr = ns_helper.element("p:nvSpPr", parent=node)
ns_helper.element("p:cNvPr", {"id": str(shape_id), "name": f"Polygon {shape_id}"}, parent=nvsppr)
ns_helper.element("p:cNvSpPr", parent=nvsppr)
ns_helper.element("p:nvPr", parent=nvsppr)
sppr = ns_helper.element("p:spPr", parent=node)
sppr.append(self.make_xfrm(ns_helper, {"rot": units.angle_to_unit(self.angle)}, x=x_min, y=y_min, width=x_max - x_min, height=y_max - y_min))
cust_geom = ns_helper.element("a:custGeom", parent=sppr)
ns_helper.element("a:avLst", parent=cust_geom)
ns_helper.element("a:ahLst", parent=cust_geom)
ns_helper.element("a:rect", {"b": "b", "l": "l", "r": "r", "t": "t"}, parent=cust_geom)
path = ns_helper.element("a:path", {"w": units.cm_to_emu(x_max - x_min), "h": units.cm_to_emu(y_max - y_min)}, parent=ns_helper.element("a:pathLst", parent=cust_geom))
for i, (px, py) in enumerate(self.points):
to = ns_helper.element("a:moveTo" if i == 0 else "a:lnTo", parent=path)
ns_helper.element("a:pt", {"x": units.cm_to_emu(px - x_min), "y": units.cm_to_emu(py - y_min)}, parent=to)
ns_helper.element("a:close", parent=path)
if self.fill:
sppr.append(self.fill.to_xml(ns_helper))
if self.stroke:
sppr.append(self.stroke.to_xml(ns_helper))
return node
def bbox(self) -> BBox:
return BBox.from_points(points=self.points, angle=self.angle)