diff --git a/demo/decrypt.py b/demo/decrypt.py index 840ccda25..7b1aab747 100644 --- a/demo/decrypt.py +++ b/demo/decrypt.py @@ -1,9 +1,9 @@ -#!/usr/bin/env python2 -#this demo will open an encrypted PDF document -#decrypt it with the provided password -#and save as a new PDF document -#usage: removePass.py +""" +This demo will open an encrypted PDF document, decrypt it with the provided +password and save as a new PDF document. +usage: removePass.py +""" import fitz import sys @@ -20,4 +20,4 @@ 'cannot decrypt %s with password "%s"' % (sys.argv[1], sys.argv[2]) #save as a new PDF -doc.save(sys.argv[3]) +doc.save(sys.argv[3], decrypt=True) # decrypt=False is default diff --git a/demo/new-annots.pdf b/demo/new-annots.pdf new file mode 100644 index 000000000..7f49c4745 Binary files /dev/null and b/demo/new-annots.pdf differ diff --git a/demo/new-annots.png b/demo/new-annots.png deleted file mode 100644 index 034e82211..000000000 Binary files a/demo/new-annots.png and /dev/null differ diff --git a/demo/new-annots.py b/demo/new-annots.py index 78511a1eb..e8ba28d52 100644 --- a/demo/new-annots.py +++ b/demo/new-annots.py @@ -10,7 +10,7 @@ It contains the following annotation types: Text ("sticky note"), FreeText, text markers (underline, strike-out, -highlight), Circle, Square, Line, PolyLine, Polygon and FileAttachment. +highlight), Circle, Square, Line, PolyLine, Polygon, FileAttachment and Stamp. Notes ----- @@ -28,56 +28,68 @@ PyMuPDF v1.13.13 ------------------------------------------------------------------------------- """ -text = "text in line\ntext in line\ntext in line" +text = "text in line\ntext in line\ntext in line\ntext in line" red = (1, 0, 0) blue = (0, 0, 1) -yellow = (1, 1, 0) -colors = {"stroke": red, "fill": yellow} -border = {"width": 1, "dashes": [1, 3]} +gold = (1, 1, 0) +colors = {"stroke": blue, "fill": gold} +border = {"width": 0.3, "dashes": [2]} displ = fitz.Rect(0, 50, 0, 50) -pos = fitz.Point(50, 100) -t1 = u"têxt üsès Lätiñ charß,\nEuro: €, mu: µ, superscripts: ²³!" +r = fitz.Rect(50, 100, 220, 135) +t1 = u"têxt üsès Lätiñ charß,\nEUR: €, mu: µ, super scripts: ²³!" def print_descr(rect, annot): - """Print a short description to the right of an annotation.""" - page = annot.parent - page.insertText(rect.br + (10, -3), + """Print a short description to the right of an annot rect.""" + annot.parent.insertText(rect.br + (10, 0), "'%s' annotation" % annot.type[1], color = red) doc = fitz.open() page = doc.newPage() -annot = page.addFreetextAnnot(pos, t1, color = blue) +annot = page.addFreetextAnnot(r, t1, rotate = 90) +annot.setBorder(border) +annot.update(fontsize = 10, border_color=red, fill_color=gold, text_color=blue) + print_descr(annot.rect, annot) r = annot.rect + displ print("added 'FreeText'") annot = page.addTextAnnot(r.tl, t1) print_descr(annot.rect, annot) -pos = annot.rect.tl + displ.tl * 2 print("added 'Sticky Note'") -page.insertText(pos, text, fontsize=11) -rl = page.searchFor("text in line") +pos = annot.rect.tl + displ.tl + +# first insert 4 rotated text lines +page.insertText(pos, text, fontsize=11, morph = (pos, fitz.Matrix(-15))) +# now search text to get the quads +rl = page.searchFor("text in line", quads = True) r0 = rl[0] r1 = rl[1] r2 = rl[2] +r3 = rl[3] annot = page.addHighlightAnnot(r0) -print_descr(r0, annot) +# need to convert quad to rect for descriptive text ... +print_descr(r0.rect, annot) print("added 'HighLight'") annot = page.addStrikeoutAnnot(r1) -print_descr(r1, annot) +print_descr(r1.rect, annot) print("added 'StrikeOut'") annot = page.addUnderlineAnnot(r2) -print_descr(r2, annot) +print_descr(r2.rect, annot) print("added 'Underline'") -r = r2 + displ +annot = page.addSquigglyAnnot(r3) +print_descr(r3.rect, annot) +print("added 'Squiggly'") + +r = r3.rect + displ annot = page.addPolylineAnnot([r.bl, r.tr, r.br, r.tl]) -annot.setLineEnds(fitz.ANNOT_LE_Circle, fitz.ANNOT_LE_Diamond) annot.setBorder(border) annot.setColors(colors) +annot.setLineEnds(fitz.ANNOT_LE_ClosedArrow, fitz.ANNOT_LE_RClosedArrow) +annot.update() print_descr(annot.rect, annot) print("added 'PolyLine'") @@ -85,15 +97,17 @@ def print_descr(rect, annot): annot = page.addPolygonAnnot([r.bl, r.tr, r.br, r.tl]) annot.setBorder(border) annot.setColors(colors) -annot.setLineEnds(fitz.ANNOT_LE_Circle, fitz.ANNOT_LE_Diamond) +annot.setLineEnds(fitz.ANNOT_LE_Diamond, fitz.ANNOT_LE_Circle) +annot.update() print_descr(annot.rect, annot) print("added 'Polygon'") r+= displ annot = page.addLineAnnot(r.tr, r.bl) -annot.setLineEnds(fitz.ANNOT_LE_Circle, fitz.ANNOT_LE_Diamond) annot.setBorder(border) annot.setColors(colors) +annot.setLineEnds(fitz.ANNOT_LE_Diamond, fitz.ANNOT_LE_Circle) +annot.update() print_descr(annot.rect, annot) print("added 'Line'") @@ -101,6 +115,7 @@ def print_descr(rect, annot): annot = page.addRectAnnot(r) annot.setBorder(border) annot.setColors(colors) +annot.update() print_descr(annot.rect, annot) print("added 'Square'") @@ -108,6 +123,7 @@ def print_descr(rect, annot): annot = page.addCircleAnnot(r) annot.setBorder(border) annot.setColors(colors) +annot.update() print_descr(annot.rect, annot) print("added 'Circle'") @@ -116,4 +132,12 @@ def print_descr(rect, annot): print_descr(annot.rect, annot) print("added 'FileAttachment'") -doc.save("new-annots.pdf", garbage=4, deflate=True, clean=True) +r+= displ +annot = page.addStampAnnot(r, stamp = 10) +annot.setColors(colors) +annot.setOpacity(0.5) +annot.update() +print_descr(annot.rect, annot) +print("added 'Stamp'") + +doc.save("new-annots.pdf", expand=255) diff --git a/demo/numpy2fitz.py b/demo/numpy2fitz.py index b57a86689..02fe34018 100644 --- a/demo/numpy2fitz.py +++ b/demo/numpy2fitz.py @@ -1,7 +1,7 @@ -#! /usr/bin/python from __future__ import print_function import numpy as np import PIL +from PIL import Image import fitz import sys, time print("Python:", sys.version) @@ -24,7 +24,7 @@ ''' height = 2048 # choose whatever you want here; image will consist -width = 1024 # of 256 x 256 sized tiles, each colored as follows +width = 2028 # of 256 x 256 sized tiles, each colored as follows image = np.ndarray((height, width, 3), dtype=np.uint8) @@ -42,10 +42,10 @@ pix.writePNG("numpy2fitz.png") ttab.append((time.perf_counter(), "fitz")) -pix = PIL.Image.frombuffer("RGB", [width, height], samples, +pix = Image.frombuffer("RGB", [width, height], samples, "raw", "RGB", 0, 1) pix.save("numpy2PIL.png") ttab.append((time.perf_counter(), "PIL")) for i, t in enumerate(ttab): - if i > 0: print(t[0] - ttab[i-1][0], t[1]) + if i > 0: print("storing with %s: %g sec." % (t[1], t[0] - ttab[i-1][0])) diff --git a/demo/piechart2.py b/demo/piechart2.py index 2876af262..890cf6c69 100644 --- a/demo/piechart2.py +++ b/demo/piechart2.py @@ -7,14 +7,17 @@ #============================================================================== from fitz.utils import getColor # for getting RGB colors by name doc = fitz.open() # new empty PDF -doc.insertPage() # creates an ISO-A4 page -page = doc[-1] # this is the page -img = page.newShape() +page = doc.newPage() # creates an ISO-A4 page + +img = page.newShape() # start a Shape (canvas) for the page + # title of the page title = "Sitzverteilung nach der Bundestagswahl 2013" + # pie chart center and point of 1st data pie center = fitz.Point(200, 250) point = fitz.Point(100, 250) # will cycle through table data + # this is the radius radius = abs(point - center) diff --git a/doc/PyMuPDF.pdf b/doc/PyMuPDF.pdf index bc5711479..bcc04ea3f 100644 Binary files a/doc/PyMuPDF.pdf and b/doc/PyMuPDF.pdf differ diff --git a/doc/html.zip b/doc/html.zip index 667f9b697..26f273d3e 100644 Binary files a/doc/html.zip and b/doc/html.zip differ diff --git a/examples/draw-pencil.py b/examples/draw-pencil.py deleted file mode 100644 index 715a588cf..000000000 --- a/examples/draw-pencil.py +++ /dev/null @@ -1,62 +0,0 @@ -from __future__ import print_function -import fitz -from shapes_and_symbols import pencil -""" -@created: 2017-07-03 14:00:00 - -@author: (c) Jorj X. McKie - -PyMuPDF demo function for creating a pencil drawing similar to ReportLab's -Users Guide on pp. 39. The main difference: pencil sharpening traces are shown -more correctly ... :-) - -Dependencies: -PyMuPDF - -License: - GNU GPL 3+ -------------------------------------------------------------------------------- -Main purpose of this function is to demonstrate that working with PyMuPDF -is easy and straightforward ... -What does introduce some complexity is the ability to scale, and to left-right -flip the image while maintaining the text legible. -------------------------------------------------------------------------------- -New (2017-09-21): ------------------ -Scaling and other morphing effects can now also be achieved with a morphing -matrix. This is possible after page method "insertTextbox" also supports this. -------------------------------------------------------------------------------- -""" -#============================================================================== -# invoke the pencil function -#============================================================================== -if __name__ == "__main__": - doc=fitz.open() # empty new PDF - page = doc.newPage() # create page (A4) - img = page.newShape() # create shape -# ============================================================================= -# pencil 1 -# ============================================================================= - penheight = 100 # thickness of pencil - pentip = fitz.Point(100, 150) # first pencil tip here - pencil(img, pentip, penheight, True) # pencil points left -# ============================================================================= -# pencil 2 -# ============================================================================= - penheight = 20 # now a smaller one - pentip = fitz.Point(100, 250) # new pencil tip - pencil(img, pentip, penheight, False) # this one points right - - pentip.x += 10 # insert a little distance - text = """Like the ReportLab User Guide does,\nyou may want to use this image, to\nemphasize content, e.g. cautionary\nremarks, notes, examples, etc.""" - page.insertText(pentip, text) # insert explanatory text -# ============================================================================= -# pencil 3 -# ============================================================================= - # yet another pencil, which we will morph around its tip - mat = fitz.Matrix(-150)*fitz.Matrix(0.5,0.5,1) # morphing: rotate & shear - pentip = fitz.Point(300, 400) - # instead of another thickness (40) we could have used a scale matrix - pencil(img, pentip, 40, True, morph=(pentip, mat)) - img.commit() - doc.save("pencil.pdf") diff --git a/examples/shapes_and_symbols.py b/examples/shapes_and_symbols.py deleted file mode 100644 index 51c1e2692..000000000 --- a/examples/shapes_and_symbols.py +++ /dev/null @@ -1,543 +0,0 @@ -import fitz -from fitz.utils import getColor -""" -------------------------------------------------------------------------------- -Created on Fri Nov 10 07:00:00 2017 - -@author: Jorj McKie -Copyright (c) 2017 Jorj X. McKie - -The license of this program is governed by the GNU GENERAL PUBLIC LICENSE -Version 3, 29 June 2007. See the "COPYING" file of the PyMuPDF repository. -------------------------------------------------------------------------------- -Contains signs and symbols created with PyMuPDF's image creation features. -The intention is to facilitate the use of these features by providing functions -that create ready-made symbols. We strive to increase the function set from -time to time. - -To include a function in your Python script, import it like so: - -from shapes_and_symbols import smiley - -Using a function ----------------- - -smiley(img, rect, ...) - -Allmost all functions have the same first and second parameter: - -img - fitz.Shape object created by page.newShape() -rect - fitz.Rect object. This is the area in which the image should appear. - -Other parameters are function-specific, but always include a "morph" argument. -This can be used to change the image's appearance in an almost arbitrary way: -rotation, shearing, mirroring. For this you must provide a fitz.Point and a -fitz.Matrix object. See PyMuPDF documentation, chapter "Shape". - -Using function "pencil" ------------------------ - -pencil(img, penciltip, thickness, ...) - -penciltip - (fitz.Point) location of the pencil's tip -thickness - (int) pencil's thickness in pixels. - -The pencil's rectangle is computed from these two values - fixed proportions are -100 x 340, if thickness is 100. However, you can use the "morph" argument to -change appearance. -The main reasons for this special treatment are the appearance of some text and -the option of letting pencil point to left or right. - -------------------------------------------------------------------------------- -Available functions -------------------- - -dontenter - traffic sign Do Not Enter -heart - heart -clover - 4 leaved clover -diamond - rhombus -caro - one of the 4 card game colors -arrow - a triangle -hand - a hand symbol, similar to internet -pencil - a pencil (eye catcher) -smiley - emoji -frowney - emoji -------------------------------------------------------------------------------- - -Dependencies ------------- -PyMuPDF -------------------------------------------------------------------------------- -""" -# ============================================================================= -# Do Not Enter -# ============================================================================= -def dontenter(img, r, morph = None): - """Draw the "Do Not Enter" traffic symbol. - """ - red = getColor("red3") - white = (1,1,1) - img.drawOval(r) # draw red circle w/ thick white border - img.finish(fill = red, color = white, width = r.width * 0.04) - img.drawOval(r) # draw empty circle, thin black border - img.finish(width = r.width * 0.001) - deltah = r.width * 0.13 - deltav = r.height * 0.45 - rs = r + (deltah, deltav, -deltah, -deltav) - img.drawRect(rs) # draw white horizontal rectangle - img.finish(color = white, fill = white, width = r.width * 0.06, - roundCap = False, morph = morph) - return - -# ============================================================================= -# Heart -# ============================================================================= -def heart(img, r, col, morph = None): - """Draw a heart image inside a rectangle. - """ - mtop = r.tl + (r.tr - r.tl) * 0.5 - mbot = r.bl + (r.br - r.bl) * 0.5 - htop = mtop + (mbot - mtop)*0.3 # top point where arcs meet - hbot = mtop + (mbot - mtop)*0.8 # bottom point joining arcs - # left and right ctrl points, symmetrical. - pl1 = r.tl + (r.tr - r.tl) * 0.25 - pr1 = r.tr - (r.tr - r.tl) * 0.25 - pl2 = r.tl + (r.bl - r.tl) * 0.40 - pr2 = r.tr + (r.br - r.tr) * 0.40 - # we have defined all 6 points and now draw 2 Bezier curves - img.drawBezier(htop, pl1, pl2, hbot) - img.drawBezier(htop, pr1, pr2, hbot) - img.finish(color = col, fill = col, closePath = True, morph = morph) - -# ============================================================================= -# Clover leaf -# ============================================================================= -def clover(img, r, col, morph = None): - """Draw a 4-leaf clover image inside a rectangle. - """ - # this is made of 4 Bezier curves, each starting and ending in the - # rect's middle point M - M = r.tl + (r.br - r.tl) * 0.5 - img.drawBezier(M, r.tl, r.tr, M) - img.drawBezier(M, r.tr, r.br, M) - img.drawBezier(M, r.bl, r.tl, M) - img.drawBezier(M, r.br, r.bl, M) - img.finish(color = col, fill = col, width = 0.3, morph = morph) - -# ============================================================================= -# Diamond -# ============================================================================= -def diamond(img, r, col, morph = None): - """Draw a rhombus in a rectangle. - """ - white = (1,1,1) - mto = r.tl + (r.tr - r.tl) * 0.5 - mri = r.tr + (r.br - r.tr) * 0.5 - mbo = r.bl + (r.br - r.bl) * 0.5 - mle = r.tl + (r.bl - r.tl) * 0.5 - img.drawPolyline((mto, mri, mbo, mle)) - img.finish(color = white, fill = col, closePath = True, morph = morph) - -# ============================================================================= -# Caro (card game color) -# ============================================================================= -def caro(img, r, col, morph = None): - """Draw a caro symbol in a rectangle. - """ - white = (1,1,1) - mto = r.tl + (r.tr - r.tl) * 0.5 - mri = r.tr + (r.br - r.tr) * 0.5 - mbo = r.bl + (r.br - r.bl) * 0.5 - mle = r.tl + (r.bl - r.tl) * 0.5 - M = r.tl + (r.br - r.tl) * 0.5 - img.drawCurve(mle, M, mto) - img.drawCurve(mto, M, mri) - img.drawCurve(mri, M, mbo) - img.drawCurve(mbo, M, mle) - img.finish(color = white, fill = col, morph = morph) - -# ============================================================================= -# Arrow -# ============================================================================= -def arrow(img, r, col, morph = None): - """Draw a triangle symbol in a rectangle. Last parameter indicates direction - the arrow points to: either as a number or as first letter of east(0), south(1), - west(3), north(4). - """ - white = (1,1,1) - p1 = r.tl - p2 = r.bl - p3 = r.tr + (r.br - r.tr) * 0.5 - img.drawPolyline((p1, p2, p3)) - img.finish(color = white, fill = col, closePath = True, morph = morph) - -# ============================================================================= -# Hand -# ============================================================================= -def hand(img, rect, color = None, fill = None, morph = None): - """Put a hand symbol inside a rectangle on a PDF page. Parameters: - img - an object of the Shape class (contains relevant page information) - rect - a rectangle. Its width must be at least 30% larger than its height. - color, fill - color triples for border and filling (optional). - morph - morphing parameters (point, matrix) - """ - if rect.width / rect.height < 1.25: - raise ValueError("rect width:height ratio must be at least 1.25") - if not color: - line = getColor("orange") - else: - line = color - if not fill: - skin = getColor("burlywood1") - else: - skin = fill - #-------------------------------------------------------------------------- - # Define control points for the symbol, relative to a rect height of 3. - # This is the actual brainware of the whole thing ... - #-------------------------------------------------------------------------- - points = ((0.0, 1.4), (1.4, 0.2), (1.4, 1.4), (2.2, 0.0), (1.4, 1.4), - (3.4, 1.4), (3.4, 1.8), (2.8, 1.8), (2.8, 2.2), (2.6, 2.2), - (2.6, 2.6), (2.5, 2.6), (2.5, 3.0), - ) - # rescale points to the argument rectangle. - f = rect.height / 3 - tl = rect.tl # need this as displacement - # function for rescaling the points in the list - rescale = lambda x: fitz.Point(points[x])*f + tl - p1 = rescale(0) - p2 = rescale(1) - p3 = rescale(2) - p4 = rescale(3) - p5 = rescale(4) - p6 = rescale(5) - p7 = rescale(6) - p8 = rescale(7) - p9 = rescale(8) - p10 = rescale(9) - p11 = rescale(10) - p12 = rescale(11) - p13 = rescale(12) - - # some additional helper points for Bezier curves of the finger tips. - d1 = fitz.Point(0.4, 0) *f - d7 = p7 - fitz.Point(1.2, 0) * f - d9 = fitz.Point(d7.x, p9.y) - d11 = fitz.Point(d7.x, p11.y) - # now draw everything - # IMPORTANT: the end point of each draw method must equal the start point - # of the next one in order to create one connected path. Only then the - # "finish" parameters will apply to all individual draws. - img.drawCurve(p1, p3, p2) - img.drawCurve(p2, p4, p5) - img.drawLine(p5, p6) - img.drawBezier(p6, p6 + d1, p7 + d1, p7) - img.drawLine(p7, d7) - img.drawLine(d7, p8) - img.drawBezier(p8, p8 + d1, p9 + d1, p9) - img.drawLine(p9, d9) - img.drawLine(d9, p10) - img.drawBezier(p10, p10 + d1, p11 + d1, p11) - img.drawLine(p11, d11) - img.drawLine(d11, p12) - img.drawBezier(p12, p12 + d1, p13 + d1, p13) - img.drawLine(p13, rect.bl) - img.finish(color = line, fill = skin, closePath = False, morph = morph) - return - -# ============================================================================= -# Pencil -# ============================================================================= -def pencil(img, penciltip, pb_height, left, morph = None): - """Draw a pencil image. Parameters: - img - Shape object - penciltip - fitz.Point, coordinates of the pencil tip - pb_height - the thickness of the pencil. This controls the dimension of the - picture: it will be contained in a rectangle of 100 x 345 pixels - if this parameter is 100. - left - bool, indicates whether the pencil points left (True) or right. - morph - a tuple (point, matrix) to achieve image torsion. - """ - from fitz.utils import getColor - from functools import partial - # define some colors - yellow = getColor("darkgoldenrod") - black = getColor("black") - white = getColor("white") - red = getColor("red") - wood = getColor("wheat2") - wood2 = getColor("wheat3") - #--------------------------------------------------------------------------- - # some adjustments depending on pencil tip is left or right: - # for choosing between a left point (lp) or a right point (rb), - # we specify oneof(lp, rp), delivering either lp or rp. Likewise, - # variable 's' is used as a sign and is either +1 or -1. - #--------------------------------------------------------------------------- - w = pb_height * 0.01 # standard line thickness - pb_width = 2 * pb_height # pencil body width - myfinish = partial(img.finish, width = w, morph = morph, closePath = False) - oneof = lambda l, r: l if left else r # choose an alternative - s = oneof(1,-1) - tipendtop = penciltip + fitz.Point(s, -0.5) * pb_height - tipendbot = penciltip + fitz.Point(s, 0.5) * pb_height - r = fitz.Rect(tipendtop, - tipendbot + (pb_width * s, 0)) # pencil body - r.normalize() # force r to be finite - # topline / botline indicate the pencil edges - topline0 = fitz.Point(r.x0 + r.width*0.1, - r.y0 + pb_height/5.) # upper pencil edge - left - topline1 = fitz.Point(r.x0 + r.width*0.9, - topline0.y) # upper epncil edge - right - botline0 = fitz.Point(r.x0 + r.width*0.1, - r.y1 - pb_height/5.) # lower pencil edge - left - botline1 = fitz.Point(r.x0 + r.width*0.9, - botline0.y) # lower pencil edge - right - - # control point 1 for pencil rubber - hp1 = oneof(r.tr, r.tl) + (pb_height*0.6*s, 0) - # control point 2 for pencil rubber - hp2 = oneof(r.br, r.bl) + (pb_height*0.6*s, 0) - # pencil body is some type of yellow - img.drawRect(r) - myfinish(fill = yellow, color = wood) - img.drawPolyline((r.tl, topline0, botline0, r.bl)) - img.drawPolyline((r.tr, topline1, botline1, r.br)) - myfinish(fill = wood, color = wood) - # draw pencil edge lines - img.drawLine(topline0, topline1) - img.drawLine(botline0, botline1) - myfinish(color = wood2) - - #=========================================================================== - # black rectangle near pencil rubber - #=========================================================================== - blackrect = fitz.Rect(oneof((r.tr - (pb_height/2., 0)), r.tl), - oneof(r.br, (r.bl + (pb_height/2., 0)))) - img.drawRect(blackrect) - myfinish(fill = black) - - #=========================================================================== - # draw the pencil rubber - #=========================================================================== - img.drawBezier(oneof(r.tr, r.tl), hp1, hp2, oneof(r.br, r.bl)) - myfinish(fill = red) - - #=========================================================================== - # draw pencil tip and curves indicating pencil sharpening traces - #=========================================================================== - img.drawPolyline((tipendtop, penciltip, tipendbot)) - myfinish(fill = wood) # pencil tip - p1 = tipendtop # either left or right - p2 = oneof(topline0, topline1) - p3 = oneof(botline0, botline1) - p4 = tipendbot - p0 = -fitz.Point(pb_height/5., 0)*s # horiz. displacment of ctrl points - cp1 = p1 + (p2-p1)*0.5 + p0 # ctrl point upper rounding - cp2 = p2 + (p3-p2)*0.5 + p0*2.9 # ctrl point middle rounding - cp3 = p3 + (p4-p3)*0.5 + p0 # ctrl point lower rounding - img.drawCurve(p1, cp1, p2) - myfinish(fill = yellow, color=yellow, closePath = True) - img.drawCurve(p2, cp2, p3) - myfinish(fill = yellow, color=yellow, closePath = True) - img.drawCurve(p3, cp3, p4) - myfinish(fill = yellow, color=yellow, closePath = True) - - #=========================================================================== - # draw the pencil tip lead - #=========================================================================== - img.drawPolyline((penciltip + (tipendtop - penciltip)*0.4, - penciltip, - penciltip + (tipendbot - penciltip)*0.4)) - #=========================================================================== - # add a curve to indicate lead is round - #=========================================================================== - img.drawCurve(penciltip + (tipendtop - penciltip)*0.4, - penciltip + (pb_height * 0.6 * s, 0), - penciltip + (tipendbot - penciltip)*0.4) - myfinish(fill = black) - - #=========================================================================== - # re-border pencil body to get rid of some pesky pixels - #=========================================================================== - img.drawPolyline((p1, p2, p3, p4)) - myfinish(color = yellow) - br_tl = oneof(blackrect.tl, blackrect.tr) - br_bl = oneof(blackrect.bl, blackrect.br) - img.drawPolyline((br_tl, tipendtop, penciltip, tipendbot, br_bl)) - myfinish() - #=========================================================================== - # draw pencil label - first a rounded rectangle - #=========================================================================== - p1 = fitz.Point(0.65, 0.15) * pb_height - p2 = fitz.Point(0.45, 0.15) * pb_height - lblrect = fitz.Rect(topline0 + oneof(p1, p2), - botline1 - oneof(p2, p1)) - img.drawRect(lblrect) - img.drawCurve(lblrect.tr, - fitz.Point(lblrect.x1+pb_height/4., penciltip.y), - lblrect.br) - img.drawCurve(lblrect.tl, - fitz.Point(lblrect.x0-pb_height/4., penciltip.y), - lblrect.bl) - myfinish(fill = black) - - #=========================================================================== - # finally the white vertical stripes - whatever they are good for - #=========================================================================== - p1t = blackrect.tl + (blackrect.width/3., pb_height/20.) - p1b = blackrect.bl + (blackrect.width/3., -pb_height/20.) - p2t = blackrect.tl + (blackrect.width*2/3., pb_height/20.) - p2b = blackrect.bl + (blackrect.width*2/3., -pb_height/20.) - img.drawLine(p1t, p1b) - img.drawLine(p2t, p2b) - img.finish(color = white, width = pb_height*0.08, roundCap = False, - morph = morph) - - # insert text to indicate a medium lead grade - if img.insertTextbox(lblrect, "HB", color = white, - fontname = "Helvetica", morph = morph, - fontsize = pb_height * 0.22, align = 1) < 0: - raise ValueError("not enough space to store 'HB' text") - return - -# ============================================================================= -# Smiley emoji -# ============================================================================= -def smiley(img, rect, color = (0,0,0), fill = (1,1,0), morph = None): - dx = rect.width * 0.2 - dy = rect.height * 0.25 - w = rect.width * 0.01 - img.drawOval(rect) # draw face - img.finish(fill = fill, width = w, morph = morph) - # calculate rectangles containing the eyes - rl = fitz.Rect(rect.tl + (dx, dy), - rect.tl + (2 * dx, 2 * dy)) - rr = fitz.Rect(rect.tr + (-2 * dx, dy), - rect.tr + (-dx, 2 * dy)) - img.drawOval(rl) # draw left eye - img.drawOval(rr) # draw right eye - img.finish(fill = color, morph = morph) - p0 = rl.bl + (0, 0.75 * dy) # left corner of mouth - p1 = rr.br + (0, 0.75 * dy) # right corner of mouth - c = rect.bl + (rect.br - rect.bl)*0.5 - img.drawCurve(p0, c, p1) # draw mouth - img.finish(width = 4 * w, closePath = False, morph = morph) - -# ============================================================================= -# Frowney emoji -# ============================================================================= -def frowney(img, rect, color = (0,0,0), fill = (1,1,0), morph = None): - dx = rect.width * 0.2 - dy = rect.height * 0.25 - w = rect.width * 0.01 - img.drawOval(rect) # draw face - img.finish(fill = fill, width = w, morph = morph) - # calculate rectangles containing the eyes - rl = fitz.Rect(rect.tl + (dx, dy), - rect.tl + (2 * dx, 2 * dy)) - rr = fitz.Rect(rect.tr + (-2 * dx, dy), - rect.tr + (-dx, 2 * dy)) - img.drawOval(rl) # draw left eye - img.drawOval(rr) # draw right eye - img.finish(fill = color, morph = morph) - p0 = rl.bl + (0, dy) # left corner of mouth - p1 = rr.br + (0, dy) # right corner of mouth - c = rl.bl + (rr.br - rl.bl)*0.5 - img.drawCurve(p0, c, p1) # draw mouth - img.finish(width = 4 * w, closePath = False, morph = morph) - -#------------------------------------------------------------------------------ -# Main program: -# Create PDF with one symbol per page which can be used by showPDFpage -#------------------------------------------------------------------------------ -if __name__ == "__main__": - green = getColor("limegreen") - red = getColor("red2") - doc = fitz.open() - p = doc.newPage() - img = p.newShape() - r = fitz.Rect(100, 100, 200, 200) - heart(img, r, red) - img.commit() - p.setCropBox(r + (10, 10, -10, -15)) - - p = doc.newPage() - img = p.newShape() - pnt = r.tl + (r.br - r.tl)*0.5 - clover(img, r, green, morph = (pnt, fitz.Matrix(45))) - img.commit() - p.setCropBox(r + (5, 5, -5, -5)) - - p = doc.newPage() - img = p.newShape() - diamond(img, r, red) - img.commit() - p.setCropBox(r) - - p = doc.newPage() - img = p.newShape() - pnt = r.tl + (r.br - r.tl)*0.5 - caro(img, r, red, morph = (pnt, fitz.Matrix(45))) - img.commit() - p.setCropBox(r + (10, 10, -10, -10)) - - p = doc.newPage() - img = p.newShape() - pnt = r.tl + (r.br - r.tl)*0.5 - arrow(img, r, red, morph = (pnt, fitz.Matrix(0))) - img.commit() - p.setCropBox(r) - - p = doc.newPage() - img = p.newShape() - dontenter(img, r, morph = None) - img.commit() - p.setCropBox(r + (-5, -5, 5, 5)) - - p = doc.newPage() - img = p.newShape() - rh = r + (0, 120, 30, 120) - hand(img, rh, morph = None) - cropbox = +img.rect + (0, 0, 0, 5) - img.commit() - p.setCropBox(cropbox) - - p = doc.newPage() - img = p.newShape() - smiley(img, r, morph = None) - cropbox = +img.rect + (-5, -5, 5, 5) - img.commit() - p.setCropBox(cropbox) - - p = doc.newPage() - img = p.newShape() - frowney(img, r, morph = None) - cropbox = +img.rect + (-5, -5, 5, 5) - img.commit() - p.setCropBox(cropbox) - - # create first pencil page (tip left) - page = doc.newPage() - img = page.newShape() - pencil(img, fitz.Point(100,150), 100, True) - cropbox = +img.rect + (-5, -5, -5, +5) - img.commit() - page.setCropBox(cropbox) - - # create second pencil page (tip right) - page = doc.newPage() - img = page.newShape() - pencil(img, fitz.Point(440,150), 100, False) - cropbox = +img.rect + (5, -5, 5, +5) - img.commit() - page.setCropBox(cropbox) - - m = {'title': "Signs and Symbols", - 'author': "Jorj X. McKie", - 'subject': "Create various symbols for use with showPDFpage()", - 'keywords': "symbols, shapes, signs", - 'creator': "shapes_and_symbols.py", - 'producer': "PyMuPDF", - 'creationDate': fitz.getPDFnow(), - 'modDate': fitz.getPDFnow()} - doc.setMetadata(m) - doc.save("symbols.pdf", garbage = 4, deflate= True) diff --git a/examples/symbols.pdf b/examples/symbols.pdf deleted file mode 100644 index cc2f6c547..000000000 Binary files a/examples/symbols.pdf and /dev/null differ diff --git a/nano_setup.py b/nano_setup.py new file mode 100644 index 000000000..fa1cf58e3 --- /dev/null +++ b/nano_setup.py @@ -0,0 +1,74 @@ +from distutils.core import setup, Extension +import sys, os + +# check the platform +if sys.platform.startswith('linux'): + module = Extension('fitz._fitz', # name of the module + ['fitz/fitz_wrap.c'], # C source file + include_dirs=[ # we need the path of the MuPDF and zlib headers + '/data/include/mupdf', + '/data/local/include/mupdf', + '/data/local/thirdparty/zlib', + ], + #library_dirs=['/usr/local/lib'], + libraries=[ + 'mupdf', + 'mupdf-third', + # 'jbig2dec', 'openjp2', 'jpeg', 'freetype', + # 'crypto', #openssl is required by mupdf on archlinux + ], # the libraries to link with + ) +elif sys.platform.startswith(('darwin', 'freebsd')): + module = Extension('fitz._fitz', # name of the module + ['fitz/fitz_wrap.c'], # C source file + # this are directories containing mupdf's and zlib's header files + include_dirs=['/data/local/include/mupdf', + '/data/local/include', + '/udatasr/local/thirdparty/zlib'], + library_dirs=['/data/local/lib'], + libraries=['mupdf', 'mupdf-third'] + ) + +else: +#=============================================================================== +# This will build / set up PyMuPDF under Windows. +# For details consult the documentation. +#=============================================================================== + module = Extension('fitz._fitz', + include_dirs=[ # we need the path of the MuPDF's headers + './mupdf/include', + './mupdf/include/mupdf', + './mupdf/thirdparty/zlib', + ], + libraries=[ # these are needed in Windows + 'libmupdf', 'libresources', + 'libthirdparty', + ], + extra_link_args=['/NODEFAULTLIB:MSVCRT'], + # x86 dir of libmupdf.lib etc. + library_dirs=['./mupdf/platform/win32/Release'], + # x64 dir of libmupdf.lib etc. + #library_dirs=['./mupdf/platform/win32/x64/Release'], + sources=['./fitz/fitz_wrap.c',]) + +setup(name = 'PyMuPDF', + version = "1.14.3", + description = 'Python bindings for the PDF rendering library MuPDF', + classifiers = ['Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', + 'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX :: Linux', + 'Operating System :: MacOS', + 'Programming Language :: C', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Topic :: Utilities'], + url = 'https://github.com/rk700/PyMuPDF', + author = 'Ruikai Liu, Jorj McKie', + author_email = 'lrk700@gmail.com', + license = 'GPLv3+', + ext_modules = [module], + py_modules = ['fitz.fitz', 'fitz.utils']) diff --git a/setup.py b/setup.py index 4fbae6a51..10c70f191 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ '/usr/local/include/mupdf', '/usr/local/thirdparty/zlib', ], - #library_dirs=['/usr/local/lib'], + #library_dirs=[''], libraries=[ 'mupdf', 'mupdf-third', @@ -22,10 +22,15 @@ module = Extension('fitz._fitz', # name of the module ['fitz/fitz_wrap.c'], # C source file # this are directories containing mupdf's and zlib's header files - include_dirs=['/usr/local/include/mupdf', - '/usr/local/include', - '/usr/local/thirdparty/zlib'], + include_dirs=['/usr/local/include/mupdf', '/usr/local/include'], + # libraries should already be linked here by brew library_dirs=['/usr/local/lib'], + #library_dirs=['/usr/local/Cellar/mupdf-tools/1.8/lib/', + #'/usr/local/Cellar/openssl/1.0.2g/lib/', + #'/usr/local/Cellar/jpeg/8d/lib/', + #'/usr/local/Cellar/freetype/2.6.3/lib/', + #'/usr/local/Cellar/jbig2dec/0.12/lib/' + #], libraries=['mupdf', 'mupdf-third'] ) @@ -51,21 +56,22 @@ #library_dirs=['./mupdf/platform/win32/x64/Release'], sources=['./fitz/fitz_wrap.c',]) +pkg_tab = open("PKG-INFO").read().split("\n") +long_dtab = [] +classifier = [] +for l in pkg_tab: + if l.startswith("Classifier: "): + classifier.append(l[12:]) + continue + if l.startswith(" "): + long_dtab.append(l.strip()) +long_desc = "\n".join(long_dtab) + setup(name = 'PyMuPDF', version = "1.14.6", description = 'Python bindings for the PDF rendering library MuPDF', - classifiers = ['Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', - 'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX :: Linux', - 'Operating System :: MacOS', - 'Programming Language :: C', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Topic :: Utilities'], + long_description = long_desc, + classifiers = classifier, url = 'https://github.com/rk700/PyMuPDF', author = 'Ruikai Liu, Jorj McKie', author_email = 'lrk700@gmail.com',