Add Boxes.saved_context() context manager

Avoid directly accessing Boxes.ctx (the cairo context) all over the place.
Also have a more modern API for returning to a previous spot.
This commit is contained in:
Wayne Wylupski 2019-02-02 21:06:00 +01:00 committed by Florian Festi
parent acb457be2a
commit c573914bcd
1 changed files with 65 additions and 62 deletions

View File

@ -28,6 +28,7 @@ from argparse import ArgumentParser
import re import re
from functools import wraps from functools import wraps
from xml.sax.saxutils import quoteattr from xml.sax.saxutils import quoteattr
from contextlib import contextmanager
from boxes import edges from boxes import edges
from boxes import formats from boxes import formats
@ -59,10 +60,9 @@ def restore(func):
@wraps(func) @wraps(func)
def f(self, *args, **kw): def f(self, *args, **kw):
self.ctx.save() with self.saved_context():
pt = self.ctx.get_current_point() pt = self.ctx.get_current_point()
func(self, *args, **kw) func(self, *args, **kw)
self.ctx.restore()
self.ctx.move_to(*pt) self.ctx.move_to(*pt)
return f return f
@ -253,6 +253,19 @@ class Boxes:
"--burn", action="store", type=float, default=0.1, "--burn", action="store", type=float, default=0.1,
help="burn correction in mm (bigger values for tighter fit)") help="burn correction in mm (bigger values for tighter fit)")
@contextmanager
def saved_context(self):
"""
Generator: for saving and restoring cairo contexts.
:param cr: cairo context
"""
cr = self.ctx
cr.save()
try:
yield cr
finally:
cr.restore()
def open(self): def open(self):
""" """
Prepare for rendering Prepare for rendering
@ -515,13 +528,12 @@ class Boxes:
pass pass
if callback and callable(callback): if callback and callable(callback):
self.ctx.save() with self.saved_context():
self.moveTo(x, y) self.moveTo(x, y)
if number is None: if number is None:
callback() callback()
else: else:
callback(number) callback(number)
self.ctx.restore()
self.ctx.move_to(0, 0) self.ctx.move_to(0, 0)
def getEntry(self, param, idx): def getEntry(self, param, idx):
@ -874,20 +886,18 @@ class Boxes:
""" """
d = (x - hl - 2 * r) / 2.0 d = (x - hl - 2 * r) / 2.0
self.ctx.save()
# Hole # Hole
self.moveTo(d + 2 * r, 0) with self.saved_context():
self.edge(hl - 2 * r) self.moveTo(d + 2 * r, 0)
self.corner(-90, r) self.edge(hl - 2 * r)
self.edge(h - 3 * r) self.corner(-90, r)
self.corner(-90, r) self.edge(h - 3 * r)
self.edge(hl - 2 * r) self.corner(-90, r)
self.corner(-90, r) self.edge(hl - 2 * r)
self.edge(h - 3 * r) self.corner(-90, r)
self.corner(-90, r) self.edge(h - 3 * r)
self.corner(-90, r)
self.ctx.restore()
self.moveTo(0, 0) self.moveTo(0, 0)
self.curveTo(d, 0, d, 0, d, -h + r) self.curveTo(d, 0, d, 0, d, -h + r)
@ -1376,23 +1386,19 @@ class Boxes:
for i in range(cx): for i in range(cx):
for j in range(cy): for j in range(cy):
if (i + j) % 2: if (i + j) % 2:
self.ctx.save() with self.saved_context():
self.moveTo((5 * i) * wx, (5 * j) * wy) self.moveTo((5 * i) * wx, (5 * j) * wy)
self.polyline(*armx) self.polyline(*armx)
self.ctx.restore() with self.saved_context():
self.ctx.save() self.moveTo((5 * i + 5) * wx, (5 * j + 5) * wy, -180)
self.moveTo((5 * i + 5) * wx, (5 * j + 5) * wy, -180) self.polyline(*armx)
self.polyline(*armx)
self.ctx.restore()
else: else:
self.ctx.save() with self.saved_context():
self.moveTo((5 * i + 5) * wx, (5 * j) * wy, 90) self.moveTo((5 * i + 5) * wx, (5 * j) * wy, 90)
self.polyline(*army) self.polyline(*army)
self.ctx.restore() with self.saved_context():
self.ctx.save() self.moveTo((5 * i) * wx, (5 * j + 5) * wy, -90)
self.moveTo((5 * i) * wx, (5 * j + 5) * wy, -90) self.polyline(*army)
self.polyline(*army)
self.ctx.restore()
self.ctx.stroke() self.ctx.stroke()
################################################## ##################################################
@ -1547,21 +1553,19 @@ class Boxes:
bottom(l / 2.) bottom(l / 2.)
tops.append(l / 2.) tops.append(l / 2.)
self.ctx.save()
# complete wall segment # complete wall segment
self.edgeCorner(bottom, right, 90) with self.saved_context():
right(h) self.edgeCorner(bottom, right, 90)
self.edgeCorner(right, top, 90) right(h)
for n, d in enumerate(reversed(tops)): self.edgeCorner(right, top, 90)
if n % 2: # flex for n, d in enumerate(reversed(tops)):
self.edge(d) if n % 2: # flex
else: self.edge(d)
top(d) else:
self.edgeCorner(top, left, 90) top(d)
left(h) self.edgeCorner(top, left, 90)
self.edgeCorner(left, bottom, 90) left(h)
self.edgeCorner(left, bottom, 90)
self.ctx.restore()
if nr == len(sides) - 1: if nr == len(sides) - 1:
break break
@ -1806,15 +1810,14 @@ class Boxes:
part(*l, **kw) part(*l, **kw)
# draw matrix # draw matrix
for i in range(rows): for i in range(rows):
self.ctx.save() with self.saved_context():
for j in range(width): for j in range(width):
if "only" in move: if "only" in move:
break break
if width*i+j >= n: if width*i+j >= n:
break break
kw["move"] = "right" kw["move"] = "right"
part(*l, **kw) part(*l, **kw)
self.ctx.restore()
kw["move"] = "up only" kw["move"] = "up only"
part(*l, **kw) part(*l, **kw)