@@ -403,15 +403,38 @@ struct fz_document_s
403403 DEBUGMSG2;
404404 }
405405
406- CLOSECHECK(embeddedFileCount)
407- %feature("autodoc","Return number of embedded files.") embeddedFileCount;
408- %pythoncode%{@property%}
409- PyObject *embeddedFileCount()
406+ //---------------------------------------------------------------------
407+ // Get EmbeddedFiles names
408+ //---------------------------------------------------------------------
409+ FITZEXCEPTION(_embeddedFileNames, !result)
410+ CLOSECHECK0(_embeddedFileNames)
411+ PyObject *_embeddedFileNames(PyObject *namelist)
410412 {
411- pdf_document *pdf = pdf_document_from_fz_document(gctx, $self);
412- int i = -1;
413- if (pdf) i = pdf_count_portfolio_entries(gctx, pdf);
414- return Py_BuildValue("i", i);
413+ pdf_document *pdf = pdf_specifics(gctx, $self); // get pdf document
414+ pdf_obj *names, *o;
415+ char *c = NULL;
416+
417+ fz_try(gctx)
418+ {
419+ assert_PDF(pdf);
420+ names = pdf_dict_getl(gctx, pdf_trailer(gctx, pdf),
421+ PDF_NAME(Root),
422+ PDF_NAME(Names),
423+ PDF_NAME(EmbeddedFiles),
424+ PDF_NAME(Names),
425+ NULL);
426+ if (pdf_is_array(gctx, names))
427+ {
428+ int i, n = pdf_array_len(gctx, names);
429+ for (i=0; i < n; i+=2)
430+ {
431+ c = pdf_to_text_string(gctx, pdf_array_get(gctx, names, i));
432+ PyList_Append(namelist, Py_BuildValue("s", c));
433+ }
434+ }
435+ }
436+ fz_catch(gctx) return NULL;
437+ return NONE;
415438 }
416439
417440 FITZEXCEPTION(embeddedFileDel, !result)
@@ -662,6 +685,96 @@ if self.isClosed or self.isEncrypted:
662685 return NONE;
663686 }
664687
688+ FITZEXCEPTION(_embeddedFileAdd, !result)
689+ PyObject *_embeddedFileAdd(const char *name, PyObject *buffer, char *filename=NULL, char *ufilename=NULL, char *desc=NULL)
690+ {
691+ pdf_document *pdf = pdf_document_from_fz_document(gctx, $self);
692+ fz_buffer *data = NULL;
693+ char *buffdata;
694+ fz_var(data);
695+ int entry = 0;
696+ size_t size = 0;
697+ pdf_obj *names = NULL;
698+ fz_try(gctx)
699+ {
700+ assert_PDF(pdf);
701+ data = JM_BufferFromBytes(gctx, buffer);
702+ if (!data) THROWMSG("bad type: ' buffer' ");
703+ size = fz_buffer_storage(gctx, data, &buffdata);
704+
705+ names = pdf_dict_getl(gctx, pdf_trailer(gctx, pdf),
706+ PDF_NAME(Root),
707+ PDF_NAME(Names),
708+ PDF_NAME(EmbeddedFiles),
709+ PDF_NAME(Names),
710+ NULL);
711+ if (!pdf_is_array(gctx, names)) // no embedded files yet
712+ {
713+ pdf_obj *root = pdf_dict_get(gctx, pdf_trailer(gctx, pdf),
714+ PDF_NAME(Root));
715+ names = pdf_new_array(gctx, pdf, 6); // an even number!
716+ pdf_dict_putl_drop(gctx, root, names,
717+ PDF_NAME(Names),
718+ PDF_NAME(EmbeddedFiles),
719+ PDF_NAME(Names),
720+ NULL);
721+ }
722+
723+ pdf_obj *fileentry = JM_embed_file(gctx, pdf, data,
724+ filename,
725+ ufilename,
726+ desc);
727+ pdf_array_push(gctx, names, pdf_new_text_string(gctx, name));
728+ pdf_array_push_drop(gctx, names, fileentry);
729+ }
730+ fz_always(gctx)
731+ {
732+ fz_drop_buffer(gctx, data);
733+ }
734+ fz_catch(gctx) return NULL;
735+ pdf->dirty = 1;
736+ return NONE;
737+ }
738+
739+ %pythoncode %{
740+ def embeddedFileNames(self):
741+ filenames = []
742+ self._embeddedFileNames(filenames)
743+ return filenames
744+
745+ def embeddedFileCount(self):
746+ return len(self.embeddedFileNames())
747+
748+ def embeddedFileNew(self, name, buffer,
749+ filename=None,
750+ ufilename=None,
751+ desc=None):
752+ """ Add an item to the EmbeddedFiles array.
753+
754+ Args:
755+ name: the name of the new item.
756+ buffer: (binary data) the file content.
757+ filename: (str) the file name.
758+ ufilename: (unicode) the filen ame.
759+ desc: (str) the description.
760+ """
761+ filenames = self.embeddedFileNames()
762+ msg = "Name ' %s' already in EmbeddedFiles array." % str(name)
763+ if name in filenames:
764+ raise ValueError(msg)
765+
766+ if filename is None:
767+ filename = name
768+ if ufilename is None:
769+ ufilename = unicode(filename, "utf8") if str is bytes else filename
770+ if desc is None:
771+ desc = name
772+ return self._embeddedFileAdd(name, buffer=buffer,
773+ filename=filename,
774+ ufilename=ufilename,
775+ desc=desc)
776+ %}
777+
665778 FITZEXCEPTION(convertToPDF, !result)
666779 CLOSECHECK(convertToPDF)
667780 %feature("autodoc","Convert document to PDF selecting page range and optional rotation. Output bytes object.") convertToPDF;
@@ -1150,6 +1263,31 @@ if len(pyliste) == 0 or min(pyliste) not in range(len(self)) or max(pyliste) not
11501263 return NONE;
11511264 }
11521265
1266+ //---------------------------------------------------------------------
1267+ // remove one page
1268+ //---------------------------------------------------------------------
1269+ FITZEXCEPTION(deletePage, !result)
1270+ %feature("autodoc","Delete a PDF page.") deletePage;
1271+ CLOSECHECK0(deletePage)
1272+ %pythonappend deletePage %{
1273+ self._reset_page_refs()
1274+ self.initData()%}
1275+ PyObject *deletePage(int pno)
1276+ {
1277+ pdf_document *pdf = pdf_specifics(gctx, $self);
1278+ fz_try(gctx)
1279+ {
1280+ assert_PDF(pdf);
1281+ int count = fz_count_pages(gctx, $self);
1282+ int n = pno;
1283+ while (n < 0) n += count;
1284+ if (!INRANGE(n, 0, count-1))
1285+ THROWMSG("bad page number(s)");
1286+ pdf_delete_page(gctx, pdf, n);
1287+ }
1288+ fz_catch(gctx) return NULL;
1289+ return NONE;
1290+ }
11531291 //********************************************************************
11541292 // get document permissions
11551293 //********************************************************************
@@ -1968,7 +2106,7 @@ if len(pyliste) == 0 or min(pyliste) not in range(len(self)) or max(pyliste) not
19682106 else:
19692107 pl.insert(to, pno)
19702108 return self.select(pl)
1971-
2109+
19722110 def movePage(self, pno, to = -1):
19732111 " " " Move a page to before some other page of the document. Specify ' to = -1' to move after last page.
19742112 " " "
@@ -1983,34 +2121,22 @@ if len(pyliste) == 0 or min(pyliste) not in range(len(self)) or max(pyliste) not
19832121 else:
19842122 pl.insert(to-1, pno)
19852123 return self.select(pl)
1986-
1987- def deletePage(self, pno = -1):
1988- " " " Delete a page from the document. First page is ' 0' , last page is ' -1' .
1989- " " "
1990- pl = list(range(len(self)))
1991- if pno < -1 or pno > pl[-1]:
1992- raise ValueError(" page number out of range" )
1993- if pno >= 0:
1994- pl.remove(pno)
1995- else:
1996- pl.remove(pl[-1])
1997- return self.select(pl)
1998-
2124+
19992125 def deletePageRange(self, from_page = -1, to_page = -1):
20002126 " " " Delete pages from the document. First page is ' 0' , last page is ' -1' .
20012127 " " "
2002- pl = list(range(len( self)))
2003- f = from_page
2004- t = to_page
2005- if f == -1:
2006- f = pl[-1]
2007- if t == -1:
2008- t = pl[-1]
2009- if not 0 <= f <= t <= pl[-1] :
2128+ pageCount = self.pageCount # page count of document
2129+ f = from_page # first page to delete
2130+ t = to_page # last page to delete
2131+ if f == -1: # means 'last page'
2132+ f = pageCount - 1
2133+ if t == -1: # means 'last page'
2134+ t = pageCount - 1
2135+ if not 0 <= f <= t <= pageCount - 1 :
20102136 raise ValueError(" page number (s) out of range" )
2011- for i in range(f, t+ 1):
2012- pl.remove (i)
2013- return self.select(pl)
2137+ for i in range(t, f - 1, - 1): # delete pages, last to first
2138+ self.deletePage (i)
2139+ return None
20142140
20152141 def saveIncr(self):
20162142 " " " Save PDF incrementally" " "
0 commit comments