Skip to content

Commit 3765f17

Browse files
committed
upgrade to v1.16.18
1 parent 34d08bd commit 3765f17

17 files changed

+922
-375
lines changed

PKG-INFO

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Metadata-Version: 1.1
22
Name: PyMuPDF
3-
Version: 1.16.17
3+
Version: 1.16.18
44
Author: Ruikai Liu
55
Author-email: [email protected]
66
Maintainer: Jorj X. McKie
@@ -9,7 +9,7 @@ Home-page: https://github.com/pymupdf/PyMuPDF
99
Download-url: https://github.com/pymupdf/PyMuPDF
1010
Summary: PyMuPDF is a Python binding for the PDF rendering library MuPDF
1111
Description:
12-
Release date: March 31, 2020
12+
Release date: April 22, 2020
1313

1414
Authors
1515
=======

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# PyMuPDF 1.16.17
1+
# PyMuPDF 1.16.18
22

33
![logo](https://github.com/pymupdf/PyMuPDF/blob/master/demo/pymupdf.jpg)
44

5-
Release date: March 31, 2020
5+
Release date: April 22, 2020
66

77
**Travis-CI:** [![Build Status](https://travis-ci.org/JorjMcKie/py-mupdf.svg?branch=master)](https://travis-ci.org/JorjMcKie/py-mupdf)
88

@@ -14,7 +14,7 @@ On **[PyPI](https://pypi.org/project/PyMuPDF)** since August 2016: [![](https://
1414

1515
# Introduction
1616

17-
This is **version 1.16.17 of PyMuPDF (formerly python-fitz)**, a Python binding with support for [MuPDF 1.16.*](http://mupdf.com/) - "a lightweight PDF, XPS, and E-book viewer".
17+
This is **version 1.16.18 of PyMuPDF (formerly python-fitz)**, a Python binding with support for [MuPDF 1.16.*](http://mupdf.com/) - "a lightweight PDF, XPS, and E-book viewer".
1818

1919
MuPDF can access files in PDF, XPS, OpenXPS, CBZ, EPUB and FB2 (e-books) formats, and it is known for its top performance and high rendering quality.
2020

docs/changes.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
Change Logs
22
===============
33

4+
Changes in Version 1.16.18
5+
---------------------------
6+
This version introduces several new features around PDF text output. The motivation is to simplify this task, while at the same time offering extending features.
7+
8+
One major achievement is using MuPDF's capabilities to dynamically choosing fallback fonts whenever a character cannot be found in the predefined one. This seemlessly works for Base-14 fonts in combination with CJK fonts (China, Japan, Korea).
9+
10+
* **Fixed** issue `#493 <https://github.com/pymupdf/PyMuPDF/issues/493>`_. ``Pixmap(doc, xref)`` should now again correctly resemble the loaded image object.
11+
* **Fixed** issue `#488 <https://github.com/pymupdf/PyMuPDF/issues/488>`_. Widget names are now modifyable.
12+
* **Added** new class :ref:`Font` which represents a font.
13+
* **Added** new class :ref:`TextWriter` which serves as a container for text to be written on a page.
14+
* **Added** :meth:`Page.writeText` to write one or more :ref:`TextWriter` objects to the page.
15+
16+
417
Changes in Version 1.16.17
518
---------------------------
619

docs/classes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Classes
99
colorspace.rst
1010
displaylist.rst
1111
document.rst
12+
font.rst
1213
identity.rst
1314
irect.rst
1415
link.rst
@@ -22,5 +23,6 @@ Classes
2223
rect.rst
2324
shape.rst
2425
textpage.rst
26+
textwriter.rst
2527
tools.rst
2628
widget.rst

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
# built documents.
4747
#
4848
# The full version, including alpha/beta/rc tags.
49-
release = "1.16.17"
49+
release = "1.16.18"
5050

5151
# The short X.Y version
5252
version = release

docs/font.rst

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
.. _Font:
2+
3+
================
4+
Font
5+
================
6+
7+
*(New in v1.16.18)* This class represents a font as defined in MuPDF (*fz_font_s* structure). It is required for the new class :ref:`TextWriter` and the new :meth:`Page.writeText`. Currently, it has no connection to how fonts are used in methods ``insertText`` or insertTextbox``, respectively.
8+
9+
A Font object also contains useful general information, like the font bbox, the number of defined glyphs, glyph names or the bbox of a single glyph.
10+
11+
**Class API**
12+
13+
.. class:: Font
14+
15+
.. method:: __init__(self, fontname=None, fontfile=None,
16+
fontbuffer=None, script=0, language=None, ordering=-1, is_bold=0,
17+
is_italic=0, is_serif=0)
18+
19+
Font constructor. The large number of parameters are used to locate font, which most closely resembles the requirements. Not all parameters are ever required -- see the below pseudo code explaining the logic how the parameters are evaluated.
20+
21+
:arg str fontname: one of the :ref:`Base-14-Fonts` or CJK fontnames. Also possible are a select few of other names like (watch the correct spelling): "Arial", "Times", "Times Roman".
22+
:arg str filename: the filename of a fontfile somewhere on your system [#f1]_.
23+
:arg bytes,bytearray,io.BytesIO fontbuffer: a fontfile loaded in memory [#f1]_.
24+
:arg in script: the number of a UCDN script. Currently supported in PyMuPDF are numbers 24, and 32 through 35.
25+
:arg str language: one of the values "zh-Hant" (traditional Chinese), "zh-Hans" (simplified Chinese), "ja" (Japanese) and "ko" (Korean). Otherwise, all ISO 639 codes from the subsets 1, 2, 3 and 5 are also possible, but are currently documentary only.
26+
:arg int ordering: an alternative selector for one of the CJK fonts.
27+
:arg bool is_bold: look for a bold font.
28+
:arg bool is_italic: look for an italic font.
29+
:arg bool is_serif: look for a serifed font.
30+
31+
:returns: a MuPDF font if successful. This is the overall logic, how an appropriate font is located::
32+
33+
if fontfile:
34+
create font from it ignoring other arguments
35+
if not successful -> exception
36+
if fonbuffer:
37+
create font from it ignoring other arguments
38+
if not successful -> exception
39+
if ordering >= 0:
40+
load **"universal"** font ignoring other parameters
41+
# this will always be successful
42+
if fontname:
43+
create a Base14 font, or resp. **"universal"** font, ignoring other parameters
44+
# note: values "Arial", "Times", "Times Roman" are also possible
45+
if not successful -> exception
46+
Finally try to load a "NOTO" font using *script* and *language* parameters.
47+
if not successful:
48+
look for fallback font
49+
50+
.. note::
51+
52+
With the usual abbreviations "helv", "tiro", etc., you will create fonts with the expected names "Helvetica", "Times-Roman" and so on.
53+
54+
Using *ordering >= 0*, or fontnames starting with "china", "japan" or "korea" will always create the same **"universal"** font **"Droid Sans Fallback Regular"**. This font supports **all CJK and all Latin characters**.
55+
56+
Actually, you would rarely ever need another font than **"Droid Sans Fallback Regular"**. **Except** that this font file is relatively large and adds about 1.65 MB (compressed) to your PDF file size. If you do not need CJK support, stick with specifying "helv", "tiro" etc., and you will get away with about 35 KB compressed.
57+
58+
If you **know** you have a mixture of CJK and Latin text, consider just using ``Font(ordering=0)`` because this supports everything and also significantly (by a factor of two to three) speeds up execution: MuPDF will always find any character in this single font and need not check fallbacks.
59+
60+
But if you do specify a Base-14 fontname, you will still be able to also write CJK characters! MuPDF automatically detects this situation and silently falls back to the universal font (which will then of course also be included in your PDF).
61+
62+
**All fonts mentioned here** also support Greek and Cyrillic letters.
63+
64+
*Monospaced* fonts are an issue: They are written with a too large width, e.g. ``" a"`` instead of ``"a"``. This applies to "cour" variants as well as most other mono fonts. The only exception we know of so far is ``consola.ttf``. If you want to output monospaced text, we recommend using the Consolas font for the time being.
65+
66+
.. method:: has_glyph(chr, language=None, script=0)
67+
68+
Check whether the unicode *chr* exists in the font or some fallback. May be used to check whether any "TOFU" symbols will appear on output.
69+
70+
:arg int chr: the unicode of the character (i.e. *ord()*).
71+
:arg str language: the language -- currently unused.
72+
:arg int script: the UCDN script number.
73+
:returns: *True* or *False*.
74+
75+
.. method:: glyph_advance(chr, language=None, script=0, wmode=0)
76+
77+
Calculate the "width" of the character's glyph (visual representation).
78+
79+
:arg int chr: the unicode number of the character. Use ``ord(c)``, not the character itself. Again, this should normally work even if a character is not supported by that font, because fallback fonts will be checked where necessary.
80+
81+
The other parameters are not in use currently. This especially means that only horizontal text writing is supported.
82+
83+
:returns: a float representing the glyph's width relative to **fontsize 1**.
84+
85+
.. method:: glyph_name_to_unicode(name)
86+
87+
Return the unicode for a given glyph name. Use it in conjunction with ``chr()`` if you want to output e.g. a certain symbol.
88+
89+
:arg str name: The name of the glyph.
90+
91+
:returns: The unicode integer, or 65533 = 0xFFFD if the name is unknown. Examples: ``font.glyph_name_to_unicode("Sigma") = 931``, ``font.glyph_name_to_unicode("sigma") = 963``. Refer to e.g. `this <https://github.com/adobe-type-tools/agl-aglfn/blob/master/glyphlist.txt>`_ publication for a list of glyph names and their unicode numbers.
92+
93+
.. method:: unicode_to_glyph_name(chr, language=None, script=0, wmode=0)
94+
95+
Show the name of the character's glyph.
96+
97+
:arg int chr: the unicode number of the character. Use ``ord(c)``, not the character itself.
98+
99+
:returns: a string representing the glyph's name. E.g. ``font.glyph_name(ord("#")) = "numbersign"``. Depending on how this font was built, the string may be empty, ".notfound" or some generated name.
100+
101+
.. method:: text_length(text, fontsize=11)
102+
103+
Calculate the length of a unicode string.
104+
105+
:arg str text: a text string -- UTF-8 encoded. For Python 2, you must use unicode here.
106+
107+
:arg float fontsize: the fontsize.
108+
109+
:returns: a float representing the length of the string when stored in the PDF. Internally :meth:`glyph_advance` is used on a by-character level. If the font does not have a character, it will automatically be looked up in a fallback font.
110+
111+
.. attribute:: flags
112+
113+
A dictionary with various font properties, each represented as bools.
114+
115+
.. attribute:: name
116+
117+
Name of the font. May be "" or "(null)".
118+
119+
.. attribute:: glyph_count
120+
121+
The number of glyphs defined in the font.
122+
123+
.. rubric:: Footnotes
124+
125+
.. [#f1] MuPDF does not support all fontfiles with this feature and will raise exceptions like *"mupdf: FT_New_Memory_Face((null)): unknown file format"*, if encounters issues.

docs/page.rst

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,15 @@ This is available for PDF documents only. There are basically two groups of meth
7474
:meth:`Page.links` return a generator of the links on the page
7575
:meth:`Page.load_annot` PDF only: load an annotation identified by its name
7676
:meth:`Page.loadLinks` return the first link on a page
77-
:meth:`Page.newShape` PDF only: start a new :ref:`Shape`
77+
:meth:`Page.newShape` PDF only: create a new :ref:`Shape`
7878
:meth:`Page.searchFor` search for a string
7979
:meth:`Page.setCropBox` PDF only: modify the visible page
8080
:meth:`Page.setMediaBox` PDF only: modify the mediabox
8181
:meth:`Page.setRotation` PDF only: set page rotation
8282
:meth:`Page.showPDFpage` PDF only: display PDF page image
8383
:meth:`Page.updateLink` PDF only: modify a link
8484
:meth:`Page.widgets` return a generator over the fields on the page
85+
:meth:`Page.writeText` write one or more :ref:`Textwriter` objects
8586
:attr:`Page.CropBox` the page's :data:`CropBox`
8687
:attr:`Page.CropBoxPosition` displacement of the :data:`CropBox`
8788
:attr:`Page.firstAnnot` first :ref:`Annot` on the page
@@ -394,6 +395,23 @@ This is available for PDF documents only. There are basically two groups of meth
394395
:returns: a :ref:`Widget` for each iteration.
395396

396397

398+
.. method:: writeText(rect=None, writers=None, overlay=True, color=None, opacity=None, keep_proportion=True, rotate=0)
399+
400+
*(New in version 1.16.18)*
401+
402+
PDF only: Write the text of one or more :ref:`Textwriter` ojects to the page.
403+
404+
:arg rect_like rect: where to place the text. If omitted, the rectangle union of the text writers is used.
405+
:arg sequence writers: a non-empty tuple / list of :ref:`TextWriter` objects or a single :ref:`TextWriter`.
406+
:arg float opacity: set transparency, overwrites resp. value in the text writers.
407+
:arg sequ color: set the text color, overwrites resp. value in the text writers.
408+
:arg bool overlay: put the text in foreground or background.
409+
:arg bool keep_proportion: maintain the aspect ratio.
410+
:arg float rotate: rotate the text by an arbitrary angle.
411+
412+
.. note:: Parameters overlay, keep_proportion and rotate have the same meaning as in :ref:`showPDFpage`.
413+
414+
397415
.. index::
398416
pair: border_width; insertText
399417
pair: color; insertText
@@ -932,6 +950,7 @@ This is available for PDF documents only. There are basically two groups of meth
932950
:rtype: :ref:`Shape`
933951
:returns: a new :ref:`Shape` to use for compound drawings. See description there.
934952

953+
935954
.. index::
936955
pair: flags; searchFor
937956
pair: hit_max; searchFor

docs/textwriter.rst

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
.. _TextWriter:
2+
3+
================
4+
TextWriter
5+
================
6+
7+
*(New in v1.16.18)* This class represents a MuPDF *text* object. It can be thought of as a store of text spans -- each span having its own position, font and font size. It is an elegant alternative for writing text to PDF pages, when compared with methods :meth:`Page.insertText` and friends:
8+
9+
* **Improved text positioning:** The position of the last inserted character is returned, as well as the combined rectangle of text stored so far.
10+
* **Automatic fallback fonts:** If a character is not represented by the chosen font, alternative fonts are automatically checked. This significantly reduces the risk of seeing unprintable symbols in the output, so-called "TOFUs". PyMuPDF now also comes with a **"universal"** font, which supports **all Latin** characters (incuding Cyrillic and Greek), and **all CJK** characters (Chinese, Japanese, Korean).
11+
* **Reusability:** A TextWriter exists independent from any page. The same text can be written multiple times, to the same or other pages, same or different PDFs, choosing different colors or transparency.
12+
* **Transparency support:** Parameter *opacity* is supported. This offers a handy way to write watermark-style text.
13+
* **Justified text:** Supported for any font -- not just simple fonts as in :meth:`Page.insertText`.
14+
15+
Using this object entails three steps:
16+
17+
1. When **created**, a TextWriter object requires a fixed **page rectangle** in relation to which it calculates text positions. Pages with different dimensions cannot use this TextWriter object.
18+
2. Store text in the TextWriter using method either :meth:`TextWriter.append` or :meth:`TextWriter.fillTextbox`.
19+
3. Output the stored text on any PDF page with the same rectangle. This is the only point, where pages are referenced.
20+
21+
TextWriters do not support text rotation. But the new method :meth:`Page.writeText` is able to combine one or more TextWriters and jointly write them to **any rectangle** and with **any rotation angle** -- much like :meth:`Page.showPDFpage`.
22+
23+
**Class API**
24+
25+
.. class:: TextWriter
26+
27+
.. method:: __init__(self, rect, opacity=1, color=None)
28+
29+
:arg rect-like rect: rectangle internally used for text positioning computations.
30+
:arg float opacity: sets the transparency for the text to store here. Values outside the interval ``[0, 1)`` will be ignored. A value of e.g. 0.5 means 50% transparency.
31+
:arg float,sequ color: the color of the text. All colors are specified as floats *0 <= color <= 1*. A single float represents some gray level, a sequence implies the colorspace via its length.
32+
33+
34+
.. method:: append(pos, text, font=None, fontsize=11, language=None)
35+
36+
Add new text, usually (but not necessarily) representing a text span.
37+
38+
:arg point_like pos: start position of the text, the bottom left point of the first character.
39+
:arg str text: a string (Python 2: unicode is mandatory!) of arbitrary length. It will be written starting at position "pos".
40+
:arg font: a :ref:`Font`. If omitted, ``fitz.Font("helv")`` will be used.
41+
:arg float fontsize: the fontsize, a positive number, default 11.
42+
:arg str language: the language to use, e.g. "en" for English. Meaningful values should be compliant with the ISO 639 standards 1, 2, 3 or 5. Reserved for future use: currently has no effect as far as we know.
43+
44+
:returns: :attr:`textRect` and :attr:`lastPoint` after this text has been added.
45+
46+
47+
.. method:: fillTextbox(rect, text, font="helv", fontsize=11, align=0, warn=True)
48+
49+
Fill a given rectangle with text. This is a convenience method to use instead of :meth:`append` (which is internally invoked).
50+
51+
:arg rect_like rect: the area to fill. No part of the text will appear outside of this.
52+
:arg str,sequ text: the text. Can be specified as a (UTF-8) string or a list / tuple of strings. A string will first be converted to a list using *splitlines()*. Every list item will begin on a new line (forced line breaks).
53+
:arg font: the :ref:`Font`
54+
:arg float fontsize: the fontsize.
55+
:arg int align: text alignment. Use one of TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT or TEXT_ALIGN_JUSTIFY.
56+
:arg bool warn: print a warning if the area is too small, or raise an exception.
57+
58+
.. method:: writeText(page, opacity=None, color=None, overlay=True)
59+
60+
Write the accumulated text to the page.
61+
62+
:arg page: write to this :ref:`Page`.
63+
:arg float opacity: overwrite the value of the TextWriter for this output.
64+
:arg sequ color: overwrite the value of the TextWriter for this output.
65+
:arg bool overlay: put in foreground (default) or background.
66+
67+
68+
.. attribute:: textRect
69+
70+
The area currently occupied. This value changes when more text is added.
71+
72+
.. attribute:: lastPoint
73+
74+
The "cursor position" after the last written character.
75+
76+
.. attribute:: opacity
77+
78+
The text opacity (modifyable).
79+
80+
.. attribute:: color
81+
82+
The text color (modifyable).
83+
84+
.. attribute:: rect
85+
86+
The rectangle for which this TextWriter was created. Must not be modified.
87+
88+
.. note::
89+
90+
1. Opacity and color apply to **all the text** in this object.
91+
2. If you need different colors / transpareny, you must create a separate TextWriter. Whenever you determine the color should change, simply append the text to the respective TextWriter using the previously returned :attr:`lastPoint` as position for the new text.
92+
3. Appending items can occur in arbitrary order: only the position parameter controls where text appears.
93+
4. Font and fontsize can freely vary within the same TextWriter. This can be used to let text with different properties appear on the same displayed line: just specify *pos* accordingly, and e.g. set it to :attr:`lastPoint` of the previously added item.

docs/version.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Covered Version
22
--------------------
33

4-
This documentation covers PyMuPDF v1.16.17 features as of **2020-03-31 08:53:33**.
4+
This documentation covers PyMuPDF v1.16.18 features as of **2020-04-22 14:00:00**.
55

66
.. note:: The major and minor versions of **PyMuPDF** and **MuPDF** will always be the same. Only the third qualifier (patch level) may be different from that of MuPDF.

0 commit comments

Comments
 (0)