Skip to content

Commit

Permalink
ENH: Add papersizes (#800)
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinThoma committed Apr 24, 2022
1 parent d1be80d commit b3247e8
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 4 deletions.
11 changes: 7 additions & 4 deletions PyPDF2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from ._version import __version__
from .merger import PdfFileMerger
from .pagerange import PageRange, parse_filename_page_ranges
from .pdf import PdfFileReader, PdfFileWriter
from PyPDF2._version import __version__
from PyPDF2.merger import PdfFileMerger
from PyPDF2.pagerange import PageRange, parse_filename_page_ranges
from PyPDF2.papersizes import PaperSize
from PyPDF2.pdf import PdfFileReader, PdfFileWriter
from PyPDF2 import pdf

__all__ = [
"__version__",
"PageRange",
"PaperSize",
"parse_filename_page_ranges",
"pdf",
"PdfFileMerger",
Expand Down
48 changes: 48 additions & 0 deletions PyPDF2/papersizes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""Helper to get paper sizes."""

from collections import namedtuple

Dimensions = namedtuple("Dimensions", ["width", "height"])


class PaperSize(object):
"""(width, height) of the paper in portrait mode in pixels at 72 ppi."""

# Notes how to calculate it:
# 1. Get the size of the paper in mm
# 2. Convert it to inches (25.4 millimeters are equal to 1 inches)
# 3. Convert it to pixels ad 72dpi (1 inch is equal to 72 pixels)

# All Din-A paper sizes follow this pattern:
# 2xA(n-1) = A(n)
# So the height of the next bigger one is the width of the smaller one
# The ratio is always approximately the ratio 1:2**0.5
# Additionally, A0 is defined to have an area of 1 m**2
# Be aware of rounding issues!
A0 = Dimensions(2384, 3370) # 841mm x 1189mm
A1 = Dimensions(1684, 2384)
A2 = Dimensions(1191, 1684)
A3 = Dimensions(842, 1191)
A4 = Dimensions(
595, 842
) # Printer paper, documents - this is by far the most common
A5 = Dimensions(420, 595) # Paperback books
A6 = Dimensions(298, 420) # Post cards
A7 = Dimensions(210, 298)
A8 = Dimensions(147, 210)

# Envelopes
C4 = Dimensions(649, 918)


_din_a = [
PaperSize.A0,
PaperSize.A1,
PaperSize.A2,
PaperSize.A3,
PaperSize.A4,
PaperSize.A5,
PaperSize.A6,
PaperSize.A7,
PaperSize.A8,
]
30 changes: 30 additions & 0 deletions Tests/test_papersizes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from PyPDF2 import papersizes
import pytest


def test_din_a0():
dim = papersizes.PaperSize.A0
area_square_pixels = float(dim.width) * dim.height

# 72 pixels is 1 inch
area_square_inch = area_square_pixels / 72**2

# 25.4 millimeter is equal to 1 inches
area_square_mm = area_square_inch * (25.4)**2
assert abs(area_square_mm - 999949) < 100
conversion_factor = 72 / 25.4
assert (dim.width - 841 * conversion_factor) < 1
assert (dim.width - 1189 * conversion_factor) < 1



@pytest.mark.parametrize("dimensions", papersizes._din_a)
def test_din_a_ratio(dimensions):
assert abs(dimensions.height - dimensions.width * 2**0.5) <= 2.5


@pytest.mark.parametrize(
"dimensions_a, dimensions_b", list(zip(papersizes._din_a, papersizes._din_a[1:]))
)
def test_din_a_doubling(dimensions_a, dimensions_b):
assert abs(dimensions_a.height - 2 * dimensions_b.width) <= 4

0 comments on commit b3247e8

Please sign in to comment.