spakin / SimpInkScr

Simple Inkscape Scripting
https://inkscape.org/~pakin/%E2%98%85simple-inkscape-scripting
GNU General Public License v3.0
320 stars 31 forks source link

"Resize to content" leads to coordinate shift #87

Closed trappitsch closed 1 year ago

trappitsch commented 1 year ago

Hi @spakin This is a really nice extension, thanks for providing it! I have the following issue (minimal version). Starting with a completely new document and drawing a circle with circle((0, 0), 100), the circle is as expected centered in the top left corner of my document. Inkscape tells me, that the circle starts at (-100.5, -100.5) with a width of 201 and a height of 201 (so far so good). Going to "Document Properties -> Resize to content", Inkscape now shifts the circle to 0, 0 and the viewbox is only around the object - as expected. However, if I now draw another circle, e.g., circle((0,0), 50), I get a second circle that is concentric to the first and not as I would have expected centered in the top left corner, i.e., the coordinates still seem to grab back to the original, unshifted viewbox. Inkscape tells me, that the x,y position of the circle is (50, 50), and not as expected (-50.5, -50.5). My assumption is that the "Resize to content" shifted the viewbox, but didn't touch the original coordinate system of the document. Is there a way to access the original system such that I can correct for any shifts? Or is this actually an unintended behavior?

Some additional info on my installation (in case it's useful):

Inkscape 1.2.2 (1:1.2.2+202212051552+b0a8486541)

    GLib version:     2.72.4
    GTK version:      3.24.33
    glibmm version:   2.66.2
    gtkmm version:    3.24.5
    libxml2 version:  2.9.13
    libxslt version:  1.1.34
    Cairo version:    1.16.0
    Pango version:    1.50.6
    HarfBuzz version: 2.7.4

    OS version:       Ubuntu 22.04.2 LTS
spakin commented 1 year ago

I observe that behavior, too. Here's why it occurs: The original circle never moves. Instead, Inkscape adds a transform="translate(100.5,100.5)" to the layer object. Consequently, the original circle remains at position (0, 0); it's just that a circle drawn at (0, 0) is now rendered at (100.5, 100.5), the new center of the canvas. When you draw the second circle at (0, 0), it too gets rendered at (100.5, 100.5).

Simple Inkscape Scripting's new canvas.resize_to_content method produces the same results but for a different reason. Rather than add a tranform to the layer, canvas.resize_to_content sets the viewbox to begin at (-100, -100) and extend 200 units in each dimension. Again, the first circle remains at (0, 0) and the second circle, also at (0, 0), is concentric. It's just that the upper left of the canvas is now (-100, -100) instead of (0, 0).

To achieve what you're hoping to see you may need explicitly to shift all shapes on the page before resizing the canvas:

for obj in all_shapes():
    obj.translate((100, 100))

If you don't want to hardwire (100, 100) you can make a first pass over all shapes, invoking each shape's bounding_box methods and keeping track of the minimum x and y values. Then make a second pass in which you shift each shape by (−x, −y), leaving (0, 0) in the upper-left corner of the canvas.

Or, if you don't want to move the existing objects, you instead can add (−x, −y) to the coordinates for all subsequently drawn shapes.

trappitsch commented 1 year ago

Interesting, thanks for the clarification. I'm using the script at the moment for automatically labeling sample in a secondary electron map, which I will have shifted and resized a few times. One nice way of working around this is actually the following - since the behavior is layer specific:

l = layer("auto_label_layer")
l.append(circle((0, 0), 100)

The new layer that is created by default has the right translation, i.e., is aligned with the current view settings. So no shift or checking is necessary and for my application, I want these automatic labels to be in a new layer anyway. Maybe this helps somebody else as well.

Closing this since your explanation is very helpful and its not an issue anymore :) Thank you!

spakin commented 1 year ago

Thanks for sharing your solution. I hope others find it useful.