def drawpage(doc, pagenum): list_ = None cookie = mupdf.Cookie() seps = None features = "" start = gettime() if state.showtime else 0 page = mupdf.Page(doc, pagenum - 1) if state.spots != SPOTS_NONE: seps = page.page_separations() if seps.m_internal: n = seps.count_separations() if state.spots == SPOTS_FULL: for i in range(n): seps.set_separation_behavior(i, mupdf.FZ_SEPARATION_SPOT) else: for i in range(n): seps.set_separation_behavior(i, mupdf.FZ_SEPARATION_COMPOSITE) elif page.page_uses_overprint(): # This page uses overprint, so we need an empty # sep object to force the overprint simulation on. seps = mupdf.Separations(0) elif state.oi and state.oi.m_internal and state.oi.colorspace_n( ) != state.colorspace.colorspace_n(): # We have an output intent, and it's incompatible # with the colorspace our device needs. Force the # overprint simulation on, because this ensures that # we 'simulate' the output intent too. */ seps = mupdf.Separations(0) if state.uselist: list_ = mupdf.DisplayList(page.bound_page()) dev = mupdf.Device(list_) if state.lowmemory: dev.enable_device_hints(FZ_NO_CACHE) page.run(dev, mupdf.Matrix(), cookie) dev.close_device() if bgprint.active and state.showtime: end = gettime() start = end - start if state.showfeatures: # SWIG doesn't appear to handle the out-param is_color in # mupdf.Device() constructor that wraps fz_new_test_device(), so we use # the underlying mupdf function() instead. # dev, iscolor = mupdf.new_test_device(0.02, 0, None) dev = mupdf.Device(dev) if state.lowmemory: dev.enable_device_hints(mupdf.FZ_NO_CACHE) if list_: list_.run_display_list(dev, mupdf.Matrix(mupdf.fz_identity), mupdf.Rect(mupdf.fz_infinite_rect), mupdf.Cookie()) else: page.run(dev, fz_identity, cookie) dev.close_device() features = " color" if iscolor else " grayscale" if state.output_file_per_page: bgprint_flush() if state.out: state.out.close_output() text_buffer = mupdf.format_output_path(state.output, pagenum) state.out = mupdf.Output(text_buffer, 0) if bgprint.active: bgprint_flush() if bgprint.active: if not state.quiet or state.showfeatures or state.showtime or state.showmd5: sys.stderr.write("page %s %d%s" % (state.filename, pagenum, features)) bgprint.started = 1 bgprint.page = page bgprint.list = list_ bgprint.seps = seps bgprint.filename = state.filename bgprint.pagenum = pagenum bgprint.interptime = start else: if not state.quiet or state.showfeatures or state.showtime or state.showmd5: sys.stderr.write("page %s %d%s" % (state.filename, pagenum, features)) dodrawpage(page, list_, pagenum, cookie, start, 0, state.filename, 0, seps)
def dodrawpage(page, list_, pagenum, cookie, start, interptime, filename, bg, seps): if state.output_file_per_page: file_level_headers() if list_: mediabox = mupdf.Rect(list_) else: mediabox = page.bound_page() if state.output_format == OUT_TRACE: state.out.write_string( "<page mediabox=\"%g %g %g %g\">\n" % (mediabox.x0, mediabox.y0, mediabox.x1, mediabox.y1)) dev = mupdf.Device(state.out) if state.lowmemory: dev.enable_device_hints(mupdf.FZ_NO_CACHE) if list_: list_.run_display_list(dev, mupdf.Matrix(), mupdf.Rect(mupdf.fz_infinite_rect), cookie) else: page.run(dev, fz_identity, cookie) state.out.write_string("</page>\n") dev.close_device() dev = None elif state.output_format == OUT_XMLTEXT: state.out.write_string( "<page mediabox=\"%g %g %g %g\">\n" % (mediabox.x0, mediabox.y0, mediabox.x1, mediabox.y1)) dev = mupdf.Device.new_raw_device(state.out) if list_: list_.run_display_list(dev, mupdf.Matrix(), mupdf.Rect(mupdf.fz_infinite_rect), cookie) else: page.run(dev, fz_identity, cookie) state.out.write_string("</page>\n") dev.close_device() dev = None elif state.output_format == OUT_BBOX: bbox = mupdf.Rect(mupdf.Rect.Fixed_EMPTY) dev = mupdf.Device(bbox) if state.lowmemory: dev.enable_device_hints(mupdf.FZ_NO_CACHE) if list_: list_.run_display_list(dev, fz_identity, mupdf.Rect(mupdf.fz_infinite_rect), cookie) else: page.run(dev, fz_identity, cookie) dev.close_device() state.out.write_string( "<page bbox=\"%s %s %s %s\" mediabox=\"%s %s %s %s\" />\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1, mediabox.x0, mediabox.y0, mediabox.x1, mediabox.y1, ) elif state.output_format in (OUT_TEXT, OUT_HTML, OUT_XHTML, OUT_STEXT): zoom = state.resolution / 72 ctm = mupdf.Matrix( mupdf.pre_scale(mupdf.rotate(state.rotation), zoom, zoom)) stext_options = mupdf.StextOptions() stext_options.flags = mupdf.FZ_STEXT_PRESERVE_IMAGES if ( state.output_format == OUT_HTML or state.output_format == OUT_XHTML) else 0 text = mupdf.StextPage(mediabox) dev = mupdf.Device(text, stext_options) if state.lowmemory: fz_enable_device_hints(dev, FZ_NO_CACHE) if list_: list_.run_display_list(dev, ctm, mupdf.Rect(mupdf.fz_infinite_rect), cookie) else: page.run(dev, ctm, cookie) dev.close_device() dev = None if state.output_format == OUT_STEXT: state.out.print_stext_page_as_xml(text, pagenum) elif state.output_format == OUT_HTML: state.out.print_stext_page_as_html(text, pagenum) elif state.output_format == OUT_XHTML: state.out.print_stext_page_as_xhtml(text, pagenum) elif state.output_format == OUT_TEXT: state.out.print_stext_page_as_text(text) state.out.write_string("\f\n") elif state.output_format == OUT_SVG: zoom = state.resolution / 72 ctm = mupdf.Matrix(zoom, zoom) ctm.pre_rotate(state.rotation) tbounds = mupdf.Rect(mediabox, ctm) if not state.output or state.output == "-": state.out = mupdf.Output(mupdf.Output.Fixed_STDOUT) else: buf = mupdf.format_output_path(state.output, pagenum) state.out = mupdf.Output(buf, 0) dev = mupdf.Device(state.out, tbounds.x1 - tbounds.x0, tbounds.y1 - tbounds.y0, mupdf.FZ_SVG_TEXT_AS_PATH, 1) if state.lowmemory: dev.enable_device_hints(dev, mupdf.FZ_NO_CACHE) if list_: list_.run_display_list(dev, ctm, tbounds, cookie) else: page.run(dev, ctm, cookie) dev.close_device() state.out.close_output() else: zoom = state.resolution / 72 m = mupdf.rotate(state.rotation) ctm = mupdf.Matrix( mupdf.pre_scale(mupdf.rotate(state.rotation), zoom, zoom)) tbounds = mupdf.Rect(mediabox, ctm) ibounds = tbounds.round_rect() # Make local copies of our width/height w = state.width h = state.height # If a resolution is specified, check to see whether w/h are # exceeded; if not, unset them. */ if state.res_specified: t = ibounds.x1 - ibounds.x0 if w and t <= w: w = 0 t = ibounds.y1 - ibounds.y0 if h and t <= h: h = 0 # Now w or h will be 0 unless they need to be enforced. if w or h: scalex = w / (tbounds.x1 - tbounds.x0) scaley = h / (tbounds.y1 - tbounds.y0) if state.fit: if w == 0: scalex = 1.0 if h == 0: scaley = 1.0 else: if w == 0: scalex = scaley if h == 0: scaley = scalex if not state.fit: if scalex > scaley: scalex = scaley else: scaley = scalex scale_mat = mupdf.Matrix.scale(scalex, scaley) ctm = mupdf.Matrix( mupdf.concat(ctm.internal(), scale_mat.internal())) tbounds = mupdf.Rect(mediabox, ctm) ibounds = tbounds.round_rect() tbounds = ibounds.rect_from_irect() band_ibounds = ibounds bands = 1 totalheight = ibounds.y1 - ibounds.y0 drawheight = totalheight if state.band_height != 0: # Banded rendering; we'll only render to a # given height at a time. drawheight = state.band_height if totalheight > state.band_height: band_ibounds.y1 = band_ibounds.y0 + state.band_height bands = (totalheight + state.band_height - 1) / state.band_height tbounds.y1 = tbounds.y0 + state.band_height + 2 #DEBUG_THREADS(("Using %d Bands\n", bands)); if state.num_workers > 0: for band in range(min(state.num_workers, bands)): state.workers[band].band = band state.workers[band].ctm = ctm state.workers[band].tbounds = tbounds state.workers[band].cookie = mupdf.Cookie() state.workers[band].list = list_ state.workers[band].pix = mupdf.Pixmap(state.colorspace, band_ibounds, seps, state.alpha) state.workers[band].pix.set_pixmap_resolution( state.resolution, state.resolution) ctm.f -= drawheight pix = state.workers[0].pix else: pix = mupdf.Pixmap(state.colorspace, band_ibounds, seps, state.alpha) pix.set_pixmap_resolution(int(state.resolution), int(state.resolution)) # Output any page level headers (for banded formats) if state.output: state.bander = None if state.output_format == OUT_PGM or state.output_format == OUT_PPM or state.output_format == OUT_PNM: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.PNM) elif state.output_format == OUT_PAM: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.PAM) elif state.output_format == OUT_PNG: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.PNG) elif state.output_format == OUT_PBM: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.PBM) elif state.output_format == OUT_PKM: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.PKM) elif state.output_format == OUT_PS: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.PS) elif state.output_format == OUT_PSD: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.PSD) elif state.output_format == OUT_PWG: if state.out_cs == CS_MONO: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.MONO, mupdf.PwgOptions()) else: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.COLOR, mupdf.PwgOptions()) elif state.output_format == OUT_PCL: if state.out_cs == CS_MONO: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.MONO, mupdf.PclOptions()) else: state.bander = mupdf.BandWriter(state.out, mupdf.BandWriter.COLOR, mupdf.PclOptions()) if state.bander: state.bander.write_header(pix.w(), totalheight, pix.n(), pix.alpha(), pix.xres(), pix.yres(), state.output_pagenum, pix.colorspace(), pix.seps()) state.output_pagenum += 1 for band in range(bands): if state.num_workers > 0: w = state.workers[band % state.num_workers] pix = w.pix bit = w.bit w.bit = None cookie.increment_errors(w.cookie.errors()) else: bit = drawband(page, list_, ctm, tbounds, cookie, band * state.band_height, pix) if state.output: if state.bander: if bit: state.bander.write_band(bit.stride(), drawheight, bit.samples()) else: state.bander.write_band(pix.stride(), drawheight, pix.samples()) bit = None if state.num_workers > 0 and band + state.num_workers < bands: w = state.workers[band % state.num_workers] w.band = band + state.num_workers w.ctm = ctm w.tbounds = tbounds w.cookie = mupdf.Cookie() ctm.f -= drawheight # FIXME if state.showmd5: digest = pix.md5_pixmap() sys.stderr.write(' ') for i in range(16): sys.stderr.write('%02x', digest[i]) if state.output_file_per_page: file_level_trailers() if state.showtime: end = gettime() diff = end - start if bg: if diff + interptime < timing.min: timing.min = diff + interptime timing.mininterp = interptime timing.minpage = pagenum timing.minfilename = filename if diff + interptime > timing.max: timing.max = diff + interptime timing.maxinterp = interptime timing.maxpage = pagenum timing.maxfilename = filename timing.count += 1 sys.stderr.write( " %dms (interpretation) %dms (rendering) %dms (total)" % (interptime, diff, diff + interptime)) else: if diff < timing.min: timing.min = diff timing.minpage = pagenum timing.minfilename = filename if diff > timing.max: timing.max = diff timing.maxpage = pagenum timing.maxfilename = filename timing.total += diff timing.count += 1 sys.stderr.write(" %dms" % diff) if not state.quiet or state.showfeatures or state.showtime or state.showmd5: sys.stderr.write("\n") if state.lowmemory: mupdf.empty_store() if state.showmemory: mupdf.dump_glyph_cache_stats(mupdf.stderr_()) mupdf.flush_warnings() if cookie.get_errors(): state.errored = 1