Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 48 additions & 10 deletions src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5767,6 +5767,23 @@ def layout(self, rect=None, width=0, height=0, fontsize=11):
self._reset_page_refs()
self.init_doc()

def apply_css(self, css: str, append: bool = True):
"""Apply CSS to a reflowable document.

If 'append' evaluates to True, the CSS will be appended to
the default CSS of this document type.
Otherwise the default CSS will be ignored.
"""
if self.is_closed or self.is_encrypted:
raise ValueError("document closed or encrypted")
doc = self.this
if not mupdf.fz_is_document_reflowable(doc):
return
if not isinstance(css, str) or not css:
return
append = int(bool(append)) # ensure integer
mupdf.fz_style_document(doc, append, css)

def load_page(self, page_id):
"""Load a page.

Expand Down Expand Up @@ -19107,6 +19124,12 @@ def JM_convert_to_pdf(doc, fp, tp, rotate) -> bytes:
Convert any MuPDF document to a PDF
Returns bytes object containing the PDF, created via 'write' function.
'''

def loc_to_pno(doc, loc):
"""Convert location to page number."""
pno = sum(mupdf.fz_count_chapter_pages(doc, i) for i in range(loc.chapter))
return pno + loc.page

pdfout = mupdf.PdfDocument()
incr = 1
s = fp
Expand All @@ -19117,6 +19140,7 @@ def JM_convert_to_pdf(doc, fp, tp, rotate) -> bytes:
e = fp # ... range
rot = JM_norm_rotation(rotate)
i = fp
pno = -1 # init current PDF page number
internal_links = [] # collect PDF-wide internal links here
while 1: # interpret & write document pages as PDF pages
if not _INRANGE(i, s, e):
Expand All @@ -19129,10 +19153,11 @@ def JM_convert_to_pdf(doc, fp, tp, rotate) -> bytes:
dev = None
page_obj = mupdf.pdf_add_page(pdfout, mediabox, rot, resources, contents)
mupdf.pdf_insert_page(pdfout, -1, page_obj)
pno += 1

# also copy links to the output PDF page
# get the PDF page we've just created
pdf_page = mupdf.pdf_load_page(pdfout, i)
pdf_page = mupdf.pdf_load_page(pdfout, pno)

# loop through source page links
link = mupdf.fz_load_links(page) # load first link
Expand All @@ -19146,29 +19171,42 @@ def JM_convert_to_pdf(doc, fp, tp, rotate) -> bytes:
else: # internal links done when PDF is complete
# find target of internal link
ret, xp, yp = mupdf.fz_resolve_link(doc, uri)
ilink={"page": i, "ret": ret, "from": rect, "h": rect.y1-rect.y0, "w": rect.x1-rect.x0, "xp": xp, "yp": yp}
internal_links.append(ilink)
if ret.chapter > -1 and ret.page > -1:
ilink = {"page": pno,
"ret": ret,
"from": rect,
"h": rect.y1 - rect.y0,
"w": rect.x1 - rect.x0,
"xp": xp,
"yp": yp,
}
internal_links.append(ilink)
link = link.next()

i += incr

# PDF created - now write it to Python bytearray
# insert any internal links collected before:
pno = None # init PDF page number
for ilink in internal_links:
pdf_page = mupdf.pdf_load_page(pdfout, ilink["page"])
this_pno = ilink["page"]
if pno != this_pno:
pdf_page = mupdf.pdf_load_page(pdfout, this_pno)
pno = this_pno
ret = ilink["ret"]
dest = mupdf.fz_link_dest()
dest.type = 7 # XYZ destination format
dest.loc.chapter = ret.chapter
dest.loc.page = ret.page
dest.type = mupdf.FZ_LINK_DEST_XYZ
dest.loc.chapter = 0 # PDFs have 1 chapter
dest.loc.page = loc_to_pno(doc, ret)
dest.h = ilink["h"]
dest.w = ilink["w"]
dest.x = ilink["xp"]
dest.y = ilink["yp"]
dest.zoom = 0
rect=ilink["from"]
rect = ilink["from"]
uri = mupdf.pdf_new_uri_from_explicit_dest(mupdf.FzLinkDest(dest))
mupdf.pdf_create_link(pdf_page, rect, uri)

# PDF created - now write it out
# prepare write options structure
opts = mupdf.PdfWriteOptions()
opts.do_garbage = 3
Expand Down
Loading