Esempio n. 1
0
    def goto_page(self, page_number=None, zoom=None):
        '''
        Updates display to show specified page number and zoom level,
        defaulting to current values if None.

        Updates self.page_number and self.zoom if we are successful.
        '''
        # Recreate the bitmap that we are displaying. We should probably use a
        # mupdf.DisplayList to avoid processing the page each time we need to
        # change zoom etc.
        #
        # We can run out of memory for large zoom values; should probably only
        # create bitmap for the visible region (or maybe slightly larger than
        # the visible region to allow for some limited scrolling?).
        #
        if page_number is None:
            page_number = self.page_number
        if zoom is None:
            zoom = self.zoom
        if page_number is None or page_number < 0 or page_number >= self.document.count_pages(
        ):
            return
        self.page = mupdf.Page(self.document, page_number)
        page_rect = self.page.bound_page()
        z = 2**(zoom / self.zoom_multiple)

        # For now we always use 'fit width' view semantics.
        #
        # Using -2 here avoids always-present horizontal scrollbar; not sure
        # why...
        z *= (self.centralWidget().size().width() - 2) / (page_rect.x1 -
                                                          page_rect.x0)

        # Need to preserve the pixmap after we return because the Qt image will
        # refer to it, so we use self.pixmap.
        try:
            self.pixmap = self.page.new_pixmap_from_page_contents(
                ctm=mupdf.Matrix(z, 0, 0, z, 0, 0),
                cs=mupdf.Colorspace(mupdf.Colorspace.Fixed_RGB),
                alpha=0,
            )
        except Exception as e:
            print(f'self.page.new_pixmap_from_page_contents() failed: {e}')
            return
        image = PyQt5.QtGui.QImage(
            int(self.pixmap.pixmap_samples()),
            self.pixmap.pixmap_width(),
            self.pixmap.pixmap_height(),
            self.pixmap.pixmap_stride(),
            PyQt5.QtGui.QImage.Format_RGB888,
        )
        qpixmap = PyQt5.QtGui.QPixmap.fromImage(image)
        self.central_widget.setPixmap(qpixmap)
        self.page_number = page_number
        self.zoom = zoom
Esempio n. 2
0
def trace_runpage( use_display_list, doc, number):
    page = mupdf.Page( doc, number-1)
    mediabox = page.bound_page()
    print( f'<page number="{number}" mediabox="{mediabox.x0} {mediabox.y0} {mediabox.x1} {mediabox.y1}">')
    output = mupdf.Output( mupdf.Output.Fixed_STDOUT)
    dev = mupdf.Device( output)
    if use_display_list:
        list_ = mupdf.DisplayList( page)
        list_.run_display_list( dev, mupdf.Matrix(mupdf.fz_identity), mupdf.Rect(mupdf.fz_infinite_rect), mupdf.Cookie())
    else:
        page.run( dev, mupdf.Matrix(mupdf.fz_identity), mupdf.Cookie())
    output.close_output()
    print( '</page>')
Esempio n. 3
0
def convert_runpage( doc, number, out):
    page = mupdf.Page( doc, number - 1)
    mediabox = page.bound_page()
    dev = out.begin_page(mediabox)
    page.run( dev, mupdf.Matrix(mupdf.fz_identity), mupdf.Cookie())
    out.end_page()
Esempio n. 4
0
def test(path):
    '''
    Runs various mupdf operations on <path>, which is assumed to be a file that
    mupdf can open.
    '''
    log(f'testing path={path}')

    assert os.path.isfile(path)
    global g_test_n
    g_test_n += 1

    # See notes in mupdfwrap.py:build_swig() about buffer_extract() and
    # buffer_storage().
    #
    assert getattr(mupdf.Buffer, 'buffer_storage_raw')
    assert getattr(mupdf.Buffer, 'buffer_storage', None) is None

    assert getattr(mupdf.Buffer, 'buffer_extract_raw')
    assert getattr(mupdf.Buffer, 'buffer_extract')

    # Test operations using functions:
    #
    log('Testing functions.')
    log(f'    Opening: %s' % path)
    document = mupdf.open_document(path)
    log(f'    mupdf.needs_password(document)={mupdf.needs_password(document)}')
    log(f'    mupdf.count_pages(document)={mupdf.count_pages(document)}')
    log(f'    mupdf.document_output_intent(document)={mupdf.document_output_intent(document)}'
        )

    # Test operations using classes:
    #
    log(f'Testing classes')

    document = mupdf.Document(path)
    log(f'Have created mupdf.Document for {path}')
    log(f'document.needs_password()={document.needs_password()}')
    log(f'document.count_pages()={document.count_pages()}')

    if 0:
        log(f'stext info:')
        show_stext(document)

    for k in (
            'format',
            'encryption',
            'info:Author',
            'info:Title',
            'info:Creator',
            'info:Producer',
            'qwerty',
    ):
        v = document.lookup_metadata(k)
        log(f'document.lookup_metadata() k={k} returned v={v!r}')
        if k == 'qwerty':
            assert v is None, f'v={v!r}'
        else:
            pass

    zoom = 10
    scale = mupdf.Matrix.scale(zoom / 100., zoom / 100.)
    page_number = 0
    log(f'Have created scale: a={scale.a} b={scale.b} c={scale.c} d={scale.d} e={scale.e} f={scale.f}'
        )

    colorspace = mupdf.Colorspace(mupdf.Colorspace.Fixed_RGB)
    log(f'{colorspace.m_internal.key_storable.storable.refs}')
    if 0:
        c = colorspace.clamp_color([3.14])
        log('colorspace.clamp_color returned c={c}')
    pixmap = mupdf.Pixmap(document, page_number, scale, colorspace, 0)
    log(f'Have created pixmap: {pixmap.m_internal.w} {pixmap.m_internal.h} {pixmap.m_internal.stride} {pixmap.m_internal.n}'
        )

    filename = f'mupdf_test-out1-{g_test_n}.png'
    pixmap.save_pixmap_as_png(filename)
    log(f'Have created {filename} using pixmap.save_pixmap_as_png().')

    # Print image data in ascii PPM format. Copied from
    # mupdf/docs/examples/example.c.
    #
    samples = pixmap.samples()
    stride = pixmap.stride()
    n = pixmap.n()
    filename = f'mupdf_test-out2-{g_test_n}.ppm'
    with open(filename, 'w') as f:
        f.write('P3\n')
        f.write('%s %s\n' % (pixmap.m_internal.w, pixmap.m_internal.h))
        f.write('255\n')
        for y in range(0, pixmap.m_internal.h):
            for x in range(pixmap.m_internal.w):
                if x:
                    f.write('  ')
                offset = y * stride + x * n
                if hasattr(mupdf, 'bytes_getitem'):
                    # swig
                    f.write('%3d %3d %3d' % (
                        mupdf.bytes_getitem(samples, offset + 0),
                        mupdf.bytes_getitem(samples, offset + 1),
                        mupdf.bytes_getitem(samples, offset + 2),
                    ))
                else:
                    # cppyy
                    f.write('%3d %3d %3d' % (
                        samples[offset + 0],
                        samples[offset + 1],
                        samples[offset + 2],
                    ))
            f.write('\n')
    log(f'Have created {filename} by scanning pixmap.')

    # Generate .png and but create Pixmap from Page instead of from Document.
    #
    page = mupdf.Page(document, 0)
    separations = page.page_separations()
    log(f'page_separations() returned {"true" if separations else "false"}')
    pixmap = mupdf.Pixmap(page, scale, colorspace, 0)
    filename = f'mupdf_test-out3-{g_test_n}.png'
    pixmap.save_pixmap_as_png(filename)
    log(f'Have created {filename} using pixmap.save_pixmap_as_png()')

    # Show links
    log(f'Links.')
    page = mupdf.Page(document, 0)
    link = mupdf.load_links(page.m_internal)
    log(f'{link}')
    if link:
        for i in link:
            log(f'{i}')

    # Check we can iterate over Link's, by creating one manually.
    #
    link = mupdf.Link(mupdf.Rect(0, 0, 1, 1), "hello")
    log(f'items in <link> are:')
    for i in link:
        log(f'    {i.m_internal.refs} {i.m_internal.uri}')

    # Check iteration over Outlines.
    #
    log(f'Outlines.')
    outline = mupdf.Outline(document)
    log(f'outline.m_internal={outline.m_internal}')
    if outline.m_internal:
        log(f'{outline.uri()} {outline.page()} {outline.x()} {outline.y()} {outline.is_open()} {outline.title()}'
            )
        log(f'items in outline tree are:')
    for o in outline:
        log(f'    {o.uri()} {o.page()} {o.x()} {o.y()} {o.is_open()} {o.title()}'
            )

    # Check iteration over StextPage.
    #
    log(f'StextPage.')
    stext_options = mupdf.StextOptions(0)
    page_num = 40
    try:
        stext_page = mupdf.StextPage(document, page_num, stext_options)
    except Exception:
        log(f'no page_num={page_num}')
    else:
        device_stext = mupdf.Device(stext_page, stext_options)
        matrix = mupdf.Matrix()
        page = mupdf.Page(document, 0)
        cookie = mupdf.Cookie()
        page.run_page(device_stext, matrix, cookie)
        log(f'    stext_page is:')
        for block in stext_page:
            log(f'        block:')
            for line in block:
                line_text = ''
                for char in line:
                    line_text += chr(char.m_internal.c)
                log(f'            {line_text}')

        device_stext.close_device()

    # Check copy-constructor.
    log(f'Checking copy-constructor')
    document2 = mupdf.Document(document)
    del document
    page = mupdf.Page(document2, 0)
    scale = mupdf.Matrix()
    pixmap = mupdf.Pixmap(page, scale, colorspace, 0)
    pixmap.save_pixmap_as_png('mupdf_test-out3.png')

    stdout = mupdf.Output(mupdf.Output.Fixed_STDOUT)
    log(f'{type(stdout)} {stdout.m_internal.state}')

    mediabox = page.bound_page()
    out = mupdf.DocumentWriter(filename, 'png', '',
                               mupdf.DocumentWriter.FormatPathType_DOCUMENT)
    dev = out.begin_page(mediabox)
    page.run_page(dev, mupdf.Matrix(mupdf.fz_identity), mupdf.Cookie())
    out.end_page()

    # Check out-params are converted into python return value.
    bitmap = mupdf.Bitmap(10, 20, 8, 72, 72)
    bitmap_details = bitmap.bitmap_details()
    log(f'{bitmap_details}')
    assert list(bitmap_details) == [10, 20, 8,
                                    12], f'bitmap_details={bitmap_details!r}'

    log(f'finished test of %s' % path)
Esempio n. 5
0
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)