3

I'm trying to print a dynamically created SVG in Python using Cairo and RSVG with the following code (it's a Gtk application).
It is a special type of paper, 147x205mm exactly. If I open the SVG in EOG I can print it without issues, but using the following code it renders the SVG much too big, so only a part of it fits on the paper.
I'm looking for a way to tell RSVG/Cairo to scale the SVG to the printing context.

#in the initializer:
    self.PrintSettings = Gtk.PrintSettings()
    self.PrintSettings.set_paper_width(147, Gtk.Unit.MM)
    self.PrintSettings.set_paper_height(204, Gtk.Unit.MM)

    self.PageSetup = Gtk.PageSetup()
    pageSize = Gtk.PaperSize.new_custom("bill", "Papel de factura", 147, 205, Gtk.Unit.MM)
    self.PageSetup.set_paper_size(pageSize)
    self.PageSetup.set_top_margin(0, Gtk.Unit.MM)
    self.PageSetup.set_bottom_margin(0, Gtk.Unit.MM)
    self.PageSetup.set_left_margin(0, Gtk.Unit.MM)
    self.PageSetup.set_right_margin(0, Gtk.Unit.MM)

def on_PrintButton_clicked(self, widget): 
    self.make_bill() #generates the SVG as "./temp.svg"         

    printOperation = Gtk.PrintOperation()
    printOperation.set_n_pages(1)
    printOperation.set_print_settings(self.PrintSettings)        

    printOperation.set_default_page_setup(self.PageSetup)

    printOperation.connect("draw_page", self.print_bill)
    print printOperation.run(Gtk.PrintOperationAction.PRINT_DIALOG, self)

def print_bill(self, printOperation, printContext, pageNr):    
    pageSetup = printContext.get_page_setup()
    cairoContext = printContext.get_cairo_context()
    svg = rsvg.Handle(file = os.getcwd() + "/temp.svg")
    svg.render_cairo(cairoContext)
    return

In case it is useful, the beginning of my SVG (always the same):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="513.77954"
height="726.37793"
id="svg2">
<defs
 id="defs4" />
<metadata
 id="metadata7">
 <rdf:RDF>
  <cc:Work
     rdf:about="">
    <dc:format>image/svg+xml</dc:format>
    <dc:type
       rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
    <dc:title></dc:title>
  </cc:Work>
 </rdf:RDF>
</metadata>
<g
 transform="translate(0,-325.9842)"
 id="layer1">

Update
I added the following lines to print_bill

    print printContext.get_width() # returns 416.692913386
    print printContext.get_height() # returns 581.102362205

This is exactly equal to the size of the SVG. I re-checked in Inkscape, which tells me, that this is the size and PX, but if I look up the values in MM it shows the correct ones.
Maybe there is a SVG tag to fix this?

neo post modern
  • 2,262
  • 18
  • 30

1 Answers1

0

I played around (a lot) with the transform parameter of the <g> element all my elements are wrapped in.
Reducing the first and forth parameter of the matrix in the transform tag allows you to size it into the required paper/drawing area.
It's also possible to move the complete drawing using the fifth and six parameter.

Example-Code:

<g
    transform="matrix(0.70,0,0,0.70,20,-190)"
    id="layer1">

I still assume (hope) there is a Cairo/Python way to solve this in a better way, but this should help.

neo post modern
  • 2,262
  • 18
  • 30