tile.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # SPDX-FileCopyrightText: 2024 geisserml <geisserml@gmail.com>
  2. # SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
  3. from enum import Enum
  4. from pathlib import Path
  5. import pypdfium2.raw as pdfium_c
  6. import pypdfium2._helpers as pdfium
  7. # TODO? consider dotted access
  8. from pypdfium2._cli._parsers import add_input, get_input
  9. class Units (Enum):
  10. PT = 0
  11. MM = 1
  12. CM = 2
  13. IN = 3
  14. def units_to_pt(value, unit):
  15. if unit is Units.PT:
  16. return value
  17. elif unit is Units.IN:
  18. return value*72
  19. elif unit is Units.CM:
  20. return (value*72) / 2.54
  21. elif unit is Units.MM:
  22. return (value*72) / 25.4
  23. else:
  24. raise ValueError(f"Invalid unit type {unit}")
  25. def attach(parser):
  26. add_input(parser, pages=False)
  27. parser.add_argument(
  28. "--output", "-o",
  29. required = True,
  30. type = Path,
  31. help = "Target path for the new document",
  32. )
  33. parser.add_argument(
  34. "--rows", "-r",
  35. type = int,
  36. required = True,
  37. help = "Number of rows (horizontal tiles)",
  38. )
  39. parser.add_argument(
  40. "--cols", "-c",
  41. type = int,
  42. required = True,
  43. help = "Number of columns (vertical tiles)",
  44. )
  45. # NOTE no short aliases for width and height since -h would confilct with argparse help
  46. parser.add_argument(
  47. "--width",
  48. type = float,
  49. required = True,
  50. help = "Target width",
  51. )
  52. parser.add_argument(
  53. "--height",
  54. type = float,
  55. required = True,
  56. help = "Target height",
  57. )
  58. parser.add_argument(
  59. "--unit", "-u",
  60. default = Units.MM,
  61. type = lambda string: Units[string.upper()],
  62. help = "Unit for target width and height (pt, mm, cm, in)",
  63. )
  64. def main(args):
  65. # Rudimentary page tiling, powered by pdfium
  66. # A more sophisticated implementation could place XObjects rather than using PDFium's helper function, support merging and arranging on the fly, etc.
  67. w = units_to_pt(args.width, args.unit)
  68. h = units_to_pt(args.height, args.unit)
  69. src_pdf = get_input(args)
  70. raw_dest = pdfium_c.FPDF_ImportNPagesToOne(src_pdf, w, h, args.cols, args.rows)
  71. dest_pdf = pdfium.PdfDocument(raw_dest)
  72. dest_pdf.save(args.output)