Skip to content

Commit

Permalink
Merge pull request #226 from JorjMcKie/master
Browse files Browse the repository at this point in the history
Uploading first patch
  • Loading branch information
JorjMcKie committed Nov 19, 2018
2 parents f4bca38 + e47f16f commit 3bc5632
Show file tree
Hide file tree
Showing 15 changed files with 329 additions and 187 deletions.
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# PyMuPDF 1.14.0
# PyMuPDF 1.14.1

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

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

# Introduction

This is **version 1.14.0 of PyMuPDF (formerly python-fitz)**, a Python binding with support for [MuPDF 1.14.0](http://mupdf.com/) - "a lightweight PDF, XPS, and E-book viewer".
This is **version 1.14.1 of PyMuPDF (formerly python-fitz)**, a Python binding with support for [MuPDF 1.14.x](http://mupdf.com/) - "a lightweight PDF, XPS, and E-book viewer".

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.

Expand All @@ -30,14 +30,15 @@ The platform tag for Mac OSX is `macosx_10_6_intel`.

The platform tag for Linux is `manylinux1_x86_64`, which makes these wheels usable on Debian, Ubuntu and most other variations.

On other operating systems you need to generate PyMuPDF yourself. And of course you can choose to do so for a wheel-supported platform, too. Before you can do this, you must download and generate MuPDF. This process depends very much on your system. For most platforms, the MuPDF source contains prepared procedures for achieving this.
On other operating systems you need to generate PyMuPDF yourself. And of course you can choose to do so for a wheel-supported platform, too. Before you can do this, you must download and generate MuPDF. This process depends very much on your system. For most platforms, the MuPDF source contains prepared procedures for achieving this. Please observe the following general steps:

* Be sure to download the official MuPDF source release from [here](https://mupdf.com/downloads). Do **not use** MuPDF's [GitHub repo](https://github.com/ArtifexSoftware/mupdf). It contains their current **development source**, which is **not compatible** with this PyMuPDF version most of the time.
* Be sure to download the official MuPDF source release from [here](https://mupdf.com/downloads/archive). Do **not use** MuPDF's [GitHub repo](https://github.com/ArtifexSoftware/mupdf). It contains their current **development source**, which is **not compatible** with this PyMuPDF version most of the time.

* The repo's `fitz` folder contains a few files whose names start with an underscore. These files contain configuration data and hotfixes and each must be copy-renamed to its correct target location of the downloaded MuPDF source **before you generate MuPDF**. Currently, these files are:
- fitz configuration file `_mupdf_config.h` copy-replace to `mupdf/include/fitz/config.h`.
- fitz error module `_error.c`, copy-replace to `mupdf/source/fitz/error.c`.
- PDF device module `_pdf-device.c` copy-replace `mupdf/source/pdf/pdf-device.c`.
* The repo's `fitz` folder contains a few files whose names start with an underscore `"_"`. These files contain configuration data and hotfixes. Each one must be copy-renamed to its correct target location of the MuPDF source that you have downloaded, **before you generate MuPDF**. Currently, these files are:
- fitz configuration file `_mupdf_config.h` copy-replace to: `mupdf/include/fitz/config.h`. It contains configuration data like e.g. which fonts to support.
- fitz error module `_error.c`, copy-replace to: `mupdf/source/fitz/error.c`. It redirects MuPDF warnings and errors so they can be intercepted by PyMuPDF.
- PDF device module `_pdf-device.c` copy-replace to: `mupdf/source/pdf/pdf-device.c`. It fixes a bug which caused method `Document.convertToPDF()` to bring down the interpeter.
- Now MuPDF can be generated.

Once this is done, adjust directories in ``setup.py`` and run ``python setup.py install``.

Expand Down
Binary file modified doc/PyMuPDF.pdf
Binary file not shown.
Binary file modified doc/html.zip
Binary file not shown.
3 changes: 3 additions & 0 deletions fitz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
TOOLS = fitz.Tools()
fitz.TOOLS = TOOLS

if fitz.VersionFitz != fitz.TOOLS.mupdf_version():
raise ValueError("MuPDF library mismatch %s <> %s" % (fitz.VersionFitz, fitz.TOOLS.mupdf_version()))

import fitz.utils

# copy functions to their respective fitz classes
Expand Down
70 changes: 49 additions & 21 deletions fitz/fitz.i
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ fz_set_stderr(gctx, JM_fitz_stderr);
if (JM_fitz_stderr && JM_fitz_stdout)
{;}
else
PySys_WriteStdout("error redirecting stdout/stderr!\n");
PySys_WriteStderr("error redirecting stdout/stderr!\n");

JM_error_log = PyList_New(0);
JM_output_log = PyList_New(0);
JM_error_log = PyByteArray_FromStringAndSize("", 0);
JM_output_log = PyByteArray_FromStringAndSize("", 0);

//-----------------------------------------------------------------------------
// STOP redirect stdout/stderr
Expand All @@ -172,6 +172,7 @@ struct DeviceWrapper {
// include version information and several other helpers
//-----------------------------------------------------------------------------
%pythoncode %{
import os
import weakref
from binascii import hexlify
import math
Expand Down Expand Up @@ -211,18 +212,27 @@ struct fz_document_s
FITZEXCEPTION(fz_document_s, !result)

%pythonprepend fz_document_s %{
if not filename or type(filename) == str:
if not filename or type(filename) is str:
pass
elif type(filename) == unicode:
filename = filename.encode('utf8')
else:
raise TypeError("filename must be string or None")
self.name = filename if filename else ""
if str is bytes: # Python 2
if type(filename) is unicode:
filename = filename.encode("utf8")
else:
filename = str(filename) # should take care of pathlib

self.streamlen = len(stream) if stream else 0
if stream and not (filename or filetype):
raise ValueError("filetype missing with stream specified")
if stream and type(stream) not in (bytes, bytearray):
raise ValueError("stream must be bytes or bytearray")

self.name = ""
if filename and self.streamlen == 0:
self.name = filename

if self.streamlen > 0:
if not (filename or filetype):
raise ValueError("filetype missing with stream specified")
if type(stream) not in (bytes, bytearray):
raise ValueError("stream must be bytes or bytearray")

self.isClosed = False
self.isEncrypted = 0
self.metadata = None
Expand Down Expand Up @@ -2102,18 +2112,18 @@ struct fz_page_s {
inklist = pdf_new_array(gctx, annot->page->doc, n0);
for (j = 0; j < n0; j++)
{
sublist = PySequence_GetItem(list, j);
sublist = PySequence_ITEM(list, j);
n1 = PySequence_Size(sublist);
stroke = pdf_new_array(gctx, annot->page->doc, 2 * n1);
for (i = 0; i < n1; i++)
{
p = PySequence_GetItem(sublist, i);
p = PySequence_ITEM(sublist, i);
if (!PySequence_Check(p) || PySequence_Size(p) != 2)
THROWMSG("3rd level entries must be pairs of floats");
x = PyFloat_AsDouble(PySequence_GetItem(p, 0));
x = PyFloat_AsDouble(PySequence_ITEM(p, 0));
if (PyErr_Occurred())
THROWMSG("invalid point coordinate");
y = PyFloat_AsDouble(PySequence_GetItem(p, 1));
y = PyFloat_AsDouble(PySequence_ITEM(p, 1));
if (PyErr_Occurred())
THROWMSG("invalid point coordinate");
Py_CLEAR(p);
Expand Down Expand Up @@ -4559,7 +4569,7 @@ struct fz_annot_s
if (n>0)
{
for (i=0; i<n; i++)
col[i] = (float) PyFloat_AsDouble(PySequence_GetItem(ccol, i));
col[i] = (float) PyFloat_AsDouble(PySequence_ITEM(ccol, i));
fz_try(gctx)
pdf_set_annot_color(gctx, annot, n, col);
fz_catch(gctx)
Expand All @@ -4577,7 +4587,7 @@ struct fz_annot_s
return;
}
for (i=0; i<n; i++)
col[i] = (float) PyFloat_AsDouble(PySequence_GetItem(icol, i));
col[i] = (float) PyFloat_AsDouble(PySequence_ITEM(icol, i));
fz_try(gctx)
pdf_set_annot_interior_color(gctx, annot, n, col);
fz_catch(gctx)
Expand Down Expand Up @@ -5998,16 +6008,34 @@ struct Tools
}
%pythoncode%{@property%}
PyObject *fitz_stderr()
char *fitz_stdout()
{
return PyUnicode_Join(Py_BuildValue("s", ""), JM_error_log);
return PyByteArray_AS_STRING(JM_output_log);
}
%feature("autodoc","Empty fitz output log.") empty_error_log;
void fitz_stdout_reset()
{
Py_CLEAR(JM_output_log);
JM_output_log = PyByteArray_FromStringAndSize("", 0);
}
%pythoncode%{@property%}
char *fitz_stderr()
{
return PyByteArray_AS_STRING(JM_error_log);
}
%feature("autodoc","Empty fitz error log.") empty_error_log;
void fitz_stderr_reset()
{
Py_CLEAR(JM_error_log);
JM_error_log = PyList_New(0);
JM_error_log = PyByteArray_FromStringAndSize("", 0);
}
char *mupdf_version()
{
return FZ_VERSION;
}
PyObject *transform_rect(PyObject *rect, PyObject *matrix)
Expand Down
52 changes: 39 additions & 13 deletions fitz/fitz.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class _object:
_newclass = 0


import os
import weakref
from binascii import hexlify
import math
Expand All @@ -105,9 +106,9 @@ class _object:


VersionFitz = "1.14.0"
VersionBind = "1.14.0"
VersionDate = "2018-11-16 05:14:22"
version = (VersionBind, VersionFitz, "20181116051422")
VersionBind = "1.14.1"
VersionDate = "2018-11-18 17:07:00"
version = (VersionBind, VersionFitz, "20181118170700")


class Matrix():
Expand Down Expand Up @@ -1572,18 +1573,27 @@ class Document(_object):
def __init__(self, filename=None, stream=None, filetype=None, rect=None, width=0, height=0, fontsize=11):
"""__init__(self, filename=None, stream=None, filetype=None, rect=None, width=0, height=0, fontsize=11) -> Document"""

if not filename or type(filename) == str:
if not filename or type(filename) is str:
pass
elif type(filename) == unicode:
filename = filename.encode('utf8')
else:
raise TypeError("filename must be string or None")
self.name = filename if filename else ""
if str is bytes: # Python 2
if type(filename) is unicode:
filename = filename.encode("utf8")
else:
filename = str(filename) # should take care of pathlib

self.streamlen = len(stream) if stream else 0
if stream and not (filename or filetype):
raise ValueError("filetype missing with stream specified")
if stream and type(stream) not in (bytes, bytearray):
raise ValueError("stream must be bytes or bytearray")

self.name = ""
if filename and self.streamlen == 0:
self.name = filename

if self.streamlen > 0:
if not (filename or filetype):
raise ValueError("filetype missing with stream specified")
if type(stream) not in (bytes, bytearray):
raise ValueError("stream must be bytes or bytearray")

self.isClosed = False
self.isEncrypted = 0
self.metadata = None
Expand Down Expand Up @@ -4095,8 +4105,19 @@ def glyph_cache_empty(self):

@property

def fitz_stdout(self):
"""fitz_stdout(self) -> char *"""
return _fitz.Tools_fitz_stdout(self)


def fitz_stdout_reset(self):
"""fitz_stdout_reset(self)"""
return _fitz.Tools_fitz_stdout_reset(self)

@property

def fitz_stderr(self):
"""fitz_stderr(self) -> PyObject *"""
"""fitz_stderr(self) -> char *"""
return _fitz.Tools_fitz_stderr(self)


Expand All @@ -4105,6 +4126,11 @@ def fitz_stderr_reset(self):
return _fitz.Tools_fitz_stderr_reset(self)


def mupdf_version(self):
"""mupdf_version(self) -> char *"""
return _fitz.Tools_mupdf_version(self)


def transform_rect(self, rect, matrix):
"""transform_rect(self, rect, matrix) -> PyObject *"""
return _fitz.Tools_transform_rect(self, rect, matrix)
Expand Down
Loading

0 comments on commit 3bc5632

Please sign in to comment.