Exemplo n.º 1
0
 def test_reloadFont(self):
     src = pathlib.Path(
         __file__).resolve().parent / "data" / "MutatorSans.ttf"
     assert src.exists()
     with tempfile.NamedTemporaryFile(suffix=".ttf") as ff:
         ff.write(src.read_bytes())
         firstModTime = os.stat(ff.name).st_mtime
         drawBot.newDrawing()
         drawBot.font(ff.name)
         self.assertEqual(ff.name, drawBot.fontFilePath())
         path = drawBot.BezierPath()
         path.text("E", font=ff.name, fontSize=1000)
         self.assertEqual((60.0, 0.0, 340.0, 700.0), path.bounds())
         ff.seek(0)
         ttf = TTFont(ff)
         ttf["glyf"]["E"].coordinates[0] = (400, 800)
         ff.seek(0)
         ttf.save(ff)
         secondModTime = os.stat(ff.name).st_mtime
         assert firstModTime != secondModTime, (firstModTime, secondModTime)
         drawBot.newDrawing()  # to clear the memoize cache in baseContext
         drawBot.font(ff.name)
         self.assertEqual(ff.name, drawBot.fontFilePath())
         path = drawBot.BezierPath()
         path.text("E", font=ff.name, fontSize=1000)
         self.assertEqual((60.0, 0.0, 400.0, 800.0), path.bounds())
Exemplo n.º 2
0
 def test_booleanoperationListIntersections(self):
     expected = [(75, 150), (150, 75)]
     import drawBot
     path1 = drawBot.BezierPath()
     path1.rect(50, 50, 100, 100)
     path2 = drawBot.BezierPath()
     path2.rect(75, 75, 100, 100)
     result = path1.intersectionPoints(path2)
     self.assertEqual(sorted(result), sorted(expected))
     path1.appendPath(path2)
     result = path1.intersectionPoints()
     self.assertEqual(sorted(result), sorted(expected))
Exemplo n.º 3
0
 def test_instructionStack(self):
     expected = [
         "reset None", "newPage 200 200", "save",
         "clipPath moveTo 5.0 5.0 lineTo 15.0 5.0 lineTo 15.0 15.0 lineTo 5.0 15.0 closePath",
         "restore", "image Image Object 10 10 0.5 None",
         "blendMode saturation", "transform 1 0 0 1 10 10",
         "drawPath moveTo 10.0 10.0 lineTo 110.0 10.0 lineTo 110.0 110.0 lineTo 10.0 110.0 closePath",
         "textBox foo bar 72.48291015625 84.0 55.0341796875 26.0 center",
         "frameDuration 10", "saveImage * {'myExtraAgrument': True}"
     ]
     with StdOutCollector() as output:
         import drawBot
         drawBot.newDrawing()
         drawBot.size(200, 200)
         drawBot.save()
         path = drawBot.BezierPath()
         path.rect(5, 5, 10, 10)
         drawBot.clipPath(path)
         drawBot.restore()
         im = drawBot.ImageObject()
         with im:
             drawBot.size(20, 20)
             drawBot.rect(5, 5, 10, 10)
         drawBot.image(im, (10, 10), alpha=.5)
         drawBot.blendMode("saturation")
         drawBot.translate(10, 10)
         drawBot.rect(10, 10, 100, 100)
         drawBot.text("foo bar", (100, 100), align="center")
         drawBot.frameDuration(10)
         drawBot.saveImage("*", myExtraAgrument=True)
         drawBot.endDrawing()
     self.assertEqual(output.lines(), expected)
Exemplo n.º 4
0
    def drawContour(self):

        color = self.colorScheme.colorsRGB['contour']

        drawBot.save()
        drawBot.fontSize(self.captionSize)
        drawBot.font(self.captionFont)

        for char in self.txt:
            uni = ord(char)
            glyphName = UV2AGL.get(uni)

            # interpolate
            g1 = self.font[glyphName].getLayer('regular')
            g2 = self.font[glyphName].getLayer('bold')
            glyph = RGlyph()
            glyph.name = g1.name
            glyph.unicode = g1.unicode
            glyph.interpolate(self.interpolationFactor, g1, g2)

            # draw contours
            drawBot.stroke(*color)
            drawBot.strokeWidth(self.contourStrokeWidth)
            drawBot.fill(None)
            B = drawBot.BezierPath()
            for contour in glyph.contours:
                contour.draw(B)
            drawBot.drawPath(B)

            # done glyph
            drawBot.translate(glyph.width, 0)

        drawBot.restore()
Exemplo n.º 5
0
    def newPath(self):
        """Answer a new empty drawBot.BezierPath.

        >>> context = DrawBotContext()
        >>> context.newPath()
        <BezierPath>
        """
        return drawBot.BezierPath()
Exemplo n.º 6
0
    def drawGlyph(self):
        color = self.colorScheme.colorsRGB['glyph']
        drawBot.save()
        drawBot.fontSize(self.captionSize)
        drawBot.font(self.captionFont)
        for char in self.txt:
            uni = ord(char)
            glyphName = UV2AGL.get(uni)

            # interpolate
            g1 = self.font[glyphName].getLayer('regular')
            g2 = self.font[glyphName].getLayer('bold')
            glyph = RGlyph()
            glyph.name = g1.name
            glyph.unicode = g1.unicode
            glyph.interpolate(self.interpolationFactor, g1, g2)

            # contours
            drawBot.fill(*color)
            B = drawBot.BezierPath()
            for contour in glyph.contours:
                contour.draw(B)
            drawBot.drawPath(B)

            # advance width
            if self.glyphWidthDraw:
                drawBot.save()
                drawBot.strokeWidth(self.glyphWidthStrokeWidth)
                drawBot.stroke(*color)
                drawBot.line((0, self.yBottom), (0, self.yTop))
                drawBot.restore()

            # glyph data
            if self.glyphDataDraw:
                h = self.captionSize * 1.5
                m = 40
                w = glyph.width - m * 2
                drawBot.save()
                drawBot.stroke(None)
                drawBot.fill(*color)
                y = self.yTop - h
                drawBot.textBox(glyph.name, (m, y, w, h))
                drawBot.textBox(str(glyph.unicode), (m, y, w, h), align='right')
                y = self.yBottom
                drawBot.textBox(str(int(glyph.width)), (m, y, w, h), align='center')
                drawBot.restore()

            # done glyph
            drawBot.translate(glyph.width, 0)

        # last margin
        if self.glyphWidthDraw:
            drawBot.strokeWidth(self.glyphWidthStrokeWidth)
            drawBot.stroke(*color)
            drawBot.line((0, self.yBottom), (0, self.yTop))

        # done
        drawBot.restore()
Exemplo n.º 7
0
def drawGlyph(g):
    # Get glyph outline
    f = g.font
    pen = CocoaPen(f)
    g.draw(pen)
    bezierPath = pen.path
    # Draw
    with db.savedState():
        db.translate(-g.width * 0.5, 450)  # Center the glyph
        path = db.BezierPath()
        path.setNSBezierPath(bezierPath)
        db.drawPath(path)
Exemplo n.º 8
0
 def shadow(self, clip=None, radius=10, alpha=0.3, color=Color.from_rgb(0,0,0,1)):
     if clip:
         cp = DATPen(fill=None).rect(clip)
         bp = db.BezierPath()
         cp.replay(bp)
         db.clipPath(bp)
     #elif self.rect:
     #    cp = DATPen(fill=None).rect(self.rect).xor(self.dat)
     #    bp = db.BezierPath()
     #    cp.replay(bp)
     #    db.clipPath(bp)
     db.shadow((0, 0), radius*3, list(color.with_alpha(alpha)))
Exemplo n.º 9
0
def draw(txt="a", variations={}, caption=""):
    db.newPage(w * scale, h * scale)
    db.scale(scale)
    db.fill(*BACKCOL)
    db.rect(0, 0, w, h)
    txt = db.FormattedString(txt, font="Handjet-Regular", fontSize=500, fontVariations=variations)
    db.fill(*TEXTCOL)
    db.stroke(None)
    path = db.BezierPath()
    path.text(txt, (w / 2, 95), align="center")
    db.drawPath(path)
    txt = db.FormattedString(caption, font="AdapterMonoPE-Regular", fontSize=11, fill=TEXTCOL)
    db.text(txt, (w / 2, 40), align="center")
def drawArrow(sf, a):
    x, y, ang = a.x, a.y, a.angle
    path = d.BezierPath()
    path.moveTo((50, 40))
    path.lineTo((0, 0))
    path.lineTo((50, -40))
    path.moveTo((0, 0))
    path.lineTo((120, 0))
    path.closePath()
    path.scale(sf)
    d.lineCap("round")
    d.lineJoin("round")
    path.rotate(ang, center=(0, 0))
    path.translate(x, y)
    d.fill(None)
    d.stroke(1, 0, 0, 0.5)
    d.strokeWidth(annoThickness / sf)
    d.drawPath(path)
def drawPlusMinus(sf, a):
    x, y = a.x, a.y
    x, y, ang = a.x, a.y, a.angle
    path = d.BezierPath()
    path.moveTo((-50, 0))
    path.lineTo((50, 0))
    if a.type == PLUS:
        path.moveTo((0, 50))
        path.lineTo((0, -50))
    path.closePath()
    path.scale(sf)
    d.lineCap("round")
    d.lineJoin("round")
    path.translate(x, y)
    d.fill(None)
    d.stroke(1, 0, 0, 0.5)
    d.strokeWidth(annoThickness / sf)
    d.drawPath(path)
Exemplo n.º 12
0
 def drawComponent(self):
     color = self.colorScheme.colorsRGB['component']
     tempName = '_tmp_'
     drawBot.save()
     for char in self.txt:
         uni = ord(char)
         glyphName = UV2AGL.get(uni)
         glyph = self.font[glyphName]
         drawBot.fill(*color + (0.5,))
         drawBot.stroke(*color)
         if len(glyph.components):
             B = drawBot.BezierPath()
             for component in glyph.components:
                 component.draw(B)
             drawBot.drawPath(B)
         # done glyph
         drawBot.translate(glyph.width, 0)
     drawBot.restore()
Exemplo n.º 13
0
def pixelBounds(fs):
    """Answers the pixel-bounds rectangle of the text.

    NOTE that @by can be a negative value, if there is text (e.g. overshoot)
    below the baseline.
    @bh is the amount of pixels above the baseline.
    For the total height of the pixel-map, calculate @ph - @py.
    For the total width of the pixel-map, calculate @pw - @px."""
    if not fs:
        return pt(0, 0, 0, 0)
    p = drawBotBuilder.BezierPath()
    p.text(fs, (0, 0))
    # OS X answers bw and bh as difference with bx and by. That is not really
    # intuitive, as the the total (width, height) then always needs to be
    # calculated by the caller. So, instead, the width and height answered is
    # the complete bounding box, and the (x, y) is the position of the bounding
    # box, compared to the (0, 0) of the string origin.
    bx, by, bw, bh = p.bounds()
    return pt(bx, by, bw - bx, bh - by)
Exemplo n.º 14
0
def draw(gn="a", variations={}, caption=""):
    db.newPage(w * scale, h * scale)
    db.scale(scale)
    db.fill(*BACKCOL)
    db.rect(0, 0, w, h)
    fs = db.FormattedString()
    fs.font("Handjet-Regular")
    fs.fontSize(200)
    fs.appendGlyph(gn)
    db.fill(*TEXTCOL)
    db.stroke(None)
    path = db.BezierPath()
    path.text(fs, (w / 2, 145), align="center")
    db.drawPath(path)
    fs = db.FormattedString(caption,
                            font="AdapterMonoPE-Regular",
                            fontSize=10,
                            fill=TEXTCOL)
    db.text(fs, (w / 2, 40), align="center")
Exemplo n.º 15
0
def make_box(box_size, box_depth):

    box = db.BezierPath()
    box.moveTo((box_size[0], 0))
    box.lineTo((0, 0))
    box.lineTo((0, box_size[1]))
    box.lineTo((box_size[0], box_size[1]))
    box.closePath()
    box.moveTo((0, 0))
    box.lineTo((box_depth[0], box_depth[1]))
    box.lineTo((box_depth[0], box_size[1] + box_depth[1]))
    box.lineTo((0, box_size[1]))
    box.closePath()
    box.moveTo((box_depth[0], box_size[1] + box_depth[1]))
    box.lineTo((box_size[0] + box_depth[0], box_size[1] + box_depth[1]))
    box.lineTo((box_size[0], box_size[1]))
    box.lineTo((0, box_size[1]))
    box.closePath()

    return box
Exemplo n.º 16
0
    def drawLayer(self):

        steps = 3
        alpha = 0.2 + 0.8 / (steps + 1)
        color = self.colorScheme.colorsRGB['layer']

        drawBot.save()

        # drawBot.fill(None)
        # drawBot.stroke(*color)
        # drawBot.strokeWidth(self.layerStrokeWidth)

        color += (alpha,)
        drawBot.fill(*color)
        drawBot.stroke(None)

        for char in self.txt:
            uni = ord(char)
            glyphName = UV2AGL.get(uni)

            g1 = self.font[glyphName].getLayer('regular')
            g2 = self.font[glyphName].getLayer('bold')

            layerGlyphs = []
            for i in range(steps):
                factor = i * 1.0 / (steps - 1)
                g3 = RGlyph()
                g3.name = g1.name
                g3.unicode = g1.unicode
                g3.interpolate(factor, g1, g2)
                layerGlyphs.append(g3)

            for g in layerGlyphs:
                B = drawBot.BezierPath()
                g.draw(B)
                drawBot.drawPath(B)

            drawBot.translate(g2.width, 0)

        drawBot.restore()
Exemplo n.º 17
0
    def test_export_SVG_mixin(self):
        expectedPath = os.path.join(testDataDir, "expected_svgMixin.svg")
        drawBot.newDrawing()
        drawBot.newPage(100, 100)
        path = drawBot.BezierPath()
        path.svgID = "hello"
        path.svgClass = "foo bar"
        path.svgLink = "drawbot.com"
        path.rect(0, 0, 20, 20)
        drawBot.drawPath(path)
        txt = drawBot.FormattedString()
        txt += "world"
        txt.svgID = "hello"
        txt.svgClass = "foo bar"
        txt.svgLink = "drawbot.com"
        drawBot.text(txt, (20, 20))

        with TempFile(suffix=".svg") as tmp:
            drawBot.saveImage(tmp.path)
            self.assertEqual(
                readData(tmp.path), readData(expectedPath),
                "Files %r and %s are not the same" % (tmp.path, expectedPath))
Exemplo n.º 18
0
    def drawSegment(self):

        color = self.colorScheme.colorsRGB['segment']
        r = self.bPointSize * 0.5        

        drawBot.save()
        drawBot.fontSize(self.captionSize)
        drawBot.font(self.captionFont)
        for char in self.txt:
            uni = ord(char)
            glyphName = UV2AGL.get(uni)

            # interpolate
            g1 = self.font[glyphName].getLayer('regular')
            g2 = self.font[glyphName].getLayer('bold')
            glyph = RGlyph()
            glyph.name = g1.name
            glyph.unicode = g1.unicode
            glyph.interpolate(self.interpolationFactor, g1, g2)

            # draw segment contours
            drawBot.stroke(*color)
            drawBot.strokeWidth(self.segmentStrokeWidth)
            drawBot.fill(None)

            B = drawBot.BezierPath()
            glyph.draw(B)
            drawBot.drawPath(B)

            # draw segment points
            drawBot.stroke(None)
            drawBot.fill(*color)
            for x, y in B.onCurvePoints:
                drawBot.oval(x - r, y - r, r * 2, r * 2)

            drawBot.translate(glyph.width, 0)

        drawBot.restore()
def draw(txt="a", variations={}, caption=""):
    db.newPage(w * scale, h * scale)
    db.scale(scale)
    db.fill(*BACKCOL)
    db.stroke(None)
    db.rect(0, 0, w, h)
    fs = db.FormattedString(txt,
                            font="Handjet-Regular",
                            fontSize=4600,
                            fontVariations=variations)
    path = db.BezierPath()
    path.text(fs, (w / 2, 1.58 * h), align="center")
    path_optim = path.copy()
    # remove overlaps when drawing the fill
    # but use the original contour when drawing the nodes
    path_optim.removeOverlap()
    path_optim.optimizePath()
    # draw the fill
    db.fill(*TEXTCOL)
    db.drawPath(path_optim)
    # draw nodes
    if path.contours:
        # drawing just the first contour is enough
        for s in path.contours[0]:
            for x, y in s:
                if (x, y) in path.onCurvePoints:
                    db.fill(*NODECOL)
                    db.stroke(*TEXTCOL)
                    db.strokeWidth(1)
                    db.oval(x - 4, y - 4, 8, 8)
    # draw caption
    fs = db.FormattedString(caption,
                            font="AdapterMonoPE-Regular",
                            fontSize=10,
                            fill=TEXTCOL)
    if caption:
        db.text(fs, (w / 2, 40), align="center")
Exemplo n.º 20
0
W = H = 600
M = 50
TW = 20  # Triangle size
TH = 18

# Create a new page canvas of 1000 x 1000 px
drawBot.newPage(W, H)
# Fill page with white background
drawBot.fill(1)
drawBot.rect(0, 0, W, H)
for n in range(200):
    # Random position within the page range
    x = M + random() * (W - M - M - TW)
    y = M + random() * (H - M - M - TW)
    # Set a random color
    drawBot.fill(random(), random(), random())
    path = drawBot.BezierPath()
    path.moveTo((x, y))
    path.lineTo((x + TW, y))
    path.lineTo((x + TW / 2, y + TH))
    path.closePath()
    drawBot.drawPath(path)

# Check is the _export/ folder exists, otherwise create it.
# We want to save exported files there, to avoid that those files get
# committed to Github everytime a new one is exported.
if not os.path.exists('_export'):
    os.path.mkdir('_export/')
# Export as png file in created _export folder (that does not sync in Github)
drawBot.saveImage('_export/0016-ManyTriangles.png')
Exemplo n.º 21
0
 def __init__(self, dat, rect=None):
     super().__init__()
     self.rect = rect
     self.dat = dat
     self.bp = db.BezierPath()
     self.dat.replay(self.bp)
Exemplo n.º 22
0
import drawBot
drawBot.newDrawing()
drawBot.size(200, 200)

testData = [
    ((25, 25, 50, 50), "rotate", (20,), (25, 25)),
    ((125, 25, 50, 50), "skew", (10, 10), (175, 25)),
    ((25, 125, 50, 50), "scale", (1.2, 1.4), (25, 175)),
]

for r, op, args, center in testData:
    drawBot.fill(0)
    bez = drawBot.BezierPath()
    bez.rect(*r)
    drawBot.drawPath(bez)
    with drawBot.savedState():
        drawBot.fill(1, 0, 0, 0.5)
        bez = drawBot.BezierPath()
        bez.rect(*r)
        getattr(bez, op)(*args, center=center)
        drawBot.drawPath(bez)
Exemplo n.º 23
0
    def makeInstance(self, axes, gname, glyph):
        nbAxes = maxNbAxes = len(axes)
        # steps = [1, 2]
        # maxNbAxes = max(steps)
        # for nbAxes in steps:

        speeds = [1 for i in range(nbAxes)]
        # LCM = self.ilcm(speeds)
        LCM = 60
        # print(LCM)
        # while ((LCM < 600 or LCM > 1200) or self.checkEqual(speeds)):
        #     speeds = [int(10/nbAxes + random.random()*60/nbAxes) for i in range(nbAxes)]
        #     LCM = self.ilcm(speeds)
        #     print(speeds, LCM, (LCM < 600 or LCM > 1200))

        alpha = 2 * math.pi / maxNbAxes
        ld = [{'Axis': l, 'PreviewValue': 0} for l in axes]
        # glyph.preview.computeDeepComponentsPreview(ld)
        origineGlyph = RGlyph()
        for atomicInstance in glyph.preview():
            atomicInstance = atomicInstance.glyph
            atomicInstance.draw(origineGlyph.getPen())
        # origineGlyph = glyph.preview.variationPreview.copy()
        origineGlyph.name = "interpo"
        db.newDrawing()
        for k in range(nbAxes):
            start = time.time()
            ld = [{
                'Axis': l,
                'PreviewValue': j == k
            } for j, l in enumerate(axes)]
            # glyph.preview.computeDeepComponentsPreview(ld)
            for g in range(LCM):

                H = 700
                W = 700
                db.newPage(W * 2.5, H)
                db.frameDuration(1 / 30)

                db.fill(1)
                db.rect(0, 0, W * 2.5, H)

                r = W / 3
                ainc = 0
                lines = []
                rands = []
                values = []

                for i in range(nbAxes):
                    path = db.BezierPath()
                    path.moveTo((H / 2, W / 2))
                    line = (r * math.sin(ainc), r * math.cos(ainc))
                    path.lineTo((H / 2 + line[0], W / 2 + line[1]))
                    dx = line[0] * .05
                    dy = line[1] * .05
                    path.moveTo((H / 2 + line[0] - dy, W / 2 + line[1] + dx))
                    path.lineTo((H / 2 + line[0] + dy, W / 2 + line[1] - dx))
                    db.stroke(.2)
                    db.strokeWidth(1.5)
                    db.fill(None)
                    db.drawPath(path)
                    ainc += alpha
                    lines.append((line, axes[i]["sourceName"]))
                    # v = getValueForAxeAtFrame(i, g, nbAxes, LCM, speeds[i])
                    # values.append(v)
                    if i == k:
                        rands.append([
                            1000 * abs(
                                math.sin(math.pi *
                                         (speeds[i] * c / LCM + speeds[i])))
                            for c in range(LCM)
                        ])
                    else:
                        rands.append([0 for c in range(LCM)])

                db.fill(1)
                db.oval(H / 2 - H * .01, W / 2 - W * .01, H * .02, W * .02)

                patharea = db.BezierPath()
                patharea.moveTo((H / 2, W / 2))
                patharea.lineTo((H / 2 + lines[0][0][0] * rands[0][g] / 1000,
                                 W / 2 + lines[0][0][1] * rands[0][g] / 1000))
                db.fill(0, 0, 0, .1)
                db.stroke(None)
                for c, (line, lineName) in enumerate(lines):
                    patharea.lineTo((H / 2 + line[0] * rands[c][g] / 1000,
                                     W / 2 + line[1] * rands[c][g] / 1000))
                patharea.lineTo((H / 2 + lines[0][0][0] * rands[0][g] / 1000,
                                 W / 2 + lines[0][0][1] * rands[0][g] / 1000))
                patharea.lineTo((H / 2, W / 2))
                db.drawPath(patharea)

                for c, (line, lineName) in enumerate(lines):
                    db.fill(0)  #1-rands[c]
                    db.stroke(.2)
                    db.strokeWidth(1)
                    db.oval(H / 2 + line[0] * rands[c][g] / 1000 - 4.5,
                            W / 2 + line[1] * rands[c][g] / 1000 - 4.5, 9, 9)
                    db.fill(.2)
                    ftxt = db.FormattedString(txt=lineName,
                                              font="GrtskZetta-Light",
                                              fontSize=14,
                                              align="center")
                    db.textBox(ftxt, (H / 2 + line[0] * 1.3 - 30,
                                      W / 2 + line[1] * 1.3 - 10, 60, 20))

                #########
                db.save()
                # ld = []
                # for j, l in enumerate(axes):
                #     ld.append({'Axis': l, 'PreviewValue':rands[j][g]/1000})

                # # d = {l:rands[j][g]/1000 for (j, l) in enumerate(axes)}

                # # glyph = interpolation(NewFont().newGlyph('temp'), ufo[gname], layersInfo = d)
                # # glyph = self.RCJKI.currentFont.get(gname)
                # glyph.preview.computeDeepComponentsPreview(ld)
                #########
                # print(glyph)
                db.translate(W * 1.3, H * .15)
                db.scale(.7 * H / 1000)
                db.stroke(.5)
                db.fill(None)
                db.rect(0, 0, 1000, 1000)
                db.fill(0)
                db.stroke(None)
                db.save()
                db.translate(0, 120)

                ratioX = ratioY = (rands[k][g]) / 1000
                resultGlyph = RGlyph()
                locations = {}
                for e in ld:
                    locations[e["Axis"]["sourceName"]] = e["PreviewValue"]
                for c in glyph.preview(locations):
                    c = c.glyph
                    c.draw(resultGlyph.getPen())
                interpoGlyph = interpolation.interpol_glyph_glyph_ratioX_ratioY_scaleX_scaleY(
                    origineGlyph, resultGlyph, ratioX, ratioY, 1, 1,
                    NewFont(showUI=False))
                db.drawGlyph(interpoGlyph)

                #         for aes in glyph.preview:
                #             # axis2layerName = {axisName:layerName for axisName, layerName in self.RCJKI.currentFont[aes['name']].lib['robocjk.atomicElement.glyphVariations'].items()}

                #             # lInfos = {axis2layerName[axisName]:v for axisName, v in aes['coord'].items()}
                # #            print(ae['coord'])
                #             for ae in aes.values():
                #                 glyph = ae[0]
                #                 print(glyph)
                #                 db.save()
                #                 self._drawGlyph(glyph)
                #                 db.restore()
                db.restore()
                db.restore()
                caption = db.FormattedString(txt='%s-axis' % (nbAxes),
                                             font="GrtskMega-Medium",
                                             fontSize=14,
                                             align="left")
                db.textBox(caption, (10, 10, W - 20, 20))

            stop = time.time()
            print(stop - start, "seconde for axis")

        pdfData = db.pdfImage()
Exemplo n.º 24
0
 def __init__(self):
     self.fill = (0, 0, 0, 1)
     self.bp = db.BezierPath()
Exemplo n.º 25
0
                 (10, 10 - padding - pathPadding))

    drawBot.image(path, (0, 0))
    drawBot.image(localPath, (w, 0))

    im1 = Image.open(path)
    im2 = Image.open(localPath)
    diff = ImageChops.difference(im1, im2)
    with tempfile.NamedTemporaryFile("wb", suffix=".png") as f:
        diff.save(f, "png")
        imDiff = drawBot.ImageObject(f.name)
        drawBot.image(imDiff, (w * 2, 0))

    hist = diff.histogram()

    redPath = drawBot.BezierPath()
    greenPath = drawBot.BezierPath()
    bluePath = drawBot.BezierPath()
    alphaPath = drawBot.BezierPath()
    reds = hist[0:256]
    greens = hist[256:512]
    blues = hist[512:768]
    alphas = hist[768:1024]

    redPath.moveTo((0, 0))
    greenPath.moveTo((0, 0))
    bluePath.moveTo((0, 0))
    alphaPath.moveTo((0, 0))
    for i in range(256):
        x = w * (i / 255)
        redPath.lineTo((x, h * (reds[i] / 255)))
    def doExport(self, f, savePath):
        # Export an image of the glyphs

        # Collect the glyph names from this font
        glyphNames = []
        glyphChoice = self.w.exportBox.glyphChoice.get()
        if glyphChoice == 0:
            glyphNames = list(f.selection)
        elif glyphChoice == 1:
            if 'public.glyphOrder' in f.lib.keys():
                allNames = f.lib['public.glyphOrder']
            else:
                allNames = list(f.keys())
                allNames.sort()
            # Only keep glyphs that have art
            for gn in allNames:
                g = f[gn]
                if len(g.contours):
                    glyphNames.append(gn)

        # Find the maximum glyph bounds, to figure out the grid spacing
        xMax = 0
        yMax = 0
        for gn in glyphNames:
            g = f[gn]
            bounds = g.bounds
            if bounds:
                thisXMax = bounds[2] - bounds[0]
                thisYMax = bounds[3] - bounds[1]
                if thisXMax > xMax:
                    xMax = thisXMax
                if thisYMax > yMax:
                    yMax = thisYMax
        xMax = int(math.ceil(xMax)) * self.pageScale
        yMax = int(math.ceil(yMax)) * self.pageScale

        # Figure out how many rows of glyphs we'll need, to lay them out in a square grid
        if len(glyphNames) < 1:
            rowCount = 1
        else:
            rowCount = math.ceil(math.sqrt(len(glyphNames)))
        colCount = math.ceil(len(glyphNames) / rowCount)

        # Work out the page dimensions, with glyphs centered up on a grid of xMax and yMax with a buffer to give a little space to work with
        pageWidth = ((colCount + 1) * xMax * self.bufferFactor)
        pageHeight = ((rowCount + 1) * yMax * self.bufferFactor)

        # Start drawing, keeping track of where each glyph was placed
        glyphLocations = []
        db.newDrawing()
        db.newPage(pageWidth, pageHeight)
        gIdx = 0
        for rowNumber in range(rowCount):
            for colNumber in range(colCount):
                if gIdx < len(glyphNames):
                    gridID = "%s-%s" % (colNumber, rowNumber)
                    gName = glyphNames[gIdx]
                    glyph = f[gName]
                    # Find the position to draw the glyph
                    # The glyph will be drawn centered on the center of each grid location
                    locX = ((colNumber * xMax * self.bufferFactor) +
                            xMax * self.bufferFactor)
                    locY = (pageHeight -
                            (rowNumber * yMax * self.bufferFactor) -
                            (yMax * self.bufferFactor))
                    # Adjust the grid location to center the glyph drawing
                    locX += -glyph.width * 0.5 * self.pageScale
                    locY += -yMax * 0.5
                    glyphLocations.append((gName, gridID))
                    # Draw the glyph
                    with db.savedState():
                        db.translate(locX, locY)
                        db.scale(self.pageScale, self.pageScale)
                        pen = CocoaPen(f)
                        glyph.draw(pen)
                        glyphPath = pen.path
                        path = db.BezierPath()
                        path.setNSBezierPath(glyphPath)
                        db.drawPath(path)
                        # Draw the glyph bounding box, for testing
                        if False:
                            db.fill(None)
                            db.stroke(0)
                            db.strokeWidth(10)
                            db.rect(0, 0, xMax, yMax)
                gIdx += 1

        # Prepare a settings document to save, with the number of rows, columns, spacing, scale, and glyph positions
        drawingData = {}
        drawingData["pageScale"] = self.pageScale
        drawingData["bufferFactor"] = self.bufferFactor
        drawingData["pageWidth"] = pageWidth
        drawingData["pageHeight"] = pageHeight
        drawingData["xMax"] = xMax
        drawingData["yMax"] = yMax
        drawingData["rowCount"] = rowCount
        drawingData["colCount"] = colCount
        drawingData["glyphLocations"] = glyphLocations

        # Save
        db.saveImage(savePath)
        plistPath = os.path.splitext(savePath)[0] + ".plist"
        with open(plistPath, "wb") as plistFile:
            dump(drawingData, plistFile)
Exemplo n.º 27
0
 xh = db.fontXHeight()
 while xh < h / 6:
     fontsize += 1
     db.fontSize(fontsize)
     xh = db.fontXHeight()
 print(fontname, "Calculated font size:", fontsize)
 target_dir = os.path.join(what, code)
 if not os.path.exists(target_dir):
     os.makedirs(target_dir)
 with open(path, mode="r") as f:
     for sample in f.readlines():
         sample = sample.strip()
         if sample != "":
             db.newDrawing()
             db.newPage(w, h)
             p = db.BezierPath()
             db.fill(1)
             db.stroke(None)
             db.rect(0, 0, w, h)
             db.fill(0)
             # produce SVGs with the text converted
             # to outlines
             fs = db.FormattedString(sample,
                                     font=fontname,
                                     fontSize=fontsize)
             p.text(fs, (w / 2, h_offset), align="center")
             db.drawPath(p)
             db.saveImage(os.path.join(target_dir, sample + ".svg"))
             tw, _ = db.textSize(fs)
             if tw > (w - 2 * margin):
                 print("Text '%s' in typeface %s is too wide." %
Exemplo n.º 28
0
import drawBot

drawBot.newDrawing()
drawBot.size(600, 100)
p1 = drawBot.BezierPath()
p1.oval(5, 5, 70, 70)
p2 = drawBot.BezierPath()
p2.rect(25, 25, 70, 70)
drawBot.fill(0, 0.3)
drawBot.stroke(0)

drawBot.drawPath(p1)
drawBot.drawPath(p2)

pUnion = p1 | p2
pIntersection = p1 & p2
pXor = p1 ^ p2
pDiff1 = p1 % p2
pDiff2 = p2 % p1

for p in [pUnion, pIntersection, pXor, pDiff1, pDiff2]:
    drawBot.translate(100, 0)
    drawBot.drawPath(p)
Exemplo n.º 29
0
def drawOutline(outline):
    bez = db.BezierPath()
    outline.drawPoints(bez)
    db.drawPath(bez)
        try:
            style_name = ttfont.getName(*entry).toStr()
            break
        except:
            pass
    else:
        style_name = " "
    return style_name

for i, word in enumerate(args.words):

    key = lower_file_name(word)
    fontSize = 1000
    font = fonts[i%len(fonts)]
    sub_folder = font.parent.stem
    bez = db.BezierPath()
    db.fontSize(fontSize)
    db.font(font)
    s = db.FormattedString(word, fontSize=fontSize, font=font)
    content_width, content_height = db.textSize(word)
    space = db.textSize(" ")[0]
    bez.text(s, (0, 0))
    yShift = abs(db.fontDescender())+50
    bez.translate(0, yShift)

    bez_left, bez_bottom, bez_right, bez_top = bez.bounds()


    canvas_width = content_width
    canvas_height = db.fontAscender() + abs(db.fontDescender()) + 100