Skip to content

Commit 10341ce

Browse files
committed
upload v1.17.6
1 parent 8d85e74 commit 10341ce

File tree

14 files changed

+178
-143
lines changed

14 files changed

+178
-143
lines changed

PKG-INFO

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Metadata-Version: 1.1
22
Name: PyMuPDF
3-
Version: 1.17.5
3+
Version: 1.17.6
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: August 6, 2020
12+
Release date: August 26, 2020
1313

1414
Authors
1515
=======
@@ -20,7 +20,7 @@ Description:
2020
Introduction
2121
============
2222

23-
This is **version 1.17.5 of PyMuPDF**, a Python binding for `MuPDF <http://mupdf.com/>`_ - "a lightweight PDF and XPS viewer".
23+
This is **version 1.17.6 of PyMuPDF**, a Python binding for `MuPDF <http://mupdf.com/>`_ - "a lightweight PDF and XPS viewer".
2424

2525
MuPDF can access files in PDF, XPS, OpenXPS, epub, comic and fiction book formats, and it is known for both, its top performance and high rendering quality.
2626

README.md

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

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

5-
Release date: August 6, 2020
5+
Release date: August 26, 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.17.5 of PyMuPDF**, a Python binding with support for [MuPDF 1.17.*](http://mupdf.com/) - "a lightweight PDF, XPS, and E-book viewer".
17+
This is **version 1.17.6 of PyMuPDF**, a Python binding with support for [MuPDF 1.17.*](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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
Change Logs
22
===============
33

4+
Changes in Version 1.17.6
5+
---------------------------
6+
* **Fixed** issue `#605 <https://github.com/pymupdf/PyMuPDF/issues/605>`_
7+
* **Fixed** issue `#600 <https://github.com/pymupdf/PyMuPDF/issues/600>`_ -- text should now be correctly positioned also for pages with a CropBox smaller than MediaBox.
8+
* **Added** text span dictionary key ``origin`` which contains the lower left coordinate of the first character in that span.
9+
* **Added** attribute :attr:`Font.buffer`, a *bytes* copy of the font file.
10+
* **Added** parameter *sanitize* to :meth:`Page.cleanContents`. Allows switching of sanitization, so only syntax cleaning will be done.
11+
412
Changes in Version 1.17.5
513
---------------------------
614
* **Fixed** issue `#561 <https://github.com/pymupdf/PyMuPDF/issues/561>`_ -- second go: certain :ref:`TextWriter` usages with many alternating fonts did not work correctly.

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
# built documents.
4343
#
4444
# The full version, including alpha/beta/rc tags.
45-
release = "1.17.5"
45+
release = "1.17.6"
4646

4747
# The short X.Y version
4848
version = release

docs/font.rst

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,13 @@ A Font object also contains useful general information, like the font bbox, the
6969

7070
*(New in v1.17.5)* Optionally, some new "reserved" fontnames become available if you install `pymupdf-fonts <https://pypi.org/project/pymupdf-fonts/>`_. **"Fira Mono"** is a nice mono-spaced sans font set and **FiraGO** is another non-serifed "universal" font, set which supports all European languages (including Cyrillic and Greek) plus Thai, Arabian, Hewbrew and Devanagari -- however none of the CJK languages. The size of a FiraGO font is only a quarter of the "Droid Sans Fallback" size (compressed 400 KB vs. 1.65 MB) -- **and** it provides the style variants bold, italic, bold-italic.
7171

72-
**"Space Mono"** is another nice and small fixed-width font from Google Fonts, which supports Latin Extended characters.
72+
**"Space Mono"** is another nice and small fixed-width font from Google Fonts, which supports Latin Extended characters and comes with all 4 important font weights.
7373

7474
The following table maps a fontname to the corresponding font:
7575

76-
=========== =========================== ==============
77-
Fontname Font Added in
78-
=========== =========================== ==============
76+
=========== =========================== ======= =============================
77+
Fontname Font New in Comment
78+
=========== =========================== ======= =============================
7979
figo FiraGO Regular v1.0.0
8080
figbo FiraGO Bold v1.0.0
8181
figit FiraGO Italic v1.0.0
@@ -86,11 +86,11 @@ A Font object also contains useful general information, like the font bbox, the
8686
spacembo Space Mono Bold v1.0.1
8787
spacemit Space Mono Italic v1.0.1
8888
spacembi Space Mono Bold-Italic v1.0.1
89-
math Noto Sans Math Regular v1.0.2
90-
music Noto Music Regular v1.0.2
91-
symbol1 Noto Sans Symbols Regular v1.0.2
92-
symbol2 Noto Sans Symbols2 Regular v1.0.2
93-
=========== =========================== ==============
89+
math Noto Sans Math Regular v1.0.2 math symbols
90+
music Noto Music Regular v1.0.2 musical symbols
91+
symbol1 Noto Sans Symbols Regular v1.0.2 replacemt for "symb"
92+
symbol2 Noto Sans Symbols2 Regular v1.0.2 extended symbol set
93+
=========== =========================== ======= =============================
9494

9595

9696
.. method:: has_glyph(chr, language=None, script=0, fallback=False)
@@ -105,7 +105,9 @@ A Font object also contains useful general information, like the font bbox, the
105105

106106
.. method:: valid_codepoints()
107107

108-
*(New in v1.17.5)* Return an array of unicodes which are supported by this font.
108+
*(New in v1.17.5)*
109+
110+
Return an array of unicodes supported by this font.
109111

110112
:returns: an *array.array* [#f2]_ of length :attr:`Font.glyph_count` (or less). I.e. *chr()* of every item in this array will be found in the font without using fallbacks. This is an example display of the supported glyphs:
111113

@@ -176,6 +178,12 @@ A Font object also contains useful general information, like the font bbox, the
176178

177179
: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.
178180

181+
.. attribute:: buffer
182+
183+
*(New in v1.17.6)*
184+
185+
A *bytes* copy of the binary font file.
186+
179187
.. attribute:: flags
180188

181189
A dictionary with various font properties, each represented as bools.

docs/functions.rst

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,13 +451,17 @@ Yet others are handy, general-purpose utilities.
451451

452452
-----
453453

454-
.. method:: Page.cleanContents()
454+
.. method:: Page.cleanContents(sanitize=True)
455455

456-
Clean and concatenate all :data:`contents` objects associated with this page. "Cleaning" includes syntactical corrections, standardizations and "pretty printing" of the contents stream. Discrepancies between :data:`contents` and :data:`resources` objects will also be corrected. See :meth:`Page._getContents` for more details.
456+
*(Changed in v1.17.6)*
457+
458+
PDF only: Clean and concatenate all :data:`contents` objects associated with this page. "Cleaning" includes syntactical corrections, standardizations and "pretty printing" of the contents stream. Discrepancies between :data:`contents` and :data:`resources` objects will also be corrected if sanitize is true. See :meth:`Page.getContents` for more details.
457459

458460
Changed in version 1.16.0 Annotations are no longer implicitely cleaned by this method. Use :meth:`Annot._cleanContents` separately.
459461

460-
.. warning:: This is a complex function which may generate large amounts of new data and render other data unused. It is **not recommended** using it together with the **incremental save** option. Also note that the resulting singleton new */Contents* object is **uncompressed**. So you should save to a **new file** using options *"deflate=True, garbage=3"*.
462+
:arg bool sanitize: *(new in v1.17.6)* if true, synchronization between resources and their actual use in the contents object is snychronized. For example, if a font is not actually used for any text of the page, then it will be deleted from the ``/Resources/Font`` object.
463+
464+
.. warning:: This is a complex function which may generate large amounts of new data and render old data unused. It is **not recommended** using it together with the **incremental save** option. Also note that the resulting singleton new */Contents* object is **uncompressed**. So you should save to a **new file** using options *"deflate=True, garbage=3"*.
461465

462466
-----
463467

@@ -471,7 +475,7 @@ Yet others are handy, general-purpose utilities.
471475

472476
.. method:: Annot._cleanContents()
473477

474-
Clean the :data:`contents` streams associated with the annotation. This is the same type of action which :meth:`Page._cleanContents` performs -- just restricted to this annotation.
478+
Clean the :data:`contents` streams associated with the annotation. This is the same type of action which :meth:`Page.cleanContents` performs -- just restricted to this annotation.
475479

476480

477481
-----

docs/pixmap.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,6 @@ psd gray, rgb, cmyk yes .psd Adobe Photoshop Document
450450

451451
.. rubric:: Footnotes
452452

453-
.. [#f1] If you need a **vector image** from the SVG, you must first convert it to a PDF. Try :meth:`Document.convertToPDF`. If this is not not good enough, look for other SVG-to-PDF conversion tools like the Python packages `svglib <https://pypi.org/project/svglib>`_, `CairoSVG <https://pypi.org/project/cairosvg>`_, `Uniconvertor <https://sk1project.net/modules.php?name=Products&product=uniconvertor&op=download>`_ or the Java solution `Apache Batik <https://github.com/apache/batik>`_. Have a look at our Uncyclo for more examples.
453+
.. [#f1] If you need a **vector image** from the SVG, you must first convert it to a PDF. Try :meth:`Document.convertToPDF`. If this is not good enough, look for other SVG-to-PDF conversion tools like the Python packages `svglib <https://pypi.org/project/svglib>`_, `CairoSVG <https://pypi.org/project/cairosvg>`_, `Uniconvertor <https://sk1project.net/modules.php?name=Products&product=uniconvertor&op=download>`_ or the Java solution `Apache Batik <https://github.com/apache/batik>`_. Have a look at our Uncyclo for more examples.
454454
455455
.. [#f2] To also set the alpha property, add an additional step to this method by dropping or adding an alpha channel to the result.

docs/textpage.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,13 @@ Span Dictionary
204204
Spans contain the actual text. A line contains **more than one span only**, if it contains text with different font properties.
205205

206206
*(Changed in version 1.14.17)* Spans now also have a *bbox* key (again).
207+
*(Changed in version 1.17.6)* Spans now also have an *origin* key.
207208

208209
=============== =====================================================================
209210
**Key** **Value**
210211
=============== =====================================================================
211212
bbox span rectangle, formatted as *tuple(fitz.Rect)*
213+
origin *tuple* coordinates of the first character's bottom left point
212214
font font name *(str)*
213215
size font size *(float)*
214216
flags font characteristics *(int)*
@@ -219,7 +221,7 @@ chars (only for :meth:`extractRAWDICT`) *list* of character dictionari
219221

220222
*(New in version 1.16.0)*
221223

222-
*"color"* is the text color encoded in sRGB format, e.g. 0xFF0000 for red.
224+
*"color"* is the text color encoded in sRGB (int) format, e.g. 0xFF0000 for red. There are functions for converting this integer back to formats (r, g, b) (PDF with float values from 0 to 1) :meth:`sRGB_to_pdf`, or (R, G, B), :meth:`sRGB_to_rgb` (with integer values from 0 to 255).
223225

224226
*"flags"* is an integer, encoding bools of font properties:
225227

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.17.5 features as of **2020-08-06 06:31:06**.
4+
This documentation covers PyMuPDF v1.17.6 features as of **2020-08-26 14:54:32**.
55

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

fitz/fitz.i

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3051,7 +3051,7 @@ struct Page {
30513051
"""Get rectangle occupied by image 'name'.
30523052

30533053
'name' is either an item of the image full list, or the referencing
3054-
name string."""
3054+
name string - elem[7] of the resp. item."""
30553055
CheckParent(self)
30563056
doc = self.parent
30573057
if doc.isClosed or doc.isEncrypted:
@@ -3112,6 +3112,7 @@ struct Page {
31123112
// Page.getTextPage
31133113
//---------------------------------------------------------------------
31143114
FITZEXCEPTION(_get_text_page, !result)
3115+
%pythonappend _get_text_page %{val.thisown = True%}
31153116
struct TextPage *
31163117
_get_text_page(int flags=0)
31173118
{
@@ -4059,6 +4060,7 @@ struct Page {
40594060
40604061
CheckParent(self)
40614062
%}
4063+
%pythonappend getDisplayList %{val.thisown = True%}
40624064
struct DisplayList *getDisplayList(int annots=1)
40634065
{
40644066
fz_display_list *dl = NULL;
@@ -4502,11 +4504,10 @@ except:
45024504
// Page clean contents stream
45034505
//---------------------------------------------------------------------
45044506
PARENTCHECK(_cleanContents, """Clean page /Contents object(s).""")
4505-
PyObject *_cleanContents()
4507+
PyObject *_cleanContents(int sanitize=0)
45064508
{
45074509
pdf_page *page = pdf_page_from_fz_page(gctx, (fz_page *) $self);
4508-
if (!page)
4509-
{
4510+
if (!page) {
45104511
return_none;
45114512
}
45124513
pdf_filter_options filter = {
@@ -4519,7 +4520,8 @@ except:
45194520
1, // instance forms
45204521
1, // sanitize plus filtering
45214522
0 // do not ascii-escape binary data
4522-
};
4523+
};
4524+
filter.sanitize = sanitize;
45234525
fz_try(gctx) {
45244526
pdf_filter_page_contents(gctx, page->doc, page, &filter);
45254527
}
@@ -5139,8 +5141,10 @@ def insertFont(self, fontname="helv", fontfile=None, fontbuffer=None,
51395141
def MediaBoxSize(self):
51405142
return Point(self.MediaBox.width, self.MediaBox.height)
51415143
5142-
def cleanContents(self):
5143-
self._cleanContents()
5144+
def cleanContents(self, sanitize=True):
5145+
if not sanitize and not self._isWrapped:
5146+
self.wrapContents()
5147+
self._cleanContents(sanitize)
51445148
51455149
getContents = _getContents
51465150
%}
@@ -7545,7 +7549,7 @@ struct Annot
75457549
//---------------------------------------------------------------------
75467550
FITZEXCEPTION(_cleanContents, !result)
75477551
PARENTCHECK(_cleanContents, """Clean appearance contents object.""")
7548-
PyObject *_cleanContents()
7552+
PyObject *_cleanContents(int sanitize=0)
75497553
{
75507554
pdf_annot *annot = (pdf_annot *) $self;
75517555
pdf_filter_options filter = {
@@ -7556,9 +7560,10 @@ struct Annot
75567560
NULL, // end page
75577561
1, // recurse: true
75587562
1, // instance forms
7559-
1, // only sanitize, no filtering
7563+
1, // sanitize,
75607564
0 // do not ascii-escape binary data
7561-
};
7565+
};
7566+
filter.sanitize = sanitize;
75627567
fz_try(gctx) {
75637568
pdf_filter_annot_contents(gctx, annot->page->doc, annot, &filter);
75647569
}
@@ -7926,6 +7931,7 @@ struct DisplayList {
79267931
DEBUGMSG2;
79277932
}
79287933
FITZEXCEPTION(DisplayList, !result)
7934+
%pythonappend DisplayList %{self.thisown = True%}
79297935
DisplayList(PyObject *mediabox)
79307936
{
79317937
fz_display_list *dl = NULL;
@@ -7964,9 +7970,10 @@ struct DisplayList {
79647970
// DisplayList.getPixmap
79657971
//---------------------------------------------------------------------
79667972
FITZEXCEPTION(getPixmap, !result)
7973+
%pythonappend getPixmap %{val.thisown = True%}
79677974
struct Pixmap *getPixmap(PyObject *matrix=NULL,
79687975
struct Colorspace *colorspace=NULL,
7969-
int alpha=1,
7976+
int alpha=0,
79707977
PyObject *clip=NULL)
79717978
{
79727979
fz_colorspace *cs = NULL;
@@ -7990,6 +7997,7 @@ struct DisplayList {
79907997
// DisplayList.getTextPage
79917998
//---------------------------------------------------------------------
79927999
FITZEXCEPTION(getTextPage, !result)
8000+
%pythonappend getTextPage %{val.thisown = True%}
79938001
struct TextPage *getTextPage(int flags = 3)
79948002
{
79958003
fz_display_list *this_dl = (fz_display_list *) $self;
@@ -8007,7 +8015,9 @@ struct DisplayList {
80078015
%pythoncode %{
80088016
def __del__(self):
80098017
if not type(self) is DisplayList: return
8010-
self.__swig_destroy__(self)
8018+
if getattr(self, "thisown", False):
8019+
self.__swig_destroy__(self)
8020+
self.thisown = False
80118021
%}
80128022
}
80138023
};
@@ -8025,6 +8035,7 @@ struct TextPage {
80258035
}
80268036
80278037
FITZEXCEPTION(TextPage, !result)
8038+
%pythonappend TextPage %{self.thisown = True%}
80288039
TextPage(PyObject *mediabox)
80298040
{
80308041
fz_stext_page *tp = NULL;
@@ -8350,7 +8361,9 @@ struct TextPage {
83508361
83518362
def __del__(self):
83528363
if not type(self) is TextPage: return
8353-
self.__swig_destroy__(self)
8364+
if getattr(self, "thisown", False):
8365+
self.__swig_destroy__(self)
8366+
self.thisown = False
83548367
%}
83558368
}
83568369
};
@@ -8448,10 +8461,10 @@ struct TextWriter
84488461
self.used_fonts.add(font)
84498462
%}
84508463
PyObject *
8451-
append(PyObject *pos, char *text, struct Font *font=NULL, float fontsize=11, char *language=NULL, int wmode=0, int bidi_level=0)
8464+
append(PyObject *pos, char *text, struct Font *font=NULL, float fontsize=11, char *language=NULL, int wmode=0, int bidi_level=0, int markup_dir=0)
84528465
{
84538466
fz_text_language lang = fz_text_language_from_string(language);
8454-
fz_bidi_direction markup_dir = 0;
8467+
//fz_bidi_direction markup_dir = 0;
84558468
fz_point p = JM_point_from_py(pos);
84568469
fz_matrix trm = fz_make_matrix(fontsize, 0, 0, fontsize, p.x, p.y);
84578470
fz_try(gctx) {
@@ -8505,6 +8518,10 @@ struct TextWriter
85058518
85068519
new_cont_lines = ["q"]
85078520
8521+
cb = page.CropBoxPosition
8522+
if bool(cb):
8523+
new_cont_lines.append("1 0 0 1 %g %g cm" % (cb.x, cb.y))
8524+
85088525
if morph:
85098526
p = morph[0] * self.ictm
85108527
delta = Matrix(1, 1).preTranslate(p.x, p.y)
@@ -8752,6 +8769,15 @@ struct Font
87528769
return this_font->glyph_count;
87538770
}
87548771
8772+
%pythoncode %{@property%}
8773+
PyObject *buffer()
8774+
{
8775+
fz_font *this_font = (fz_font *) $self;
8776+
unsigned char *data = NULL;
8777+
size_t len = fz_buffer_storage(gctx, this_font->buffer, &data);
8778+
return JM_BinFromCharSize(data, len);
8779+
}
8780+
87558781
%pythoncode %{@property%}
87568782
%pythonappend bbox%{val = Rect(val)%}
87578783
PyObject *bbox()

0 commit comments

Comments
 (0)