demo-printing.lua 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. return function(parent, dir)
  2. local lgi = require 'lgi'
  3. local GLib = lgi.GLib
  4. local Gio = lgi.Gio
  5. local Gtk = lgi.Gtk
  6. local Gdk = lgi.Gdk
  7. local cairo = lgi.cairo
  8. local Pango = lgi.Pango
  9. local PangoCairo = lgi.PangoCairo
  10. local assert = lgi.assert
  11. -- Prepare settings.
  12. local settings = Gtk.PrintSettings {}
  13. local outdir = GLib.get_user_special_dir('DIRECTORY_DOCUMENTS')
  14. or GLib.get_home_dir()
  15. settings:set(Gtk.PRINT_OUTPUT_URI, 'file://' .. outdir .. '/gtk-demo.'
  16. .. (settings:get(Gtk.PRINT_OUTPUT_FILE_FORMAT) or 'pdf'))
  17. -- Create the print operation.
  18. local operation = Gtk.PrintOperation {
  19. use_full_page = true,
  20. unit = 'POINTS',
  21. embed_page_setup = true,
  22. print_settings = settings
  23. }
  24. local HEADER_HEIGHT = 10 * 72 / 25.4
  25. local HEADER_GAP = 3 * 72 / 25.4
  26. local font_size = 12
  27. local contents
  28. function operation:on_begin_print(context)
  29. contents = {}
  30. local height = context:get_height() - HEADER_HEIGHT - HEADER_GAP
  31. contents.lines_per_page = math.floor(height / font_size)
  32. -- Parse input stream into lines.
  33. local file = dir:get_child('demo-printing.lua')
  34. contents.filename = file:query_info(
  35. Gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 'NONE'):get_display_name()
  36. local input = Gio.DataInputStream {
  37. newline_type = 'ANY',
  38. base_stream = assert(file:read()),
  39. }
  40. while true do
  41. local line, len = input:read_line_utf8()
  42. if not line and len == 0 then break end
  43. assert(line, len)
  44. contents[#contents + 1] = line
  45. end
  46. contents.num_pages =
  47. math.floor((#contents - 1) / contents.lines_per_page + 1)
  48. self:set_n_pages(contents.num_pages)
  49. end
  50. function operation:on_draw_page(context, page_nr)
  51. local cr = context:get_cairo_context()
  52. local width = context:get_width()
  53. cr:rectangle(0, 0, width, HEADER_HEIGHT)
  54. cr:set_source_rgb(0.8, 0.8, 0.8)
  55. cr:fill_preserve()
  56. cr:set_source_rgb(0, 0, 0)
  57. cr.line_width = 1
  58. cr:stroke()
  59. local layout = context:create_pango_layout()
  60. layout.font_description = Pango.FontDescription.from_string('sans 14')
  61. layout.text = contents.filename
  62. local text_width, text_height = layout:get_pixel_size()
  63. if text_width > width then
  64. layout.width = width
  65. layout.ellipsize = 'START'
  66. text_width, text_height = layout:get_pixel_size()
  67. end
  68. cr:move_to((width - text_width) / 2, (HEADER_HEIGHT - text_height) / 2)
  69. cr:show_layout(layout)
  70. layout.text = ("%d/%d"):format(page_nr + 1, contents.num_pages)
  71. layout.width = -1
  72. text_width, text_height = layout:get_pixel_size()
  73. cr:move_to(width - text_width - 4, (HEADER_HEIGHT - text_height) / 2)
  74. cr:show_layout(layout)
  75. layout = context:create_pango_layout()
  76. layout.font_description = Pango.FontDescription.from_string('monospace')
  77. cr:move_to(0, HEADER_HEIGHT + HEADER_GAP)
  78. local line = page_nr * contents.lines_per_page
  79. for i = 1, math.min(#contents - line, contents.lines_per_page) do
  80. layout.text = contents[line + i]
  81. cr:show_layout(layout)
  82. cr:rel_move_to(0, font_size)
  83. end
  84. end
  85. -- Run the operation
  86. local ok, err = operation:run('PRINT_DIALOG', parent)
  87. if not ok then
  88. local dialog = Gtk.MessageDialog {
  89. transient_for = parent,
  90. destroy_with_parent = true,
  91. message_type = 'ERROR',
  92. buttons = 'CLOSE',
  93. message = err,
  94. on_response = Gtk.Widget.destroy,
  95. }
  96. dialog:show_all()
  97. end
  98. end,
  99. "Printing",
  100. table.concat {
  101. [[Gtk.PrintOperation offers a simple API to support printing ]],
  102. [[in a cross-platform way.]],
  103. }