pycairo icon indicating copy to clipboard operation
pycairo copied to clipboard

Context.restore() doesn't restore the current point?

Open nedbat opened this issue 3 years ago • 3 comments

import cairo

with cairo.SVGSurface("example.svg", 200, 200) as surface:
    context = cairo.Context(surface)
    context.move_to(100, 200)
    print(context.get_current_point())
    context.save()
    context.move_to(300, 400)
    print(context.get_current_point())
    context.restore()
    print(context.get_current_point())

This prints:

(100.0, 200.0)
(300.0, 400.0)
(300.0, 400.0)

After the context.restore(), shouldn't the current point be restored to (100, 200)?

nedbat avatar Aug 05 '22 20:08 nedbat

After the context.restore(), shouldn't the current point be restored to (100, 200)?

Not sure, but reading the docs the current point restored to (100, 200) seems like expected behaviour. I think you'll get better help if you ask on the Cairo mailing list, https://lists.cairographics.org/mailman/listinfo/cairo. Here is a C repro of the same you did here, https://gist.github.com/naveen521kk/fa19da383be0a15b52c947a30bbee6b3

naveen521kk avatar Aug 06 '22 07:08 naveen521kk

This might be a documentation issue - in the docs it says "state" is saved/restored, but not what that state includes (e.g. position)... it'll be interesting to see what people say on the mailing list/

stuaxo avatar Aug 08 '22 13:08 stuaxo

I guess the entire path is not part of the save/restore:

import cairo

def show_path(label, context):
    path_str = str(context.copy_path())
    if path_str:
        path_str = path_str.replace("\n", "; ")
    else:
        path_str = "<empty>"
    print(f"{label}: {path_str}")


with cairo.SVGSurface("example.svg", 200, 200) as surface:
    context = cairo.Context(surface)

    show_path("Initial", context)

    context.move_to(100, 200)
    context.line_to(300, 400)
    context.close_path()

    show_path("Before save", context)

    context.save()
    show_path("Before stroke", context)
    context.stroke()
    show_path("After stroke", context)
    context.restore()

    show_path("After restore", context)

produces:

Initial: <empty>
Before save: move_to 100.000000 200.000000; line_to 300.000000 400.000000; close path; move_to 100.000000 200.000000
Before stroke: move_to 100.000000 200.000000; line_to 300.000000 400.000000; close path; move_to 100.000000 200.000000
After stroke: <empty>
After restore: <empty>

nedbat avatar Aug 09 '22 10:08 nedbat