Skip to content

Commit e6331c0

Browse files
committed
Introduce document conversion to PDF
1 parent 9bc0c65 commit e6331c0

File tree

5 files changed

+238
-8
lines changed

5 files changed

+238
-8
lines changed

fitz/fitz.i

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ import sys
109109
%include helper-select.i
110110
%include helper-xobject.i
111111
%include helper-pdfinfo.i
112+
%include helper-convert.i
112113

113114
//-----------------------------------------------------------------------------
114115
// fz_document
@@ -526,6 +527,20 @@ struct fz_document_s
526527
return entry;
527528
}
528529
530+
531+
FITZEXCEPTION(convertToPDF, !result)
532+
CLOSECHECK(convertToPDF)
533+
PyObject *convertToPDF()
534+
{
535+
PyObject *doc;
536+
fz_try(gctx)
537+
{
538+
doc = JM_convert_to_pdf(gctx, $self);
539+
}
540+
fz_catch(gctx) return NULL;
541+
return doc;
542+
}
543+
529544
CLOSECHECK(pageCount)
530545
%pythoncode%{@property%}
531546
int pageCount()
@@ -1266,12 +1281,19 @@ if links:
12661281
pdf_document *pdf = pdf_specifics(gctx, $self);
12671282
if (!pdf) Py_RETURN_FALSE;
12681283
pdf_obj *form = NULL;
1284+
pdf_obj *fields = NULL;
1285+
int have_form = 0;
12691286
fz_try(gctx)
12701287
{
12711288
form = pdf_dict_getl(gctx, pdf_trailer(gctx, pdf), PDF_NAME_Root, PDF_NAME_AcroForm, NULL);
1289+
if (form)
1290+
{
1291+
fields = pdf_dict_get(gctx, form, PDF_NAME_Fields);
1292+
if (fields && pdf_array_len(gctx, fields) > 0) have_form = 1;
1293+
}
12721294
}
12731295
fz_catch(gctx) Py_RETURN_FALSE;
1274-
if (!form) Py_RETURN_FALSE;
1296+
if (!have_form) Py_RETURN_FALSE;
12751297
Py_RETURN_TRUE;
12761298
}
12771299

fitz/fitz.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ class _object:
102102

103103

104104
VersionFitz = "1.13.0"
105-
VersionBind = "1.13.2"
106-
VersionDate = "2018-05-02 09:39:09"
107-
version = (VersionBind, VersionFitz, "20180502093909")
105+
VersionBind = "1.13.3"
106+
VersionDate = "2018-05-03 15:12:04"
107+
version = (VersionBind, VersionFitz, "20180503151204")
108108

109109

110110
#------------------------------------------------------------------------------
@@ -641,6 +641,14 @@ def embeddedFileAdd(self, buffer, name, filename=None, desc=None):
641641

642642
return _fitz.Document_embeddedFileAdd(self, buffer, name, filename, desc)
643643

644+
645+
def convertToPDF(self):
646+
"""convertToPDF(self) -> PyObject *"""
647+
if self.isClosed:
648+
raise ValueError("operation illegal for closed doc")
649+
650+
return _fitz.Document_convertToPDF(self)
651+
644652
@property
645653

646654
def pageCount(self):

fitz/fitz_wrap.c

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4781,6 +4781,83 @@ void JM_ScanResources(fz_context *ctx, pdf_document *pdf, pdf_obj *rsrc,
47814781
}
47824782

47834783

4784+
4785+
//-----------------------------------------------------------------------------
4786+
// convert a document to a PDF
4787+
//-----------------------------------------------------------------------------
4788+
PyObject *JM_convert_to_pdf(fz_context *ctx, fz_document *doc)
4789+
{
4790+
pdf_document *pdfout = pdf_create_document(ctx);
4791+
int pageCount = fz_count_pages(ctx, doc);
4792+
fz_rect mediabox;
4793+
fz_device *dev = NULL;
4794+
fz_buffer *contents = NULL;
4795+
pdf_obj *resources = NULL;
4796+
fz_page *page;
4797+
int i;
4798+
for (i = 0; i < pageCount; i++)
4799+
{
4800+
fz_try(ctx)
4801+
{
4802+
page = fz_load_page(ctx, doc, i);
4803+
fz_bound_page(ctx, page, &mediabox);
4804+
dev = pdf_page_write(ctx, pdfout, &mediabox, &resources, &contents);
4805+
fz_run_page(ctx, page, dev, &fz_identity, NULL);
4806+
fz_close_device(ctx, dev);
4807+
fz_drop_device(ctx, dev);
4808+
dev = NULL;
4809+
pdf_obj *page_obj = pdf_add_page(ctx, pdfout, &mediabox, 0, resources, contents);
4810+
pdf_insert_page(ctx, pdfout, -1, page_obj);
4811+
pdf_drop_obj(ctx, page_obj);
4812+
}
4813+
fz_always(ctx)
4814+
{
4815+
pdf_drop_obj(ctx, resources);
4816+
fz_drop_buffer(ctx, contents);
4817+
fz_drop_device(ctx, dev);
4818+
}
4819+
fz_catch(ctx)
4820+
{
4821+
fz_drop_page(ctx, page);
4822+
fz_rethrow(ctx);
4823+
}
4824+
}
4825+
unsigned char *c;
4826+
PyObject *r;
4827+
size_t len;
4828+
fz_buffer *res = NULL;
4829+
fz_output *out = NULL;
4830+
int errors = 0;
4831+
pdf_write_options opts;
4832+
opts.do_incremental = 0;
4833+
opts.do_ascii = 0;
4834+
opts.do_compress = 1;
4835+
opts.do_compress_images = 1;
4836+
opts.do_compress_fonts = 1;
4837+
opts.do_decompress = 0;
4838+
opts.do_garbage = 4;
4839+
opts.do_linear = 0;
4840+
opts.do_clean = 0;
4841+
opts.do_pretty = 0;
4842+
opts.continue_on_error = 1;
4843+
opts.errors = &errors;
4844+
fz_try(ctx)
4845+
{
4846+
res = fz_new_buffer(ctx, 1024);
4847+
out = fz_new_output_with_buffer(ctx, res);
4848+
pdf_write_document(ctx, pdfout, out, &opts);
4849+
len = fz_buffer_storage(ctx, res, &c);
4850+
r = PyBytes_FromStringAndSize(c, len);
4851+
}
4852+
fz_always(ctx)
4853+
{
4854+
fz_drop_output(ctx, out);
4855+
fz_drop_buffer(ctx, res);
4856+
}
4857+
fz_catch(ctx) fz_rethrow(ctx);
4858+
return r;
4859+
}
4860+
47844861
SWIGINTERN void delete_fz_document_s(struct fz_document_s *self){
47854862
DEBUGMSG1("document w/o close");
47864863
fz_drop_document(gctx, self);
@@ -5366,6 +5443,15 @@ SWIGINTERN int fz_document_s_embeddedFileAdd(struct fz_document_s *self,PyObject
53665443
fz_catch(gctx) return -1;
53675444
return entry;
53685445
}
5446+
SWIGINTERN PyObject *fz_document_s_convertToPDF(struct fz_document_s *self){
5447+
PyObject *doc;
5448+
fz_try(gctx)
5449+
{
5450+
doc = JM_convert_to_pdf(gctx, self);
5451+
}
5452+
fz_catch(gctx) return NULL;
5453+
return doc;
5454+
}
53695455
SWIGINTERN int fz_document_s_pageCount(struct fz_document_s *self){
53705456
return fz_count_pages(gctx, self);
53715457
}
@@ -5992,12 +6078,19 @@ SWIGINTERN PyObject *fz_document_s_isFormPDF(struct fz_document_s *self){
59926078
pdf_document *pdf = pdf_specifics(gctx, self);
59936079
if (!pdf) Py_RETURN_FALSE;
59946080
pdf_obj *form = NULL;
6081+
pdf_obj *fields = NULL;
6082+
int have_form = 0;
59956083
fz_try(gctx)
59966084
{
59976085
form = pdf_dict_getl(gctx, pdf_trailer(gctx, pdf), PDF_NAME_Root, PDF_NAME_AcroForm, NULL);
6086+
if (form)
6087+
{
6088+
fields = pdf_dict_get(gctx, form, PDF_NAME_Fields);
6089+
if (fields && pdf_array_len(gctx, fields) > 0) have_form = 1;
6090+
}
59986091
}
59996092
fz_catch(gctx) Py_RETURN_FALSE;
6000-
if (!form) Py_RETURN_FALSE;
6093+
if (!have_form) Py_RETURN_FALSE;
60016094
Py_RETURN_TRUE;
60026095
}
60036096
SWIGINTERN int fz_document_s__getOLRootNumber(struct fz_document_s *self){
@@ -9131,6 +9224,35 @@ SWIGINTERN PyObject *_wrap_Document_embeddedFileAdd(PyObject *SWIGUNUSEDPARM(sel
91319224
}
91329225

91339226

9227+
SWIGINTERN PyObject *_wrap_Document_convertToPDF(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
9228+
PyObject *resultobj = 0;
9229+
struct fz_document_s *arg1 = (struct fz_document_s *) 0 ;
9230+
void *argp1 = 0 ;
9231+
int res1 = 0 ;
9232+
PyObject * obj0 = 0 ;
9233+
PyObject *result = 0 ;
9234+
9235+
if (!PyArg_ParseTuple(args,(char *)"O:Document_convertToPDF",&obj0)) SWIG_fail;
9236+
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_fz_document_s, 0 | 0 );
9237+
if (!SWIG_IsOK(res1)) {
9238+
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Document_convertToPDF" "', argument " "1"" of type '" "struct fz_document_s *""'");
9239+
}
9240+
arg1 = (struct fz_document_s *)(argp1);
9241+
{
9242+
result = (PyObject *)fz_document_s_convertToPDF(arg1);
9243+
if(!result)
9244+
{
9245+
PyErr_SetString(PyExc_RuntimeError, fz_caught_message(gctx));
9246+
return NULL;
9247+
}
9248+
}
9249+
resultobj = result;
9250+
return resultobj;
9251+
fail:
9252+
return NULL;
9253+
}
9254+
9255+
91349256
SWIGINTERN PyObject *_wrap_Document_pageCount(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
91359257
PyObject *resultobj = 0;
91369258
struct fz_document_s *arg1 = (struct fz_document_s *) 0 ;
@@ -18018,6 +18140,7 @@ static PyMethodDef SwigMethods[] = {
1801818140
{ (char *)"Document_embeddedFileSetInfo", _wrap_Document_embeddedFileSetInfo, METH_VARARGS, (char *)"Change filename or description of embedded file given its entry number or name."},
1801918141
{ (char *)"Document_embeddedFileGet", _wrap_Document_embeddedFileGet, METH_VARARGS, (char *)"Retrieve embedded file content given its entry number or name."},
1802018142
{ (char *)"Document_embeddedFileAdd", _wrap_Document_embeddedFileAdd, METH_VARARGS, (char *)"Add new file from buffer."},
18143+
{ (char *)"Document_convertToPDF", _wrap_Document_convertToPDF, METH_VARARGS, (char *)"Document_convertToPDF(self) -> PyObject *"},
1802118144
{ (char *)"Document_pageCount", _wrap_Document_pageCount, METH_VARARGS, (char *)"Document_pageCount(self) -> int"},
1802218145
{ (char *)"Document__getMetadata", _wrap_Document__getMetadata, METH_VARARGS, (char *)"Document__getMetadata(self, key) -> char *"},
1802318146
{ (char *)"Document_needsPass", _wrap_Document_needsPass, METH_VARARGS, (char *)"Document_needsPass(self) -> int"},

fitz/helper-convert.i

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
%{
2+
//-----------------------------------------------------------------------------
3+
// convert a document to a PDF
4+
//-----------------------------------------------------------------------------
5+
PyObject *JM_convert_to_pdf(fz_context *ctx, fz_document *doc)
6+
{
7+
pdf_document *pdfout = pdf_create_document(ctx);
8+
int pageCount = fz_count_pages(ctx, doc);
9+
fz_rect mediabox;
10+
fz_device *dev = NULL;
11+
fz_buffer *contents = NULL;
12+
pdf_obj *resources = NULL;
13+
fz_page *page;
14+
int i;
15+
for (i = 0; i < pageCount; i++)
16+
{
17+
fz_try(ctx)
18+
{
19+
page = fz_load_page(ctx, doc, i);
20+
fz_bound_page(ctx, page, &mediabox);
21+
dev = pdf_page_write(ctx, pdfout, &mediabox, &resources, &contents);
22+
fz_run_page(ctx, page, dev, &fz_identity, NULL);
23+
fz_close_device(ctx, dev);
24+
fz_drop_device(ctx, dev);
25+
dev = NULL;
26+
pdf_obj *page_obj = pdf_add_page(ctx, pdfout, &mediabox, 0, resources, contents);
27+
pdf_insert_page(ctx, pdfout, -1, page_obj);
28+
pdf_drop_obj(ctx, page_obj);
29+
}
30+
fz_always(ctx)
31+
{
32+
pdf_drop_obj(ctx, resources);
33+
fz_drop_buffer(ctx, contents);
34+
fz_drop_device(ctx, dev);
35+
}
36+
fz_catch(ctx)
37+
{
38+
fz_drop_page(ctx, page);
39+
fz_rethrow(ctx);
40+
}
41+
}
42+
unsigned char *c;
43+
PyObject *r;
44+
size_t len;
45+
fz_buffer *res = NULL;
46+
fz_output *out = NULL;
47+
int errors = 0;
48+
pdf_write_options opts;
49+
opts.do_incremental = 0;
50+
opts.do_ascii = 0;
51+
opts.do_compress = 1;
52+
opts.do_compress_images = 1;
53+
opts.do_compress_fonts = 1;
54+
opts.do_decompress = 0;
55+
opts.do_garbage = 4;
56+
opts.do_linear = 0;
57+
opts.do_clean = 0;
58+
opts.do_pretty = 0;
59+
opts.continue_on_error = 1;
60+
opts.errors = &errors;
61+
fz_try(ctx)
62+
{
63+
res = fz_new_buffer(ctx, 1024);
64+
out = fz_new_output_with_buffer(ctx, res);
65+
pdf_write_document(ctx, pdfout, out, &opts);
66+
len = fz_buffer_storage(ctx, res, &c);
67+
r = PyBytes_FromStringAndSize(c, len);
68+
}
69+
fz_always(ctx)
70+
{
71+
fz_drop_output(ctx, out);
72+
fz_drop_buffer(ctx, res);
73+
}
74+
fz_catch(ctx) fz_rethrow(ctx);
75+
return r;
76+
}
77+
%}

fitz/version.i

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
%pythoncode %{
22
VersionFitz = "1.13.0"
3-
VersionBind = "1.13.2"
4-
VersionDate = "2018-05-02 09:39:09"
5-
version = (VersionBind, VersionFitz, "20180502093909")
3+
VersionBind = "1.13.3"
4+
VersionDate = "2018-05-03 15:12:04"
5+
version = (VersionBind, VersionFitz, "20180503151204")
66
%}

0 commit comments

Comments
 (0)