def draw(self, scale=0.01, cm=False): self.dat.scale(scale, point=False) self.page = self.page.scale(scale) b = self.dat.bounds() limits = Rect(0, 0, 11, 8.5) if cm: limits = limits.scale(2.54) if b.x >= 0 and b.y >= 0 and b.w <= limits.w and b.h <= limits.h: print("Drawing!") else: print("Too big!", b) return False ad = axidraw.AxiDraw() ad.interactive() ad.options.units = 1 if cm else 0 ad.options.speed_pendown = 10 ad.options.speed_penup = 50 ad.options.pen_rate_raise = 10 ad.connect() ad.penup() self.ad = ad tp = TransformPen(self, (1, 0, 0, -1, 0, self.page.h)) self.dat.replay(tp) time.sleep(MOVE_DELAY) ad.penup() ad.moveto(0, 0) ad.disconnect()
def test_gss(self): """ A rect passed to gs and gss should create the same value on the pen """ dp1 = (DraftingPen().define(r=Rect(100, 100)).gss("$r")) dp2 = (DraftingPen().define(r=Rect(100, 100)).gs("$r")) self.assertEqual(dp1.value, dp2.value)
def bounds(self): """Calculate the bounds of this shape; mostly for internal use.""" try: cbp = BoundsPen(None) self.replay(cbp) mnx, mny, mxx, mxy = cbp.bounds return Rect((mnx, mny, mxx - mnx, mxy - mny)) except: return Rect(0, 0, 0, 0)
def test_transforms(self): dp = (DraftingPen(Rect(100, 100)).frame(Rect(100, 100)).align(Rect(200, 200))) self.assertEqual(dp.frame().mxx, 150) self.assertEqual(dp.value[-2][-1][-1][0], 50) self.assertEqual(dp.copy().rotate(45).round().value, dp.copy().rotate(360 + 45).round().value) self.assertEqual(dp.copy().scale(2).ambit().w, 200)
def roundedRect(self, rect, hr, vr=None): """Rounded rectangle primitive""" if vr is None: vr = hr l, b, w, h = Rect(rect) r, t = l + w, b + h K = 4 * (math.sqrt(2)-1) / 3 circle = hr == 0.5 and vr == 0.5 if hr <= 0.5: hr = w * hr if vr <= 0.5: vr = h * vr self.moveTo((l + hr, b)) if not circle: self.lineTo((r - hr, b)) self.curveTo((r+hr*(K-1), b), (r, b+vr*(1-K)), (r, b+vr)) if not circle: self.lineTo((r, t-vr)) self.curveTo((r, t-vr*(1-K)), (r-hr*(1-K), t), (r-hr, t)) if not circle: self.lineTo((l+hr, t)) self.curveTo((l+hr*(1-K), t), (l, t-vr*(1-K)), (l, t-vr)) if not circle: self.lineTo((l, b+vr)) self.curveTo((l, b+vr*(1-K)), (l+hr*(1-K), b), (l+hr, b)) self.closePath() return self
def test_pens_ambit(self): dps = ( DraftingPens([ DraftingPen(Rect(50, 50)), DraftingPen(Rect(100, 100, 100, 100)) ]) #.print(lambda x: x.tree()) ) ram = dps.ambit() self.assertEqual(ram, Rect(0, 0, 200, 200)) moves = [] dps.walk(lambda p, pos, _: moves.append([p, pos])) self.assertEqual(moves[0][0], dps) self.assertEqual(moves[0][1], -1) self.assertEqual(moves[1][1], 0)
def test_cairo_pdf(self): r = Rect(300, 300) pdf = renders / "test_cairo.pdf" dp = (StSt("CDEL", co, 100, wdth=0.5).pens().align(r)) CairoPen.Composite(dp, r, pdf) self.assertEqual(len(dp), 4) self.assertEqual(type(dp), DraftingPens)
def new_drawing(rect: Rect = Rect(1000, 1000), count=1, save_to=None): db.newDrawing() for idx in range(0, count): with new_page(rect) as r: yield idx, r if save_to: db.saveImage(str(save_to)) db.endDrawing()
def test_gs_relative_moves(self): r = Rect(100, 100) dp = (DraftingPen().define(r=r).gs("$r↖ ¬OX50OY-50 §OY-50")) self.assertEqual(len(dp.value), 4) self.assertEqual(dp.value[0][-1][0], Point(0, 100)) self.assertEqual(dp.value[1][-1][0], Point(50, 50)) self.assertEqual(dp.value[2][-1][0], Point(0, 50))
def test_gs_arrowcluster(self): r = Rect(100, 100) dp = (DraftingPen().define(r=r).gs("$r↖↗↘")) self.assertEqual(len(dp.value), 4) self.assertEqual(dp.value[0][-1][0], Point(0, 100)) self.assertEqual(dp.value[1][-1][0], Point(100, 100)) self.assertEqual(dp.value[2][-1][0], Point(100, 0))
def resetGlyphRun(self): self.glyphs = self.style.font.font.getGlyphRunFromTextInfo(self.text_info, addDrawings=False, features=self.features, varLocation=self.variations) #self.glyphs = self.style.font.font.getGlyphRun(self.text, features=self.features, varLocation=self.variations) x = 0 for glyph in self.glyphs: glyph.frame = Rect(x+glyph.dx, glyph.dy, glyph.ax, self.style.capHeight) x += glyph.ax self.getGlyphFrames()
def test_cairo_png(self): with test_image(self, "test_cairo.png") as (i, r): rr = Rect(0, 0, 100, 100) dp = (DraftingPen().define(r=rr, c=75).gs( "$r↗ ↘|$c|$r↓ ↙|$c|$r↖").align(r).scale(1.2).rotate(180).f( hsl(0.5, a=0.1)).s(hsl(0.9)).sw(5)) CairoPen.Composite(dp, r, i) self.assertEqual(len(dp.value), 4) self.assertEqual(type(dp), DraftingPen)
def ambit(self, th=False, tv=False): """Get the calculated rect boundary of the DraftingPen; `th` means `(t)rue (h)orizontal`; `ty` means `(t)rue (v)ertical`; passing either ignores a non-bounds-derived frame in either dimension""" if self._frame: if (th or tv) and len(self.value) > 0: f = self._frame b = self.bounds() if th and tv: return b elif th: return Rect(b.x, f.y, b.w, f.h) else: return Rect(f.x, b.y, f.w, b.h) else: return self._frame else: return self.bounds()
def test_image(test: unittest.TestCase, path, rect=Rect(300, 300)): img = (renders / path) hash_before = hash_img(img) if img.exists(): img.unlink() yield (img, rect) hash_after = hash_img(img) test.assertEqual(hash_after, hash_before) test.assertEqual(img.exists(), True)
def pens(self, align=False): rects = self.lineRects() pens = _PensClass() for idx, l in enumerate(self.lines): r = rects[idx] dps = l.pens().translate(r.x, r.y) # r.x dps.addFrame(Rect(r.x, r.y, r.w, r.h)) #if align: # dps.container = Rect(0, r.y, r.w, r.h) # dps.align(dps.container, x=self.style.x, y=None) pens.append(dps) return pens
def test_gs(self): r = Rect(0, 0, 100, 100) dps = DraftingPens() dp = (DraftingPen().define(r=r).gs("$r↖ $r↗ ↘|65|$r↙ ɜ")) self.assertEqual(len(dp.value), 4) self.assertEqual(dp.value[-2][-1][0], Point(100, 35)) self.assertEqual(dp.value[-1][0], "endPath") self.assertEqual(dp.unended(), False) dps.append(DraftingPens([dp])) self.assertEqual(len(dps.tree().splitlines()), 3) self.assertEqual(dps.tree().splitlines()[-1], " | | DraftingPen<4mvs:end/>")
def add_page(): global page_count page_count += 1 newPage("LetterLandscape") page = Rect(width(), height()).inset(30, 30) labels, textarea = page.divide(20, "mny") with savedState(): stroke(0.9) strokeWidth(1) line(*labels.en) with savedState(): now = datetime.today().strftime('%Y/%m/%d %H:%M') fontSize(10) font(secondary_font) text(f"{designer_name} / Type West", labels.psw) text(font_name, labels.ps, align="center") text(f"{now} — Pg.{page_count}", labels.pse, align="right") font(font_name) return textarea.subtract(30, "mny")
def ambit(self, th=False, tv=False): """Get the calculated rect boundary of the DraftingPens; `th` means `(t)rue (h)orizontal`; `ty` means `(t)rue (v)ertical`; passing either ignores a non-bounds-derived frame in either dimension""" if self._frame and (th == False and tv == False): return self._frame else: try: union = self._pens[0].ambit(th=th, tv=tv) for p in self._pens[1:]: union = union.union(p.ambit(th=th, tv=tv)) return union except Exception as e: return Rect(0, 0, 0, 0)
def StSt(text, font, font_size=24, rect=Rect(1080, 1080), xa="mdx", **kwargs): if isinstance(font, Style): style = font else: style = Style(font, font_size, **kwargs) fit = kwargs.get("fit", None) leading = kwargs.get("leading", 10) if "\n" in text: lockup = Composer(rect, text, style, fit=fit, leading=leading).pens() if xa: lockup = lockup.xa(xa) else: lockup = StyledString(text, style) if fit: lockup.fit(fit) lockup = lockup.pens() return lockup
def boxCurveTo(self, point, factor, pt, po=(0, 0), mods={}, flatten=False): if flatten: self.lineTo(pt) return self a = Point(self.value[-1][-1][-1]) d = Point(pt) box = Rect.FromMnMnMxMx([min(a.x, d.x), min(a.y, d.y), max(a.x, d.x), max(a.y, d.y)]) try: f1, f2 = factor except TypeError: if isinstance(factor, Atom): f1, f2 = (factor[0], factor[0]) else: f1, f2 = (factor, factor) if isinstance(point, str): p = box.point(point) p1, p2 = (p, p) elif isinstance(point, Point): p1, p2 = point, point else: p1, p2 = point p1 = box.point(p1) p2 = box.point(p2) p1 = p1.offset(*po) p2 = p2.offset(*po) b = a.interp(f1, p1) c = d.interp(f2, p2) mb = mods.get("b") mc = mods.get("c") if mb: b = mb(b) elif mc: c = mc(c) self.curveTo(b, c, d) return self
def __init__(self, *args): SHContext.__init__(self) RecordingPen.__init__(self) from drafting.pens.draftingpens import DraftingPens self.single_pen_class = DraftingPen self.multi_pen_class = DraftingPens self._tag = None self._frame = None self._visible = True self._parent = None self._last = None self._alpha = 1 self._typographic = False self.glyphName = None self._current_attr_tag = "default" self.clearAttrs() self.data = {} self.defs = None self.macros = {} for _, arg in enumerate(args): if isinstance(arg, str): self.tag(arg) elif isinstance(arg, DraftingPen): self.replace_with(arg) elif isinstance(arg, Rect): self.rect(arg) elif isinstance(arg, Line): self.line(arg) elif isinstance(arg, Point): self.oval(Rect.FromCenter(arg, 50, 50))
def page_rect() -> Rect: return Rect(db.width(), db.height())
def new_page(r: Rect = Rect(1000, 1000)): _r = Rect(r) db.newPage(*_r.wh()) yield _r
def test_remove_blanks(self): dps = (DraftingPens([DraftingPen(Rect(50, 50)), DraftingPen()])) self.assertEqual(len(dps), 2) dps.remove_blanks() self.assertEqual(len(dps), 1)
def img(self, src=None, rect=Rect(0, 0, 500, 500), pattern=True, opacity=1.0): """Get/set an image fill""" if src: return self.attr(image=dict(src=src, rect=rect, pattern=pattern, opacity=opacity)) else: return self.attr(field="image")
def test_reverse(self): dp = (DraftingPen().define(r=Rect(100, 100)).gs("$r↖ $r↗ $r↘ ɜ")) p1 = dp.value[0][-1] p2 = dp.reverse().value[-2][-1] self.assertEqual(p1, p2)