~ubuntu-branches/ubuntu/utopic/pdfposter/utopic

« back to all changes in this revision

Viewing changes to pdftools/pdfposter/__init__.py

  • Committer: Package Import Robot
  • Author(s): Elena Grandi, Jakub Wilk, Elena Grandi
  • Date: 2013-05-22 10:03:38 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130522100338-26uo6rmqsurfcfzv
Tags: 0.6.0-1
[ Jakub Wilk ]
* Use canonical URIs for Vcs-* fields.

[ Elena Grandi ]
* New upstream release
* Regenerate PDF files from python sources
* Include html documentation
* Updated homepage and author contacts
* debian/control: bump Standards-Version to 3.9.3 (no changes needed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
pdftools.pdfposter - scale and tile PDF images/pages to print on multiple pages.
4
4
"""
5
5
#
6
 
# Copyright 2008-2009 by Hartmut Goebel <h.goebel@goebel-consult.de>
 
6
# Copyright 2008-2013 by Hartmut Goebel <h.goebel@crazy-compilers.com>
7
7
#
8
8
# This program is free software: you can redistribute it and/or modify
9
9
# it under the terms of the GNU General Public License as published by
19
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
20
#
21
21
 
22
 
__author__ = "Hartmut Goebel <h.goebel@goebel-consult.de>"
23
 
__copyright__ = "Copyright 2008-2009 by Hartmut Goebel <h.goebel@goebel-consult.de>"
 
22
__author__ = "Hartmut Goebel <h.goebel@crazy-compilers.com>"
 
23
__copyright__ = "Copyright 2008-2013 by Hartmut Goebel <h.goebel@crazy-compilers.com>"
24
24
__licence__ = "GNU General Public License version 3 (GPL v3)"
25
 
__version__ = "0.5.0"
 
25
__version__ = "0.6.0"
 
26
 
 
27
# ignore some warnings for pyPDF < 1.13
 
28
import warnings
 
29
warnings.filterwarnings('ignore', "the sets module is deprecated")
 
30
warnings.filterwarnings('ignore', "the md5 module is deprecated")
26
31
 
27
32
from pyPdf.pdf import PdfFileWriter, PdfFileReader, PageObject, getRectangle, \
28
33
     ArrayObject, ContentStream, NameObject, FloatObject, RectangleObject
112
117
 
113
118
def rectangle2box(pdfbox):
114
119
    return {
115
 
        'width'   : pdfbox.upperRight[0],
116
 
        'height'  : pdfbox.upperRight[1],
117
 
        'offset_x': pdfbox.lowerLeft[0],
118
 
        'offset_y': pdfbox.lowerLeft[1],
119
 
        'unit'    : 'pt',
120
 
        'units_x' : pdfbox.upperRight[0],
121
 
        'units_y' : pdfbox.upperRight[1],
 
120
        'width'   : pdfbox.getUpperRight_x()-pdfbox.getLowerLeft_x(),
 
121
        'height'  : pdfbox.getUpperRight_y()-pdfbox.getLowerLeft_y(),
 
122
        'offset_x': pdfbox.getLowerLeft_x(),
 
123
        'offset_y': pdfbox.getLowerLeft_y(),
 
124
        # the following are unused, but need to be set to make
 
125
        # `rotate_box()` work
 
126
        'units_x' : None,
 
127
        'units_y' : None,
122
128
        }
123
129
 
124
130
def rotate_box(box):
150
156
 
151
157
    rotate = False
152
158
 
153
 
    inbox_x = float(inbox['width' ]-inbox['offset_x'])
154
 
    inbox_y = float(inbox['height']-inbox['offset_y'])
 
159
    inbox_x = float(inbox['width' ])
 
160
    inbox_y = float(inbox['height'])
155
161
    log(17, 'input  dimensions: %.2f %.2f (trimbox of input page)',
156
162
            inbox_x, inbox_y)
157
163
 
224
230
            newpage[NameObject(attr)] = RectangleObject(list(page[attr]))
225
231
    return newpage
226
232
 
 
233
def _clip_pdf_page(page, x, y, width, height):
 
234
    content = ContentStream(page["/Contents"].getObject(), page.pdf)
 
235
    content.operations[:0] = [
 
236
        ([], 'q'), # save graphic state
 
237
        ([], 'n'), # cancel path w/ filling or stroking
 
238
        (RectangleObject((x, y, width, height)), 're'), # rectangle path
 
239
        ([], 'W*'), # clip
 
240
        ]
 
241
    content.operations.append([[], "Q"]) # restore graphic state
 
242
    page[NameObject('/Contents')] = content
 
243
 
227
244
 
228
245
def _scale_pdf_page(page, factor):
229
246
    for boxname in PAGE_BOXES:
240
257
    page[NameObject('/Contents')] = content
241
258
 
242
259
 
243
 
def posterize(outpdf, page, mediabox, posterbox, scale):
 
260
def posterize(outpdf, page, mediabox, posterbox, scale, use_ArtBox=False):
244
261
    """
245
262
    page: input page
246
263
    mediabox : size secs of the media to print on
247
264
    posterbox: size secs of the resulting poster
248
265
    scale: scale factor (to be used instead of posterbox)
249
266
    """
250
 
    inbox = rectangle2box(page.artBox)
 
267
    if use_ArtBox:
 
268
        inbox = rectangle2box(page.artBox)
 
269
    else:
 
270
        inbox = rectangle2box(page.trimBox)
 
271
    _clip_pdf_page(page, inbox['offset_x'], inbox['offset_y'],
 
272
                   inbox['width'], inbox['height'])
251
273
    ncols, nrows, scale, rotate = decide_num_pages(inbox, mediabox,
252
274
                                                   posterbox, scale)
253
275
    mediabox = mediabox.copy()
260
282
    h_step = mediabox['width']  - mediabox['offset_x']
261
283
    v_step = mediabox['height'] - mediabox['offset_y']
262
284
    
263
 
    trimbox = rectangle2box(page.trimBox)
 
285
    if use_ArtBox:
 
286
        trimbox = rectangle2box(page.artBox)
 
287
    else:
 
288
        trimbox = rectangle2box(page.trimBox)
264
289
    h_pos = float(trimbox['offset_x'])
265
290
    h_max, v_max = float(trimbox['width']), float(trimbox['height'])
266
291
    for col in range(ncols):
267
 
        v_pos = float(trimbox['offset_y'])
 
292
        v_pos = float(trimbox['offset_y']) + (nrows-1) * v_step
268
293
        for row in range(nrows):
269
294
            log(17, 'Creating page with offset: %.2f %.2f' % (h_pos, v_pos))
270
295
            newpage = copyPage(page)
277
302
            newpage.trimBox = RectangleObject((h_pos, v_pos,
278
303
                                               min(h_max, h_pos + h_step),
279
304
                                               min(v_max, v_pos + v_step)))
280
 
            newpage.cropBox = newpage.artBox = newpage.trimBox
 
305
            newpage.artBox = newpage.trimBox
281
306
            outpdf.addPage(newpage)
282
 
            v_pos += v_step
 
307
            v_pos -= v_step
283
308
        h_pos += h_step
284
309
 
285
310
def password_hook():
308
333
 
309
334
    for i, page in enumerate(inpdf.pages):
310
335
        log(19, '---- processing page %i -----', i+1)
311
 
        posterize(outpdf, page, opts.media_size, opts.poster_size, opts.scale)
 
336
        posterize(outpdf, page, opts.media_size, opts.poster_size, opts.scale,
 
337
                  opts.use_ArtBox)
312
338
    if not opts.dry_run:
313
339
        outpdf.write(open(outfilename, 'wb'))