John
John

Reputation: 222

Print Multiple Pages in Gtk/Pango/Cairo/Python

I am trying to take the text contents of a Gtk.TextView and print it. Since the contents span several pages I need to separate the text into chunks that will be placed on each page. The Pango.WrapMode.WORD command seems to give me the required line length. But I am having difficulty calculating the length of each chunk of text, which I understand has to do with an ink to logical ratio (see example). I think the following example adapted from: https://blog.digitaloctave.com/posts/python/gtk3/printing-with-cairo-gtk3-python.html shows what I am after. In PyQt, printing is a trivial matter, but since Gtk is not a framework, printing has to be done manually. I haven't been able to see many examples in SO or the internet doing this. I am only needing one font and size, but am I going to come up against other problems that may make this much more complicated? Thank you for any help.

#!/usr/bin/python3
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Pango, PangoCairo
import cairo
class PrintExample():
# https://blog.digitaloctave.com/posts/python/gtk3/printing-with-cairo-gtk3-python.html
# https://lazka.github.io/pgi-docs/Pango-1.0/classes/Layout.html#Pango.Layout.get_extents)
# https://docs.gtk.org/Pango/method.Layout.get_pixel_extents.html
    def __init__(self):
        super().__init__()
        self.print_image()
#
    def print_image(self):
        page_setup = Gtk.PageSetup()
        p_op = Gtk.PrintOperation()
        p_op.set_n_pages(1)
        p_op.set_default_page_setup(page_setup)
        p_op.connect("draw_page", self.draw_page)
        p_op.run(Gtk.PrintOperationAction.PREVIEW, None)
#
    def draw_page (self, operation, print_context, page_number):
        cr = print_context.get_cairo_context()
        lo = PangoCairo.create_layout(cr)
        desc = Pango.FontDescription("sans 36")
        lo.set_font_description(desc)
#
        txt = """This line is longer than the others to show that word
        wrapping in Pango Cairo is working properly. \nLine1\nLine2
        \nLine4\nLine5\nLine\nLine6\nLine7\nLine8\nLine9\nLine10\nLine11
        \nLine12"""
#
        lo.set_markup(txt)
        lo.set_width(550 * Pango.SCALE)
        lo.set_wrap(Pango.WrapMode.WORD)
        cr.save()
        PangoCairo.update_layout(cr, lo)
        PangoCairo.show_layout(cr, lo)
        cr.restore()
# The problem is that the page displayed does not show Line11 or Line12,
# so I have to calculate where in the text that I should start a new
# page with cr.show_page().
# According to: https://stackoverflow.com/questions/26746456/
# using:
# ink, logical = lo_text.get_pixel_extents()
# returns Pango.rectangles.
#
# But I am stuck at this point. I *think* I need to get the size of the
# rectangles to calculate the ratio of text to screen fonts. I then
# will need to find the length of each string within txt to place on the page.

#        cr.show_page() #/14993720/
PrintExample()

Upvotes: 0

Views: 31

Answers (0)

Related Questions