Skip to content

Commit 9ca9bd8

Browse files
committed
add helper method Drawing.page_setup()
1 parent 76809d7 commit 9ca9bd8

File tree

4 files changed

+153
-9
lines changed

4 files changed

+153
-9
lines changed

docs/source/drawing/drawing.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ Drawing Object
196196

197197
.. automethod:: new_layout
198198

199+
.. automethod:: page_setup
200+
199201
.. automethod:: delete_layout
200202

201203
.. automethod:: add_image_def
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright (c) 2022, Manfred Moitzi
2+
# License: MIT License
3+
4+
import pytest
5+
import ezdxf
6+
7+
8+
def test_reset_layout1_landscape():
9+
doc = ezdxf.new()
10+
assert len(doc.layouts) == 2
11+
psp = doc.page_setup("Layout1", fmt="ISO A0")
12+
assert len(doc.layouts) == 2
13+
assert psp.dxf_layout.dxf.paper_width == 1189
14+
assert psp.dxf_layout.dxf.paper_height == 841
15+
16+
17+
def test_invalid_paper_format_returns_A3():
18+
doc = ezdxf.new()
19+
with pytest.raises(ValueError):
20+
doc.page_setup("Layout1", fmt="INVALID")
21+
22+
23+
def test_reset_layout1_portrait():
24+
doc = ezdxf.new()
25+
assert len(doc.layouts) == 2
26+
psp = doc.page_setup("Layout1", fmt="ISO A0", landscape=False)
27+
assert len(doc.layouts) == 2
28+
assert psp.dxf_layout.dxf.paper_width == 841
29+
assert psp.dxf_layout.dxf.paper_height == 1189
30+
31+
32+
def test_resetting_layout1_creates_a_new_main_viewport():
33+
doc = ezdxf.new()
34+
psp = doc.paperspace("Layout1")
35+
assert len(psp) == 0 # no main viewport exist, not required
36+
psp = doc.page_setup("Layout1", fmt="ISO A0")
37+
assert len(psp.query("VIEWPORT")) == 1
38+
39+
40+
def test_resetting_layout1_does_not_delete_entities():
41+
doc = ezdxf.new()
42+
psp = doc.paperspace("Layout1")
43+
psp.add_point((0, 0))
44+
assert len(psp) == 1
45+
psp = doc.page_setup("Layout1", fmt="ISO A0")
46+
assert len(psp.query("POINT")) == 1
47+
48+
49+
def test_new_layout2():
50+
doc = ezdxf.new()
51+
assert len(doc.layouts) == 2
52+
psp = doc.page_setup("Layout2", fmt="ISO A0")
53+
assert len(doc.layouts) == 3
54+
assert psp.dxf_layout.dxf.paper_width == 1189
55+
assert psp.dxf_layout.dxf.paper_height == 841
56+
57+
58+
if __name__ == '__main__':
59+
pytest.main([__file__])

src/ezdxf/document.py

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -819,9 +819,7 @@ def paperspace(self, name: str = "") -> Paperspace:
819819
psp = self.layouts.get(name)
820820
if isinstance(psp, Paperspace):
821821
return psp
822-
raise KeyError(
823-
"use method modelspace() to acquire the modelspace."
824-
)
822+
raise KeyError("use method modelspace() to acquire the modelspace.")
825823
else:
826824
return self.active_layout()
827825

@@ -913,7 +911,7 @@ def delete_layout(self, name: str) -> None:
913911
"""
914912
Delete paper space layout `name` and all entities owned by this layout.
915913
Available only for DXF R2000 or later, DXF R12 supports only one
916-
paperspace and it can't be deleted.
914+
paperspace, and it can't be deleted.
917915
918916
"""
919917
if name not in self.layouts:
@@ -942,6 +940,68 @@ def new_layout(self, name, dxfattribs=None) -> "Layout":
942940
else:
943941
return self.layouts.new(name, dxfattribs)
944942

943+
def page_setup(
944+
self,
945+
name: str = "Layout1",
946+
fmt: str = "ISO A3",
947+
landscape=True,
948+
) -> Paperspace:
949+
"""
950+
Creates a new paperspace layout if `name` does not
951+
exist or reset the existing layout.
952+
The paper format name `fmt` defines one of the following paper sizes,
953+
measures in landscape orientation:
954+
955+
=========== ======= ======= =======
956+
Name Units Width Height
957+
=========== ======= ======= =======
958+
ISO A0 mm 1189 841
959+
ISO A1 mm 841 594
960+
ISO A2 mm 594 420
961+
ISO A3 mm 420 297
962+
ISO A4 mm 297 210
963+
ANSI A inch 11 8.5
964+
ANSI B inch 17 11
965+
ANSI C inch 22 17
966+
ANSI D inch 34 22
967+
ANSI E inch 44 34
968+
ARCH C inch 24 18
969+
ARCH D inch 36 24
970+
ARCH E inch 48 36
971+
ARCH E1 inch 42 30
972+
Letter inch 11 8.5
973+
Legal inch 14 8.5
974+
=========== ======= ======= =======
975+
976+
The layout uses the associated units of the paper format as drawing
977+
units, has no margins or offset defined and the scale of the paperspace
978+
layout is 1:1.
979+
980+
Args:
981+
name: paperspace layout name
982+
fmt: paper format
983+
landscape: ``True`` for landscape orientation, ``False`` for portrait
984+
orientation
985+
986+
"""
987+
from ezdxf.tools.standards import PAGE_SIZES
988+
989+
width: float
990+
height: float
991+
try:
992+
units, width, height = PAGE_SIZES[fmt]
993+
except KeyError:
994+
raise ValueError(f"unknown paper format: {fmt}")
995+
if not landscape:
996+
width, height = height, width
997+
try:
998+
psp = self.paperspace(name)
999+
except KeyError:
1000+
psp = cast(Paperspace, self.new_layout(name))
1001+
1002+
psp.page_setup(size=(width, height), margins=(0, 0, 0, 0), units=units)
1003+
return psp
1004+
9451005
def acquire_arrow(self, name: str):
9461006
"""For standard AutoCAD and ezdxf arrows create block definitions if
9471007
required, otherwise check if block `name` exist. (internal API)

src/ezdxf/tools/standards.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright (c) 2016-2022, Manfred Moitzi
22
# License: MIT License
3+
from __future__ import annotations
34
from typing import TYPE_CHECKING, List, Tuple, Sequence, Union, cast
45

56
from ezdxf import const
@@ -11,13 +12,15 @@
1112
import logging
1213

1314
if TYPE_CHECKING:
14-
from ezdxf.eztypes import Drawing, DimStyle
15+
from ezdxf.document import Drawing
16+
from ezdxf.entities import DimStyle
17+
from ezdxf.layouts import Paperspace
1518

1619
logger = logging.getLogger("ezdxf")
1720
LTypeDef = Tuple[str, str, Sequence[float]]
1821

1922

20-
def setup_drawing(doc: "Drawing", topics: Union[str, bool, Sequence] = "all"):
23+
def setup_drawing(doc: Drawing, topics: Union[str, bool, Sequence] = "all"):
2124
"""
2225
Setup default linetypes, text styles or dimension styles.
2326
@@ -69,7 +72,7 @@ def get_token(name: str) -> List[str]:
6972
setup_dimstyles(doc, domain=domain)
7073

7174

72-
def setup_linetypes(doc: "Drawing") -> None:
75+
def setup_linetypes(doc: Drawing) -> None:
7376
measurement = 1
7477
if doc:
7578
measurement = doc.header.get("$MEASUREMENT", measurement)
@@ -86,7 +89,7 @@ def setup_linetypes(doc: "Drawing") -> None:
8689
)
8790

8891

89-
def setup_styles(doc: "Drawing") -> None:
92+
def setup_styles(doc: Drawing) -> None:
9093
doc.header["$TEXTSTYLE"] = "OpenSans"
9194
for name, font in styles():
9295
if name in doc.styles:
@@ -99,7 +102,7 @@ def setup_styles(doc: "Drawing") -> None:
99102
)
100103

101104

102-
def setup_dimstyles(doc: "Drawing", domain: str = "all") -> None:
105+
def setup_dimstyles(doc: Drawing, domain: str = "all") -> None:
103106
setup_styles(doc)
104107
ezdxf_dimstyle = setup_dimstyle(
105108
doc,
@@ -3976,3 +3979,23 @@ def setup_visual_styles_r2013(doc: "Drawing"):
39763979
),
39773980
},
39783981
}
3982+
3983+
# all page sizes in landscape orientation
3984+
PAGE_SIZES = {
3985+
"ISO A0": ("mm", 1189, 841),
3986+
"ISO A1": ("mm", 841, 594),
3987+
"ISO A2": ("mm", 594, 420),
3988+
"ISO A3": ("mm", 420, 297),
3989+
"ISO A4": ("mm", 297, 210),
3990+
"ANSI A": ("inch", 11, 8.5),
3991+
"ANSI B": ("inch", 17, 11),
3992+
"ANSI C": ("inch", 22, 17),
3993+
"ANSI D": ("inch", 34, 22),
3994+
"ANSI E": ("inch", 44, 34),
3995+
"ARCH C": ("inch", 24, 18),
3996+
"ARCH D": ("inch", 36, 24),
3997+
"ARCH E": ("inch", 48, 36),
3998+
"ARCH E1": ("inch", 42, 30),
3999+
"Letter": ("inch", 11, 8.5),
4000+
"Legal": ("inch", 14, 8.5),
4001+
}

0 commit comments

Comments
 (0)