I updated the PDF Booklet project and removed Python 2 dependencies so that it will run under Ubuntu 22.04.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
5.5 KiB

2 years ago
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. PdfShuffler 0.6.0 - GTK+ based utility for splitting, rearrangement and
  5. modification of PDF documents.
  6. Copyright (C) 2008-2012 Konstantinos Poulios
  7. <https://sourceforge.net/projects/pdfshuffler>
  8. This file is part of PdfShuffler.
  9. PdfShuffler is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 3 of the License, or
  12. (at your option) any later version.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17. You should have received a copy of the GNU General Public License along
  18. with this program; if not, write to the Free Software Foundation, Inc.,
  19. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. """
  21. from gi.repository import Gtk, GObject
  22. from gi.repository import cairo
  23. from math import pi as M_PI
  24. class CellRendererImage(Gtk.CellRenderer):
  25. __gproperties__ = {
  26. "image": (GObject.TYPE_PYOBJECT, "Image", "Image",
  27. GObject.PARAM_READWRITE),
  28. "width": (GObject.TYPE_FLOAT, "Width", "Width",
  29. 0., 1.e4, 0., GObject.PARAM_READWRITE),
  30. "height": (GObject.TYPE_FLOAT, "Height", "Height",
  31. 0., 1.e4, 0., GObject.PARAM_READWRITE),
  32. "rotation": (GObject.TYPE_INT, "Rotation", "Rotation",
  33. 0, 360, 0, GObject.PARAM_READWRITE),
  34. "scale": (GObject.TYPE_FLOAT, "Scale", "Scale",
  35. 0.01, 100., 1., GObject.PARAM_READWRITE),
  36. "resample": (GObject.TYPE_FLOAT,
  37. "Resample", "Resample Coefficient",
  38. 1., 100., 1., GObject.PARAM_READWRITE),
  39. "cropL": (GObject.TYPE_FLOAT, "CropL", "CropL",
  40. 0., 1., 0., GObject.PARAM_READWRITE),
  41. "cropR": (GObject.TYPE_FLOAT, "CropR", "CropR",
  42. 0., 1., 0., GObject.PARAM_READWRITE),
  43. "cropT": (GObject.TYPE_FLOAT, "CropT", "CropT",
  44. 0., 1., 0., GObject.PARAM_READWRITE),
  45. "cropB": (GObject.TYPE_FLOAT, "CropB", "CropB",
  46. 0., 1., 0., GObject.PARAM_READWRITE),
  47. }
  48. def __init__(self):
  49. ## self.__GObject_init__() Original code modified in the line below
  50. Gtk.CellRendererText.__init__(self)
  51. GObject.GObject.__init__(self)
  52. self.th1 = 2. # border thickness
  53. self.th2 = 3. # shadow thickness
  54. def get_geometry(self):
  55. rotation = int(self.rotation) % 360
  56. rotation = ((rotation) / 90) * 90
  57. if not self.image:
  58. w0 = w1 = self.width / self.resample
  59. h0 = h1 = self.height / self.resample
  60. else:
  61. w0 = self.image.get_width()
  62. h0 = self.image.get_height()
  63. if rotation == 90 or rotation == 270:
  64. w1, h1 = h0, w0
  65. else:
  66. w1, h1 = w0, h0
  67. x = self.cropL * w1
  68. y = self.cropT * h1
  69. scale = self.resample * self.scale
  70. w2 = int(scale * (1. - self.cropL - self.cropR) * w1)
  71. h2 = int(scale * (1. - self.cropT - self.cropB) * h1)
  72. return w0,h0,w1,h1,w2,h2,rotation
  73. def do_set_property(self, pspec, value):
  74. setattr(self, pspec.name, value)
  75. def do_get_property(self, pspec):
  76. return getattr(self, pspec.name)
  77. def do_render(self, window, widget, cell_area, \
  78. expose_area, flags):
  79. if not self.image:
  80. return
  81. w0,h0,w1,h1,w2,h2,rotation = self.get_geometry()
  82. th = int(2*self.th1+self.th2)
  83. w = w2 + th
  84. h = h2 + th
  85. x = cell_area.x
  86. y = cell_area.y
  87. if cell_area and w > 0 and h > 0:
  88. x += self.get_property('xalign') * \
  89. (cell_area.width - w - self.get_property('xpad'))
  90. y += self.get_property('yalign') * \
  91. (cell_area.height - h - self.get_property('ypad'))
  92. cr = window # cr = window.cairo_create()
  93. cr.translate(x,y)
  94. x = self.cropL * w1
  95. y = self.cropT * h1
  96. #shadow
  97. cr.set_source_rgb(0.5, 0.5, 1)
  98. cr.rectangle(th, th, w2, h2)
  99. cr.fill()
  100. #border
  101. cr.set_source_rgb(0, 0, 0)
  102. cr.rectangle(0, 0, w2+2*self.th1, h2+2*self.th1)
  103. cr.fill()
  104. #image
  105. cr.set_source_rgb(1, 1, 1)
  106. cr.rectangle(self.th1, self.th1, w2, h2)
  107. cr.fill_preserve()
  108. cr.clip()
  109. cr.translate(self.th1,self.th1)
  110. scale = self.resample * self.scale
  111. cr.scale(scale, scale)
  112. cr.translate(-x,-y)
  113. if rotation > 0:
  114. cr.translate(w1/2,h1/2)
  115. cr.rotate(rotation * M_PI / 180)
  116. cr.translate(-w0/2,-h0/2)
  117. cr.set_source_surface(self.image)
  118. cr.paint()
  119. def do_get_size(self, widget, cell_area=None):
  120. x = y = 0
  121. w0,h0,w1,h1,w2,h2,rotation = self.get_geometry()
  122. th = int(2*self.th1+self.th2)
  123. w = w2 + th
  124. h = h2 + th
  125. if cell_area and w > 0 and h > 0:
  126. x = self.get_property('xalign') * \
  127. (cell_area.width - w - self.get_property('xpad'))
  128. y = self.get_property('yalign') * \
  129. (cell_area.height - h - self.get_property('ypad'))
  130. w += 2 * self.get_property('xpad')
  131. h += 2 * self.get_property('ypad')
  132. return int(x), int(y), w, h