|
|
@ -25,6 +25,11 @@ import logging
|
|
|
|
|
|
|
|
|
|
|
|
have_img2pdf = True
|
|
|
|
have_img2pdf = True
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
|
|
|
|
from PIL import Image
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ignore PIL limit because this software is meant to create posters which
|
|
|
|
|
|
|
|
# naturally can be very large in size
|
|
|
|
|
|
|
|
Image.MAX_IMAGE_PIXELS = None
|
|
|
|
import img2pdf
|
|
|
|
import img2pdf
|
|
|
|
except ImportError:
|
|
|
|
except ImportError:
|
|
|
|
have_img2pdf = False
|
|
|
|
have_img2pdf = False
|
|
|
@ -46,7 +51,7 @@ except ImportError:
|
|
|
|
tkinter.Menubutton = dummy
|
|
|
|
tkinter.Menubutton = dummy
|
|
|
|
tkinter.LabelFrame = dummy
|
|
|
|
tkinter.LabelFrame = dummy
|
|
|
|
|
|
|
|
|
|
|
|
VERSION = "0.5.1"
|
|
|
|
VERSION = "0.5.2"
|
|
|
|
|
|
|
|
|
|
|
|
PAGE_SIZES = OrderedDict(
|
|
|
|
PAGE_SIZES = OrderedDict(
|
|
|
|
[
|
|
|
|
[
|
|
|
@ -267,7 +272,7 @@ def complex_cover(n, m, x, y):
|
|
|
|
if X4 > 0 and Y4 > 0:
|
|
|
|
if X4 > 0 and Y4 > 0:
|
|
|
|
simple_config, (sx, sy) = simple_cover(X4, Y4, x, y)
|
|
|
|
simple_config, (sx, sy) = simple_cover(X4, Y4, x, y)
|
|
|
|
# shift the results such that they are in the center
|
|
|
|
# shift the results such that they are in the center
|
|
|
|
for (cx, cy, p) in simple_config:
|
|
|
|
for cx, cy, p in simple_config:
|
|
|
|
newconfig.append(
|
|
|
|
newconfig.append(
|
|
|
|
(
|
|
|
|
(
|
|
|
|
w0 * X(r, 0) + (X4 - sx) / 2 + cx,
|
|
|
|
w0 * X(r, 0) + (X4 - sx) / 2 + cx,
|
|
|
@ -281,7 +286,7 @@ def complex_cover(n, m, x, y):
|
|
|
|
if X4 > 0 and Y4 > 0:
|
|
|
|
if X4 > 0 and Y4 > 0:
|
|
|
|
simple_config, (sx, sy) = simple_cover(X4, Y4, x, y)
|
|
|
|
simple_config, (sx, sy) = simple_cover(X4, Y4, x, y)
|
|
|
|
# shift the results such that they are in the center
|
|
|
|
# shift the results such that they are in the center
|
|
|
|
for (cx, cy, p) in simple_config:
|
|
|
|
for cx, cy, p in simple_config:
|
|
|
|
newconfig.append(
|
|
|
|
newconfig.append(
|
|
|
|
(
|
|
|
|
(
|
|
|
|
w3 * X(r, 3) + (X4 - sx) / 2 + cx,
|
|
|
|
w3 * X(r, 3) + (X4 - sx) / 2 + cx,
|
|
|
@ -387,6 +392,10 @@ class Plakativ:
|
|
|
|
gdl = self.doc[self.pagenr].get_displaylist
|
|
|
|
gdl = self.doc[self.pagenr].get_displaylist
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
gdl = self.doc[self.pagenr].getDisplayList
|
|
|
|
gdl = self.doc[self.pagenr].getDisplayList
|
|
|
|
|
|
|
|
# this may fail with "RuntimeError: image is too wide"
|
|
|
|
|
|
|
|
# from pdf_load_image_imp() in pdf-image.c from mupdf for sizes larger
|
|
|
|
|
|
|
|
# than 1<<16 pixels:
|
|
|
|
|
|
|
|
# https://bugs.ghostscript.com/show_bug.cgi?id=703839
|
|
|
|
rect = gdl().rect
|
|
|
|
rect = gdl().rect
|
|
|
|
inpage_width = pt_to_mm(rect.width)
|
|
|
|
inpage_width = pt_to_mm(rect.width)
|
|
|
|
inpage_height = pt_to_mm(rect.height)
|
|
|
|
inpage_height = pt_to_mm(rect.height)
|
|
|
@ -589,7 +598,7 @@ class Plakativ:
|
|
|
|
# the computed positions and storing the largest border size in
|
|
|
|
# the computed positions and storing the largest border size in
|
|
|
|
# each dimension
|
|
|
|
# each dimension
|
|
|
|
poster_top = poster_right = poster_bottom = poster_left = 0
|
|
|
|
poster_top = poster_right = poster_bottom = poster_left = 0
|
|
|
|
for (posx, posy, p) in self.layout["positions"]:
|
|
|
|
for posx, posy, p in self.layout["positions"]:
|
|
|
|
if p:
|
|
|
|
if p:
|
|
|
|
top = posy - border_top
|
|
|
|
top = posy - border_top
|
|
|
|
if top < 0 and -top > poster_top:
|
|
|
|
if top < 0 and -top > poster_top:
|
|
|
@ -708,7 +717,11 @@ class Plakativ:
|
|
|
|
shape = page.new_shape()
|
|
|
|
shape = page.new_shape()
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
shape = page.newShape()
|
|
|
|
shape = page.newShape()
|
|
|
|
shape.drawRect(
|
|
|
|
if hasattr(shape, "draw_rect"):
|
|
|
|
|
|
|
|
dr = shape.draw_rect
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
dr = shape.drawRect
|
|
|
|
|
|
|
|
dr(
|
|
|
|
fitz.Rect(
|
|
|
|
fitz.Rect(
|
|
|
|
x0,
|
|
|
|
x0,
|
|
|
|
y0,
|
|
|
|
y0,
|
|
|
@ -718,7 +731,7 @@ class Plakativ:
|
|
|
|
)
|
|
|
|
)
|
|
|
|
shape.finish(color=(0, 0, 1))
|
|
|
|
shape.finish(color=(0, 0, 1))
|
|
|
|
# outer rectangle
|
|
|
|
# outer rectangle
|
|
|
|
shape.drawRect(
|
|
|
|
dr(
|
|
|
|
fitz.Rect(
|
|
|
|
fitz.Rect(
|
|
|
|
x0 - left,
|
|
|
|
x0 - left,
|
|
|
|
y0 - top,
|
|
|
|
y0 - top,
|
|
|
@ -812,9 +825,13 @@ class Plakativ:
|
|
|
|
shape = page.new_shape()
|
|
|
|
shape = page.new_shape()
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
shape = page.newShape()
|
|
|
|
shape = page.newShape()
|
|
|
|
|
|
|
|
if hasattr(shape, "draw_rect"):
|
|
|
|
|
|
|
|
dr = shape.draw_rect
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
dr = shape.drawRect
|
|
|
|
if guides:
|
|
|
|
if guides:
|
|
|
|
if portrait:
|
|
|
|
if portrait:
|
|
|
|
shape.drawRect(
|
|
|
|
dr(
|
|
|
|
fitz.Rect(
|
|
|
|
fitz.Rect(
|
|
|
|
mm_to_pt(self.layout["border_left"]),
|
|
|
|
mm_to_pt(self.layout["border_left"]),
|
|
|
|
mm_to_pt(self.layout["border_top"]),
|
|
|
|
mm_to_pt(self.layout["border_top"]),
|
|
|
@ -823,7 +840,7 @@ class Plakativ:
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
shape.drawRect(
|
|
|
|
dr(
|
|
|
|
fitz.Rect(
|
|
|
|
fitz.Rect(
|
|
|
|
mm_to_pt(self.layout["border_bottom"]),
|
|
|
|
mm_to_pt(self.layout["border_bottom"]),
|
|
|
|
mm_to_pt(self.layout["border_left"]),
|
|
|
|
mm_to_pt(self.layout["border_left"]),
|
|
|
@ -859,7 +876,7 @@ class Plakativ:
|
|
|
|
)
|
|
|
|
)
|
|
|
|
if border:
|
|
|
|
if border:
|
|
|
|
if portrait:
|
|
|
|
if portrait:
|
|
|
|
shape.drawRect(
|
|
|
|
dr(
|
|
|
|
fitz.Rect(
|
|
|
|
fitz.Rect(
|
|
|
|
mm_to_pt(self.layout["border_left"] - x),
|
|
|
|
mm_to_pt(self.layout["border_left"] - x),
|
|
|
|
mm_to_pt(self.layout["border_top"] - y),
|
|
|
|
mm_to_pt(self.layout["border_top"] - y),
|
|
|
@ -876,7 +893,7 @@ class Plakativ:
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
shape.drawRect(
|
|
|
|
dr(
|
|
|
|
fitz.Rect(
|
|
|
|
fitz.Rect(
|
|
|
|
mm_to_pt(self.layout["border_bottom"] - x),
|
|
|
|
mm_to_pt(self.layout["border_bottom"] - x),
|
|
|
|
mm_to_pt(self.layout["border_left"] - y),
|
|
|
|
mm_to_pt(self.layout["border_left"] - y),
|
|
|
@ -1034,7 +1051,10 @@ class Application(tkinter.Frame):
|
|
|
|
top_frame = tkinter.Frame(frame_right)
|
|
|
|
top_frame = tkinter.Frame(frame_right)
|
|
|
|
top_frame.pack(fill=tkinter.X)
|
|
|
|
top_frame.pack(fill=tkinter.X)
|
|
|
|
|
|
|
|
|
|
|
|
tkinter.Button(top_frame, text="Open PDF", command=self.on_open_button).pack(
|
|
|
|
button_text = "Open PDF"
|
|
|
|
|
|
|
|
if have_img2pdf:
|
|
|
|
|
|
|
|
button_text = "Open PDF, JPG, PNG, TIF"
|
|
|
|
|
|
|
|
tkinter.Button(top_frame, text=button_text, command=self.on_open_button).pack(
|
|
|
|
side=tkinter.LEFT, expand=tkinter.TRUE, fill=tkinter.X
|
|
|
|
side=tkinter.LEFT, expand=tkinter.TRUE, fill=tkinter.X
|
|
|
|
)
|
|
|
|
)
|
|
|
|
tkinter.Button(top_frame, text="Help", state=tkinter.DISABLED).pack(
|
|
|
|
tkinter.Button(top_frame, text="Help", state=tkinter.DISABLED).pack(
|
|
|
@ -1188,10 +1208,13 @@ class Application(tkinter.Frame):
|
|
|
|
self.canvas.delete(tkinter.ALL)
|
|
|
|
self.canvas.delete(tkinter.ALL)
|
|
|
|
|
|
|
|
|
|
|
|
if not hasattr(self, "plakativ"):
|
|
|
|
if not hasattr(self, "plakativ"):
|
|
|
|
|
|
|
|
button_text = "Open PDF"
|
|
|
|
|
|
|
|
if have_img2pdf:
|
|
|
|
|
|
|
|
button_text = "Open PDF, JPG, PNG, TIF"
|
|
|
|
self.canvas.create_text(
|
|
|
|
self.canvas.create_text(
|
|
|
|
self.canvas_size[0] / 2,
|
|
|
|
self.canvas_size[0] / 2,
|
|
|
|
self.canvas_size[1] / 2,
|
|
|
|
self.canvas_size[1] / 2,
|
|
|
|
text='Click on the "Open PDF" button in the upper right.',
|
|
|
|
text='Click on the "%s" button in the upper right.' % button_text,
|
|
|
|
fill="white",
|
|
|
|
fill="white",
|
|
|
|
)
|
|
|
|
)
|
|
|
|
return
|
|
|
|
return
|
|
|
@ -1247,7 +1270,7 @@ class Application(tkinter.Frame):
|
|
|
|
|
|
|
|
|
|
|
|
# draw rectangles
|
|
|
|
# draw rectangles
|
|
|
|
# TODO: also draw numbers indicating the page number
|
|
|
|
# TODO: also draw numbers indicating the page number
|
|
|
|
for (x, y, portrait) in self.plakativ.layout["positions"]:
|
|
|
|
for x, y, portrait in self.plakativ.layout["positions"]:
|
|
|
|
x0 = (x + self.plakativ.layout["posterpos"][0]) * zoom_1 + (
|
|
|
|
x0 = (x + self.plakativ.layout["posterpos"][0]) * zoom_1 + (
|
|
|
|
self.canvas_size[0] - zoom_1 * self.plakativ.layout["overallsize"][0]
|
|
|
|
self.canvas_size[0] - zoom_1 * self.plakativ.layout["overallsize"][0]
|
|
|
|
) / 2
|
|
|
|
) / 2
|
|
|
@ -1335,8 +1358,6 @@ class Application(tkinter.Frame):
|
|
|
|
)
|
|
|
|
)
|
|
|
|
# remove alpha channel
|
|
|
|
# remove alpha channel
|
|
|
|
if remove_alpha:
|
|
|
|
if remove_alpha:
|
|
|
|
from PIL import Image
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
img = Image.open(self.filename).convert("RGBA")
|
|
|
|
img = Image.open(self.filename).convert("RGBA")
|
|
|
|
background = Image.new("RGBA", img.size, (255, 255, 255))
|
|
|
|
background = Image.new("RGBA", img.size, (255, 255, 255))
|
|
|
|
img = Image.alpha_composite(background, img)
|
|
|
|
img = Image.alpha_composite(background, img)
|
|
|
@ -1693,6 +1714,7 @@ class BorderSizeWidget(tkinter.LabelFrame):
|
|
|
|
]
|
|
|
|
]
|
|
|
|
):
|
|
|
|
):
|
|
|
|
self.variables[n] = tkinter.DoubleVar()
|
|
|
|
self.variables[n] = tkinter.DoubleVar()
|
|
|
|
|
|
|
|
|
|
|
|
# need to pass k and v as function arguments so that their value
|
|
|
|
# need to pass k and v as function arguments so that their value
|
|
|
|
# does not get overwritten each loop iteration
|
|
|
|
# does not get overwritten each loop iteration
|
|
|
|
def callback(varname, idx, op, k_copy=n, v_copy=self.variables[n]):
|
|
|
|
def callback(varname, idx, op, k_copy=n, v_copy=self.variables[n]):
|
|
|
|