PyGObject Poppler

Web で配布されているコミックは PDF であることもある。
我がアプリで PDF も読み込みできるといいんだけど。

Poppler – Wikipedia

こんなライブラリがあることを知った。

Fedora デフォルトには普通に Gir で入っていたりするし。
そりゃ Evince が使っているし。

Poppler 0.18 (0.69.0) – Poppler 0.18

ドキュメントもある。
関数名も解りやすいし適当に書いてみよう。

#!/usr/bin/env python3

import gi, cairo
gi.require_version('Gtk', '3.0')
gi.require_version('Poppler', '0.18')
from gi.repository import Gtk, Gio, Poppler

PDFFILE = 'りんごの色.pdf'
 
class PdfWin(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.connect('delete-event', Gtk.main_quit)
        # PDF file
        f = Gio.File.new_for_path(PDFFILE)
        self.pdf = Poppler.Document.new_from_gfile(f)
        self.max_page = self.pdf.get_n_pages()
        self.num = 0
        # button
        button = Gtk.Button.new_with_label('Next Page')
        button.connect('clicked', self.on_button_clicked)
        # DrawingArea
        self.canvas = Gtk.DrawingArea()
        self.canvas.connect('draw', self.on_draw)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.pack_start(button, False, False, 0)
        vbox.pack_end(self.canvas, True, True, 0)
        self.add(vbox)
        self.resize(400, 400)
        self.show_all()
 
    def on_button_clicked(self, widget):
        if self.num < self.max_page-1:
            self.canvas.queue_draw()
            self.num += 1

    def on_draw(self, widget, cr):
        aw = widget.get_allocated_width()
        ah = widget.get_allocated_height()
        page = self.pdf.get_page(self.num)
        w, h = page.get_size()
        if aw * h > ah * w:
            n = ah/h
            matrix = cairo.Matrix(n, 0, 0, n, aw/2-w*n/2, 0)
            cr.transform(matrix)
        else:
            n = aw/w
            matrix = cairo.Matrix(n, 0, 0, n, n, ah/2-h*n/2)
            cr.transform(matrix)
        page.render(cr)
 
PdfWin()
Gtk.main()

こんなにアッサリ。。。
何もインストールしないでも表示するだけならマジでこれだけ。

cairo のドキュメントを見ると PDFSurface なんてサーフェスがあるね。
こんなに面白かったのか cairo って。