aspose-pdf-foss-for-python 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aspose_pdf/__init__.py +367 -0
- aspose_pdf/_compat_surface.py +142 -0
- aspose_pdf/_export_files.py +108 -0
- aspose_pdf/_pending_signatures.py +222 -0
- aspose_pdf/_version.py +17 -0
- aspose_pdf/actions.py +273 -0
- aspose_pdf/annotations/__init__.py +1614 -0
- aspose_pdf/annotations/pdf3d.py +70 -0
- aspose_pdf/attachments.py +62 -0
- aspose_pdf/auto_links.py +375 -0
- aspose_pdf/block_extraction.py +223 -0
- aspose_pdf/cgm.py +7 -0
- aspose_pdf/clustering/__init__.py +13 -0
- aspose_pdf/clustering/hierarchical_agglomerative_clustering.py +151 -0
- aspose_pdf/color.py +241 -0
- aspose_pdf/destinations.py +164 -0
- aspose_pdf/document.py +5884 -0
- aspose_pdf/document_fonts.py +150 -0
- aspose_pdf/drawing.py +13 -0
- aspose_pdf/engine/__init__.py +1 -0
- aspose_pdf/engine/agl.py +243 -0
- aspose_pdf/engine/annotation_cleanup.py +407 -0
- aspose_pdf/engine/annotation_import.py +503 -0
- aspose_pdf/engine/annotation_json.py +313 -0
- aspose_pdf/engine/annotation_xfdf.py +405 -0
- aspose_pdf/engine/annotation_xfdf_import.py +389 -0
- aspose_pdf/engine/appearance.py +1361 -0
- aspose_pdf/engine/attachment_zip.py +306 -0
- aspose_pdf/engine/attachment_zip_import.py +387 -0
- aspose_pdf/engine/auto_crop.py +101 -0
- aspose_pdf/engine/auto_tag.py +1451 -0
- aspose_pdf/engine/blank_pages.py +198 -0
- aspose_pdf/engine/blank_split.py +73 -0
- aspose_pdf/engine/bookmark_json.py +714 -0
- aspose_pdf/engine/bookmark_split.py +167 -0
- aspose_pdf/engine/ccitt.py +457 -0
- aspose_pdf/engine/ccitt_tables.py +231 -0
- aspose_pdf/engine/cert_chain.py +306 -0
- aspose_pdf/engine/cff_outlines.py +928 -0
- aspose_pdf/engine/cms.py +562 -0
- aspose_pdf/engine/comparison_html.py +435 -0
- aspose_pdf/engine/conformance.py +2748 -0
- aspose_pdf/engine/contact_sheet.py +215 -0
- aspose_pdf/engine/content_authoring.py +1347 -0
- aspose_pdf/engine/content_bounds.py +67 -0
- aspose_pdf/engine/content_isolation.py +180 -0
- aspose_pdf/engine/content_stream_parser.py +2318 -0
- aspose_pdf/engine/cos.py +416 -0
- aspose_pdf/engine/data/__init__.py +81 -0
- aspose_pdf/engine/data/agl/LICENSE-ADOBE-AGL.txt +28 -0
- aspose_pdf/engine/data/agl/LICENSE-REPORTLAB.txt +31 -0
- aspose_pdf/engine/data/agl/README.md +44 -0
- aspose_pdf/engine/data/agl/glyphlist.json.zlib +0 -0
- aspose_pdf/engine/data/cmaps/LICENSE-ADOBE-CMAP.txt +28 -0
- aspose_pdf/engine/data/cmaps/LICENSE-ADOBE-MAPPING.txt +28 -0
- aspose_pdf/engine/data/cmaps/README.md +51 -0
- aspose_pdf/engine/data/cmaps/predefined_cmaps_CNS1.json.zlib +0 -0
- aspose_pdf/engine/data/cmaps/predefined_cmaps_GB1.json.zlib +0 -0
- aspose_pdf/engine/data/cmaps/predefined_cmaps_Japan1.json.zlib +0 -0
- aspose_pdf/engine/data/cmaps/predefined_cmaps_Korea1.json.zlib +0 -0
- aspose_pdf/engine/data/cmaps/predefined_cmaps_index.json.zlib +0 -0
- aspose_pdf/engine/data/fonts/LICENSE-DEJAVU.txt +187 -0
- aspose_pdf/engine/data/fonts/LICENSE-OFL.txt +102 -0
- aspose_pdf/engine/data/fonts/README.md +47 -0
- aspose_pdf/engine/data/fonts/dingbats.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/mono-bold.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/mono-bolditalic.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/mono-italic.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/mono-regular.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/sans-bold.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/sans-bolditalic.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/sans-italic.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/sans-regular.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/serif-bold.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/serif-bolditalic.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/serif-italic.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/serif-regular.ttf.zlib +0 -0
- aspose_pdf/engine/data/fonts/symbol.ttf.zlib +0 -0
- aspose_pdf/engine/data/number.py +78 -0
- aspose_pdf/engine/data/types.py +156 -0
- aspose_pdf/engine/data/xmp.py +1458 -0
- aspose_pdf/engine/dct.py +854 -0
- aspose_pdf/engine/dss.py +658 -0
- aspose_pdf/engine/duplicate_pages.py +67 -0
- aspose_pdf/engine/encryption.py +967 -0
- aspose_pdf/engine/field_appearance.py +310 -0
- aspose_pdf/engine/file_output.py +98 -0
- aspose_pdf/engine/filters.py +958 -0
- aspose_pdf/engine/flatten.py +388 -0
- aspose_pdf/engine/font_authoring.py +609 -0
- aspose_pdf/engine/font_inventory.py +211 -0
- aspose_pdf/engine/font_resolver.py +829 -0
- aspose_pdf/engine/font_subset.py +545 -0
- aspose_pdf/engine/font_subset_cff.py +963 -0
- aspose_pdf/engine/font_subset_type1.py +114 -0
- aspose_pdf/engine/font_variations.py +159 -0
- aspose_pdf/engine/form_batch.py +134 -0
- aspose_pdf/engine/form_csv.py +267 -0
- aspose_pdf/engine/form_csv_export.py +131 -0
- aspose_pdf/engine/form_data.py +364 -0
- aspose_pdf/engine/form_field_edit.py +306 -0
- aspose_pdf/engine/form_fields.py +253 -0
- aspose_pdf/engine/form_json.py +89 -0
- aspose_pdf/engine/form_schema.py +246 -0
- aspose_pdf/engine/form_validation.py +395 -0
- aspose_pdf/engine/glyph_outlines.py +465 -0
- aspose_pdf/engine/graphics_absorb.py +1061 -0
- aspose_pdf/engine/grid_split.py +80 -0
- aspose_pdf/engine/gvar.py +467 -0
- aspose_pdf/engine/headings.py +273 -0
- aspose_pdf/engine/image_export.py +875 -0
- aspose_pdf/engine/image_import.py +219 -0
- aspose_pdf/engine/image_resample.py +116 -0
- aspose_pdf/engine/image_resolution.py +376 -0
- aspose_pdf/engine/image_zip.py +339 -0
- aspose_pdf/engine/imposition.py +233 -0
- aspose_pdf/engine/incremental_update.py +477 -0
- aspose_pdf/engine/inline_image.py +337 -0
- aspose_pdf/engine/interleave.py +188 -0
- aspose_pdf/engine/io.py +53 -0
- aspose_pdf/engine/jbig2.py +186 -0
- aspose_pdf/engine/jpeg2000.py +2124 -0
- aspose_pdf/engine/jpeg_encoder.py +706 -0
- aspose_pdf/engine/jpx.py +211 -0
- aspose_pdf/engine/link_extraction.py +378 -0
- aspose_pdf/engine/link_urls.py +252 -0
- aspose_pdf/engine/link_validation.py +555 -0
- aspose_pdf/engine/lists.py +307 -0
- aspose_pdf/engine/logging.py +18 -0
- aspose_pdf/engine/merge_bookmarks.py +180 -0
- aspose_pdf/engine/optional_content.py +1323 -0
- aspose_pdf/engine/page_count_split.py +60 -0
- aspose_pdf/engine/page_labels.py +295 -0
- aspose_pdf/engine/page_zip.py +219 -0
- aspose_pdf/engine/parser_exceptions.py +125 -0
- aspose_pdf/engine/pdf_matrix.py +90 -0
- aspose_pdf/engine/pdf_parser_cos.py +1611 -0
- aspose_pdf/engine/pdf_writer_cos.py +544 -0
- aspose_pdf/engine/predefined_cmaps.py +635 -0
- aspose_pdf/engine/primitives/__init__.py +5 -0
- aspose_pdf/engine/primitives/matrix.py +31 -0
- aspose_pdf/engine/pubsec.py +898 -0
- aspose_pdf/engine/rasterized_copy.py +171 -0
- aspose_pdf/engine/rasterizer.py +5483 -0
- aspose_pdf/engine/redaction.py +140 -0
- aspose_pdf/engine/revocation.py +495 -0
- aspose_pdf/engine/rich_text.py +415 -0
- aspose_pdf/engine/sanitize.py +412 -0
- aspose_pdf/engine/sfnt.py +247 -0
- aspose_pdf/engine/shading.py +2317 -0
- aspose_pdf/engine/sign_field.py +689 -0
- aspose_pdf/engine/signature_appearance.py +302 -0
- aspose_pdf/engine/signature_profiles.py +206 -0
- aspose_pdf/engine/signature_revisions.py +476 -0
- aspose_pdf/engine/signature_validator.py +313 -0
- aspose_pdf/engine/signed_changes.py +208 -0
- aspose_pdf/engine/signing.py +288 -0
- aspose_pdf/engine/simple_pdf.py +21416 -0
- aspose_pdf/engine/spread_split.py +330 -0
- aspose_pdf/engine/stamps.py +414 -0
- aspose_pdf/engine/std_font_data.py +201 -0
- aspose_pdf/engine/std_fonts.py +97 -0
- aspose_pdf/engine/std_metrics.py +364 -0
- aspose_pdf/engine/stream_output.py +22 -0
- aspose_pdf/engine/stroke.py +228 -0
- aspose_pdf/engine/svg_export.py +1162 -0
- aspose_pdf/engine/symbol_encodings.py +260 -0
- aspose_pdf/engine/tables.py +420 -0
- aspose_pdf/engine/text_blocks.py +467 -0
- aspose_pdf/engine/text_comparison.py +146 -0
- aspose_pdf/engine/text_edit.py +1936 -0
- aspose_pdf/engine/text_export.py +758 -0
- aspose_pdf/engine/text_faces.py +275 -0
- aspose_pdf/engine/text_highlight.py +197 -0
- aspose_pdf/engine/text_layout.py +574 -0
- aspose_pdf/engine/text_locate.py +423 -0
- aspose_pdf/engine/text_metrics.py +86 -0
- aspose_pdf/engine/text_outlines.py +150 -0
- aspose_pdf/engine/text_region.py +476 -0
- aspose_pdf/engine/text_selection.py +53 -0
- aspose_pdf/engine/text_split.py +141 -0
- aspose_pdf/engine/tiff_import.py +130 -0
- aspose_pdf/engine/timestamp.py +327 -0
- aspose_pdf/engine/toc.py +407 -0
- aspose_pdf/engine/type1_outlines.py +471 -0
- aspose_pdf/engine/viewer_preferences.py +275 -0
- aspose_pdf/engine/visual_comparison.py +318 -0
- aspose_pdf/engine/webp_encoder.py +107 -0
- aspose_pdf/engine/woff.py +302 -0
- aspose_pdf/engine/woff2.py +674 -0
- aspose_pdf/engine/word_extraction.py +235 -0
- aspose_pdf/exceptions.py +148 -0
- aspose_pdf/facades.py +1569 -0
- aspose_pdf/font_registry.py +149 -0
- aspose_pdf/font_repository.py +311 -0
- aspose_pdf/font_substitution.py +115 -0
- aspose_pdf/forms.py +1688 -0
- aspose_pdf/generated/__init__.py +3 -0
- aspose_pdf/generated/document.py +14 -0
- aspose_pdf/generated/forms.py +12 -0
- aspose_pdf/generated/pdfa.py +12 -0
- aspose_pdf/generated/security.py +33 -0
- aspose_pdf/geometry.py +149 -0
- aspose_pdf/graphics.py +256 -0
- aspose_pdf/html.py +117 -0
- aspose_pdf/image_resolution.py +45 -0
- aspose_pdf/images.py +524 -0
- aspose_pdf/interactive.py +435 -0
- aspose_pdf/latex.py +14 -0
- aspose_pdf/layers.py +482 -0
- aspose_pdf/license_management.py +65 -0
- aspose_pdf/link_extraction.py +52 -0
- aspose_pdf/link_validation.py +29 -0
- aspose_pdf/lists.py +365 -0
- aspose_pdf/load_limits.py +173 -0
- aspose_pdf/load_options.py +63 -0
- aspose_pdf/logical_structure.py +34 -0
- aspose_pdf/lowcode.py +1598 -0
- aspose_pdf/markdown.py +38 -0
- aspose_pdf/ofd.py +7 -0
- aspose_pdf/optimization.py +51 -0
- aspose_pdf/outlines.py +271 -0
- aspose_pdf/page_labels.py +169 -0
- aspose_pdf/page_ranges.py +90 -0
- aspose_pdf/page_size.py +220 -0
- aspose_pdf/pages.py +1883 -0
- aspose_pdf/paths.py +306 -0
- aspose_pdf/pdf_consts.py +19 -0
- aspose_pdf/pdfa.py +285 -0
- aspose_pdf/pdfua.py +194 -0
- aspose_pdf/pdfx.py +267 -0
- aspose_pdf/permissions.py +340 -0
- aspose_pdf/presentation.py +170 -0
- aspose_pdf/primitives.py +22 -0
- aspose_pdf/printing.py +41 -0
- aspose_pdf/py.typed +0 -0
- aspose_pdf/recipients.py +78 -0
- aspose_pdf/sanitization.py +90 -0
- aspose_pdf/save_format.py +25 -0
- aspose_pdf/save_options.py +25 -0
- aspose_pdf/security/__init__.py +160 -0
- aspose_pdf/security/impl/__init__.py +1 -0
- aspose_pdf/security/impl/digests/__init__.py +1 -0
- aspose_pdf/signature.py +385 -0
- aspose_pdf/signature_appearance.py +263 -0
- aspose_pdf/stamps.py +563 -0
- aspose_pdf/svg.py +41 -0
- aspose_pdf/table_extraction.py +156 -0
- aspose_pdf/tables.py +272 -0
- aspose_pdf/tagged.py +254 -0
- aspose_pdf/text.py +762 -0
- aspose_pdf/text_block.py +286 -0
- aspose_pdf/text_comparison.py +31 -0
- aspose_pdf/text_layout.py +100 -0
- aspose_pdf/utils.py +74 -0
- aspose_pdf/validation.py +286 -0
- aspose_pdf/viewer_preferences.py +375 -0
- aspose_pdf/visual_comparison.py +53 -0
- aspose_pdf/visualization.py +118 -0
- aspose_pdf/xmp.py +75 -0
- aspose_pdf_foss_for_python-0.1.0.dist-info/METADATA +2233 -0
- aspose_pdf_foss_for_python-0.1.0.dist-info/RECORD +265 -0
- aspose_pdf_foss_for_python-0.1.0.dist-info/WHEEL +5 -0
- aspose_pdf_foss_for_python-0.1.0.dist-info/licenses/LICENSE +21 -0
- aspose_pdf_foss_for_python-0.1.0.dist-info/top_level.txt +1 -0
aspose_pdf/page_size.py
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""Named page sizes for authoring, in PDF points.
|
|
2
|
+
|
|
3
|
+
A PDF measures its pages in default user space units, which are 1/72 inch
|
|
4
|
+
(ISO 32000-1 8.3.2.3), so every size here is a point pair. The ISO A and B
|
|
5
|
+
sizes are defined in millimetres and the US sizes in inches, and both are
|
|
6
|
+
converted exactly rather than rounded to a printer's approximation: an A4 page
|
|
7
|
+
is 210 x 297 mm, which is 595.275591 x 841.889764 pt as the writer spells it.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import math
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from typing import ClassVar
|
|
15
|
+
|
|
16
|
+
__all__ = ["PageSize"]
|
|
17
|
+
|
|
18
|
+
_POINTS_PER_INCH = 72.0
|
|
19
|
+
_MM_PER_INCH = 25.4
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True, slots=True, eq=False)
|
|
23
|
+
class PageSize:
|
|
24
|
+
"""A page's width and height in PDF points.
|
|
25
|
+
|
|
26
|
+
The named sizes are class attributes -- ``PageSize.A4``, ``PageSize.LETTER``
|
|
27
|
+
and the rest listed below -- and each one is *portrait*, the shorter side
|
|
28
|
+
first, which is how both ISO 216 and the US sizes are named. Turn one over
|
|
29
|
+
with :meth:`landscape`.
|
|
30
|
+
|
|
31
|
+
ISO A series: ``A0``, ``A1``, ``A2``, ``A3``, ``A4``, ``A5``, ``A6``.
|
|
32
|
+
ISO B series: ``B4``, ``B5``.
|
|
33
|
+
US sizes: ``LETTER``, ``LEGAL``, ``TABLOID``, ``LEDGER``, ``EXECUTIVE``,
|
|
34
|
+
``STATEMENT``.
|
|
35
|
+
|
|
36
|
+
``LETTER`` is the size a new page has when none is asked for, because it is
|
|
37
|
+
what this package has always created and what a ``/MediaBox`` that cannot
|
|
38
|
+
give a size falls back to.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
width: float
|
|
42
|
+
height: float
|
|
43
|
+
|
|
44
|
+
# ClassVar, so the named sizes stay class attributes: an annotation without
|
|
45
|
+
# it would make each one a *field* of the dataclass and PageSize(w, h) would
|
|
46
|
+
# need seventeen arguments. They are assigned below the class body, which is
|
|
47
|
+
# the earliest a PageSize can be built.
|
|
48
|
+
A0: ClassVar[PageSize]
|
|
49
|
+
A1: ClassVar[PageSize]
|
|
50
|
+
A2: ClassVar[PageSize]
|
|
51
|
+
A3: ClassVar[PageSize]
|
|
52
|
+
A4: ClassVar[PageSize]
|
|
53
|
+
A5: ClassVar[PageSize]
|
|
54
|
+
A6: ClassVar[PageSize]
|
|
55
|
+
B4: ClassVar[PageSize]
|
|
56
|
+
B5: ClassVar[PageSize]
|
|
57
|
+
LETTER: ClassVar[PageSize]
|
|
58
|
+
LEGAL: ClassVar[PageSize]
|
|
59
|
+
TABLOID: ClassVar[PageSize]
|
|
60
|
+
LEDGER: ClassVar[PageSize]
|
|
61
|
+
EXECUTIVE: ClassVar[PageSize]
|
|
62
|
+
STATEMENT: ClassVar[PageSize]
|
|
63
|
+
|
|
64
|
+
def __post_init__(self) -> None:
|
|
65
|
+
object.__setattr__(self, "width", _positive(self.width, "width"))
|
|
66
|
+
object.__setattr__(self, "height", _positive(self.height, "height"))
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
def from_mm(cls, width: float, height: float) -> PageSize:
|
|
70
|
+
"""A size given in millimetres, converted to points."""
|
|
71
|
+
# Multiplied before it is divided: 72 and the millimetres are both
|
|
72
|
+
# exact, so there is one rounding here instead of two, and the result is
|
|
73
|
+
# the number a caller gets computing it by hand.
|
|
74
|
+
return cls(
|
|
75
|
+
_positive(width, "width") * _POINTS_PER_INCH / _MM_PER_INCH,
|
|
76
|
+
_positive(height, "height") * _POINTS_PER_INCH / _MM_PER_INCH,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_inches(cls, width: float, height: float) -> PageSize:
|
|
81
|
+
"""A size given in inches, converted to points."""
|
|
82
|
+
return cls(
|
|
83
|
+
_positive(width, "width") * _POINTS_PER_INCH,
|
|
84
|
+
_positive(height, "height") * _POINTS_PER_INCH,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def by_name(cls, name: str) -> PageSize:
|
|
89
|
+
"""The named size *name* ("A4", "letter", "half letter", ...).
|
|
90
|
+
|
|
91
|
+
Case, spaces, hyphens and underscores are ignored, so a size read from a
|
|
92
|
+
configuration file or a command line needs no normalising first.
|
|
93
|
+
"""
|
|
94
|
+
if not isinstance(name, str):
|
|
95
|
+
raise TypeError("page size name must be a string")
|
|
96
|
+
key = "".join(name.split()).replace("-", "").replace("_", "").upper()
|
|
97
|
+
try:
|
|
98
|
+
return _NAMED[key]
|
|
99
|
+
except KeyError:
|
|
100
|
+
known = ", ".join(sorted(_CANONICAL))
|
|
101
|
+
raise ValueError(f"Unknown page size {name!r}; known sizes: {known}") from None
|
|
102
|
+
|
|
103
|
+
def landscape(self) -> PageSize:
|
|
104
|
+
"""This size with its longer side across: ``width >= height``."""
|
|
105
|
+
if self.width >= self.height:
|
|
106
|
+
return self
|
|
107
|
+
return PageSize(self.height, self.width)
|
|
108
|
+
|
|
109
|
+
def portrait(self) -> PageSize:
|
|
110
|
+
"""This size with its longer side up: ``width <= height``."""
|
|
111
|
+
if self.width <= self.height:
|
|
112
|
+
return self
|
|
113
|
+
return PageSize(self.height, self.width)
|
|
114
|
+
|
|
115
|
+
def rotated(self) -> PageSize:
|
|
116
|
+
"""This size with the two sides swapped, whichever way round it is."""
|
|
117
|
+
return PageSize(self.height, self.width)
|
|
118
|
+
|
|
119
|
+
def scaled(self, factor: float) -> PageSize:
|
|
120
|
+
"""This size with both sides multiplied by *factor*."""
|
|
121
|
+
scale = _positive(factor, "factor")
|
|
122
|
+
return PageSize(self.width * scale, self.height * scale)
|
|
123
|
+
|
|
124
|
+
def __eq__(self, other: object) -> bool:
|
|
125
|
+
"""Two sizes are equal when they write the same numbers into a file.
|
|
126
|
+
|
|
127
|
+
A PDF holds six decimal places (7.3.3), so an A4 page saved and reloaded
|
|
128
|
+
comes back as 595.275591 x 841.889764 -- the same sheet as
|
|
129
|
+
:attr:`PageSize.A4`, half a nanometre from it in floating point. Comparing
|
|
130
|
+
the rounded pair is what makes ``page.size == PageSize.A4`` true for a
|
|
131
|
+
document that has been through a save, which is the only answer that is
|
|
132
|
+
any use.
|
|
133
|
+
"""
|
|
134
|
+
if not isinstance(other, PageSize):
|
|
135
|
+
return NotImplemented
|
|
136
|
+
return self._written() == other._written()
|
|
137
|
+
|
|
138
|
+
def __hash__(self) -> int:
|
|
139
|
+
return hash(self._written())
|
|
140
|
+
|
|
141
|
+
def _written(self) -> tuple[float, float]:
|
|
142
|
+
"""The pair as a file would hold it: six decimal places."""
|
|
143
|
+
return (round(self.width, 6), round(self.height, 6))
|
|
144
|
+
|
|
145
|
+
def as_rect(self, x: float = 0.0, y: float = 0.0) -> tuple[float, float, float, float]:
|
|
146
|
+
"""This size as a rectangle ``(x, y, x + width, y + height)``.
|
|
147
|
+
|
|
148
|
+
The origin defaults to ``(0, 0)``, where a page's own coordinate system
|
|
149
|
+
starts; a ``/MediaBox`` may sit elsewhere and this keeps that possible.
|
|
150
|
+
"""
|
|
151
|
+
try:
|
|
152
|
+
x0, y0 = float(x), float(y)
|
|
153
|
+
except (TypeError, ValueError):
|
|
154
|
+
raise TypeError("rectangle origin must be two numbers") from None
|
|
155
|
+
if not (math.isfinite(x0) and math.isfinite(y0)):
|
|
156
|
+
raise ValueError("rectangle origin must be finite")
|
|
157
|
+
return (x0, y0, x0 + self.width, y0 + self.height)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _positive(value: float, name: str) -> float:
|
|
161
|
+
"""*value* as a finite positive float, or a refusal that names the field."""
|
|
162
|
+
if isinstance(value, bool):
|
|
163
|
+
raise TypeError(f"{name} must be a number")
|
|
164
|
+
try:
|
|
165
|
+
number = float(value)
|
|
166
|
+
except (TypeError, ValueError):
|
|
167
|
+
raise TypeError(f"{name} must be a number") from None
|
|
168
|
+
if not math.isfinite(number):
|
|
169
|
+
raise ValueError(f"{name} must be finite")
|
|
170
|
+
if number <= 0:
|
|
171
|
+
raise ValueError(f"{name} must be above zero")
|
|
172
|
+
return number
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# ISO 216 defines the A series by halving A0, one square metre, and the B
|
|
176
|
+
# series between two neighbouring A sizes; both are stated in millimetres.
|
|
177
|
+
PageSize.A0 = PageSize.from_mm(841, 1189)
|
|
178
|
+
PageSize.A1 = PageSize.from_mm(594, 841)
|
|
179
|
+
PageSize.A2 = PageSize.from_mm(420, 594)
|
|
180
|
+
PageSize.A3 = PageSize.from_mm(297, 420)
|
|
181
|
+
PageSize.A4 = PageSize.from_mm(210, 297)
|
|
182
|
+
PageSize.A5 = PageSize.from_mm(148, 210)
|
|
183
|
+
PageSize.A6 = PageSize.from_mm(105, 148)
|
|
184
|
+
PageSize.B4 = PageSize.from_mm(250, 353)
|
|
185
|
+
PageSize.B5 = PageSize.from_mm(176, 250)
|
|
186
|
+
|
|
187
|
+
# The US sizes are whole inches or halves of one, so these are exact.
|
|
188
|
+
PageSize.LETTER = PageSize.from_inches(8.5, 11)
|
|
189
|
+
PageSize.LEGAL = PageSize.from_inches(8.5, 14)
|
|
190
|
+
PageSize.TABLOID = PageSize.from_inches(11, 17)
|
|
191
|
+
PageSize.LEDGER = PageSize.from_inches(17, 11)
|
|
192
|
+
PageSize.EXECUTIVE = PageSize.from_inches(7.25, 10.5)
|
|
193
|
+
PageSize.STATEMENT = PageSize.from_inches(5.5, 8.5)
|
|
194
|
+
|
|
195
|
+
#: The sizes :meth:`PageSize.by_name` knows, by their canonical name.
|
|
196
|
+
_CANONICAL: dict[str, PageSize] = {
|
|
197
|
+
"A0": PageSize.A0,
|
|
198
|
+
"A1": PageSize.A1,
|
|
199
|
+
"A2": PageSize.A2,
|
|
200
|
+
"A3": PageSize.A3,
|
|
201
|
+
"A4": PageSize.A4,
|
|
202
|
+
"A5": PageSize.A5,
|
|
203
|
+
"A6": PageSize.A6,
|
|
204
|
+
"B4": PageSize.B4,
|
|
205
|
+
"B5": PageSize.B5,
|
|
206
|
+
"LETTER": PageSize.LETTER,
|
|
207
|
+
"LEGAL": PageSize.LEGAL,
|
|
208
|
+
"TABLOID": PageSize.TABLOID,
|
|
209
|
+
"LEDGER": PageSize.LEDGER,
|
|
210
|
+
"EXECUTIVE": PageSize.EXECUTIVE,
|
|
211
|
+
"STATEMENT": PageSize.STATEMENT,
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# Spellings a caller is as likely to write as the canonical one.
|
|
215
|
+
_NAMED: dict[str, PageSize] = {
|
|
216
|
+
**_CANONICAL,
|
|
217
|
+
"HALFLETTER": PageSize.STATEMENT,
|
|
218
|
+
"LEDGER11X17": PageSize.TABLOID,
|
|
219
|
+
"11X17": PageSize.TABLOID,
|
|
220
|
+
}
|