Пример #1
0
def number(num: int) -> Line:
    if 0 > num > 9999:
        raise RuntimeError(
            'Cistercian numbers can only represent numbers from 0 to 9999')

    num_drawing = Group()
    num_drawing.add(zero())
    if num != 0:
        for i, digit in enumerate(reversed(str(num))):
            digit_drawing = draw_functions[int(digit)]()
            offset = offsets[i]
            try:
                isnt_flat = bool(digit_drawing['y1'] - digit_drawing['y2'])
            except KeyError:
                isnt_flat = True
            if offset[1] and isnt_flat:
                offset = (offset[0], offset[1] - 10)
            digit_drawing.translate(offset)
            if i % 2 != 0:
                digit_drawing.scale((-1, 1))
                digit_drawing.translate((-10, 0))
            if i > 1:
                if isnt_flat:
                    digit_drawing.scale((1, -1))
                    digit_drawing.translate((0, -10))
                elif digit == '2':
                    digit_drawing.translate((0, -20))
            num_drawing.add(digit_drawing)

    num_drawing.translate((20, 20))
    return num_drawing
Пример #2
0
    def save(cls, image, filename, mosaic=False):
        # Use debug=False everywhere to turn off SVG validation,
        # which turns out to be obscenely expensive in this
        # library.
        DEBUG = False

        svg = svgwrite.Drawing(filename=filename,
                               style='background-color: black;',
                               size=(("%dpx" % (2 * image.r_outer),
                                      "%dpx" % (2 * image.r_outer))),
                               debug=DEBUG)

        group = Group(debug=DEBUG)
        group.translate(image.r_outer, image.r_outer)

        for y, row in enumerate(image.pixels):
            ring = image.rings[y]

            theta = 2 * math.pi / len(row)

            r1 = ring.center + image.r_ring / 2
            r2 = ring.center - image.r_ring / 2

            for x, c in enumerate(row):

                if mosaic:
                    path = Path(stroke='black',
                                stroke_width=1,
                                fill=cls.color_hex(c),
                                debug=DEBUG)

                    path.push((('M', 0, r2),
                               ('L', 0, r1),
                               ('A', r1, r1, 0, '0,0',
                                (r1 * sin(theta),
                                 r1 * cos(theta))),
                               ('L', r2 * sin(theta),
                                     r2 * cos(theta)),
                               ('A', r2, r2, 0, '0,1',
                                (0, r2))))
                else:
                    path = Path(stroke=cls.color_hex(c),
                                stroke_width=image.r_pixel,
                                fill='none',
                                debug=DEBUG)

                    path.push((('M', 0, ring.center),
                               ('A', ring.center, ring.center, 0, '0,0',
                                (ring.center * sin(theta),
                                 ring.center * cos(theta)))))

                path.rotate(180 - degrees(theta * (x + 1)),
                            center=(0, 0))

                group.add(path)

        svg.add(group)
        svg.save()
Пример #3
0
    def save(cls, image, filename, mosaic=False):
        # Use debug=False everywhere to turn off SVG validation,
        # which turns out to be obscenely expensive in this
        # library.
        DEBUG = False

        svg = svgwrite.Drawing(filename=filename,
                               style='background-color: black;',
                               size=(("%dpx" % (2 * image.r_outer),
                                      "%dpx" % (2 * image.r_outer))),
                               debug=DEBUG)

        group = Group(debug=DEBUG)
        group.translate(image.r_outer, image.r_outer)

        for y, row in enumerate(image.pixels):
            ring = image.rings[y]

            theta = 2 * math.pi / len(row)

            r1 = ring.center + image.r_ring / 2
            r2 = ring.center - image.r_ring / 2

            for x, c in enumerate(row):

                if mosaic:
                    path = Path(stroke='black',
                                stroke_width=1,
                                fill=cls.color_hex(c),
                                debug=DEBUG)

                    path.push(
                        (('M', 0, r2), ('L', 0, r1), ('A', r1, r1, 0, '0,0',
                                                      (r1 * sin(theta),
                                                       r1 * cos(theta))),
                         ('L', r2 * sin(theta),
                          r2 * cos(theta)), ('A', r2, r2, 0, '0,1', (0, r2))))
                else:
                    path = Path(stroke=cls.color_hex(c),
                                stroke_width=image.r_pixel,
                                fill='none',
                                debug=DEBUG)

                    path.push((('M', 0, ring.center),
                               ('A', ring.center, ring.center, 0, '0,0',
                                (ring.center * sin(theta),
                                 ring.center * cos(theta)))))

                path.rotate(180 - degrees(theta * (x + 1)), center=(0, 0))

                group.add(path)

        svg.add(group)
        svg.save()
Пример #4
0
def new_drawing(filename='plot.svg', display_scale=1):
	from svgwrite.drawing   import Drawing
	from svgwrite.container import Group
	size = 2 * PADDING + SCALE
	dwg = Drawing(filename, size=(size * display_scale, size * display_scale))
	dwg.viewbox(minx=0, miny=0, width=size, height=size)
	
	add_stylesheet(dwg)
	
	canvas = Group(id='canvas')
	canvas.translate(PADDING, PADDING)
	canvas.scale(1, -1)
	canvas.translate(0, -SCALE)
	dwg.add(canvas)
	
	return dwg, canvas
Пример #5
0
def convert_font():
    cwd = pathlib.Path.cwd()

    for root, dirs, files in os.walk('{}/exports'.format(cwd)):
        for name in files:
            source = os.path.join(root, name)
            target = 'fonts/{}.min.svg'.format(name.split('.')[0])
            print(source)

            try:
                paths, attr = svg2paths(source)
            except Exception as e:
                print(e)
                continue

            try:
                xmin, xmax, ymin, ymax = bounding_box(paths)
            except Exception as e:
                print(e)
                continue

            dx = xmax - xmin
            dy = ymax - ymin

            viewbox = '{} {} {} {}'.format(xmin, ymin, dx, dy)

            attr = {'viewBox': viewbox, 'preserveAspectRatio': 'xMidYMid meet'}

            wsvg(paths=paths, svg_attributes=attr, filename=source)

            doc = SaxDocument(source)
            d = doc.get_pathd_and_matrix()[0]
            g = Group()

            dwg = svgwrite.Drawing(target)
            dwg.viewbox(minx=xmin, miny=ymin, width=dx, height=dy)
            dwg.add(g)
            g.scale(sx=1, sy=-1)
            g.translate(tx=0, ty=-dy - ymin * 2)
            g.add(dwg.path(d))
            dwg.save()

            generate_pdf(target)
Пример #6
0
    def encode(self, bits_data: List[int]):
        tattoo_bit_height = int(len(bits_data) / 8)
        x, y = 0, 0
        xmin, xmax = 0, 0
        ymin, ymax = 0, 0
        tattoo = Group(id="tattoo")
        for j in range(tattoo_bit_height):
            for i in range(8):
                if x > xmax:
                    xmax = x
                if y > ymax:
                    ymax = y
                bit = bits_data.pop()
                if bit == 0:
                    tattoo.add(Use("#zero", (x, y)))
                elif bit == 1:
                    tattoo.add(Use("#one", (x, y)))
                else:
                    raise RuntimeError()
                x, y = self.shift_bit(x, y)
            x, y = self.shift_byte(j, y)

        xmax += self.poly.inner_circle_radius * self.dimens.bit_radius * 2
        ymax += self.poly.outer_circle_radius * self.dimens.bit_radius * 2
        tattoo_width = xmax - xmin
        tattoo_height = ymax - ymin
        scaled_width_mm = 65
        scale_factor = scaled_width_mm * 3.78 / tattoo_width
        scaled_height_mm = tattoo_height * scale_factor / 3.78
        tattoo.scale(scale_factor)
        tattoo.translate(
            3.78 * (210 - scaled_width_mm) / 2,
            3.78 * (297 - scaled_height_mm) / 2
        )
        self.dwg.add(tattoo)
        self.dwg.save(pretty=True)
Пример #7
0
def nest(output, files, wbin, hbin, enclosing_rectangle=False):

    packer = newPacker()

    def float2dec(x):
        return _float2dec(x, 4)

    def bbox_paths(paths):
        bbox = None
        for p in paths:
            p_bbox = p.bbox()
            if bbox is None:
                bbox = p_bbox
            else:
                bbox = (min(p_bbox[0], bbox[0]), max(p_bbox[1], bbox[1]),
                        min(p_bbox[2], bbox[2]), max(p_bbox[3], bbox[3]))
        return tuple(float2dec(x) for x in bbox)

    all_paths = {}
    for svg\
            in files:
        paths, attributes = svg2paths(svg)
        bbox = bbox_paths(paths)
        for i in range(files[svg]):
            rid = svg + str(i)
            all_paths[rid] = {'paths': paths, 'bbox': bbox}
            print(rid)
            packer.add_rect(bbox[1] - bbox[0], bbox[3] - bbox[2], rid=rid)

    print('Rectangle packing...')
    while True:
        packer.add_bin(wbin, hbin)
        packer.pack()
        rectangles = {r[5]: r for r in packer.rect_list()}
        if len(rectangles) == len(all_paths):
            break
        else:
            print('not enough space in the bin, adding ')

    combineds = {}

    print('packing into SVGs...')
    for rid, obj in all_paths.items():
        paths = obj['paths']
        bbox = obj['bbox']
        group = Group()

        width, height = (float2dec(bbox[1] - bbox[0]),
                         float2dec(bbox[3] - bbox[2]))
        bin, x, y, w, h, _ = rectangles[rid]
        if bin not in combineds:
            svg_file = output
            if bin != 0:
                splitext = os.path.splitext(svg_file)
                svg_file = splitext[0] + '.%s' % bin + splitext[1]
            dwg = Drawing(svg_file,
                          profile='tiny',
                          size=('%smm' % wbin, '%smm' % hbin),
                          viewBox="0 0 %s %s" % (wbin, hbin))
            combineds[bin] = dwg

        combined = combineds[bin]

        if (width > height and w > h) or \
                (width < height and w < h) or \
                (width == height and w == h):
            rotate = 0
            dx = -bbox[0]
            dy = -bbox[2]
        else:
            rotate = 90
            dx = -bbox[2]
            dy = -bbox[0]

        for p in paths:
            path = Path(d=p.d())
            path.stroke(color='red', width='1')
            path.fill(opacity=0)
            group.add(path)

        group.translate(x + dx, y + dy)
        group.rotate(rotate)
        combined.add(group)

    for combined in combineds.values():
        if enclosing_rectangle:
            r = Rect(size=(wbin, hbin))
            r.fill(opacity=0)
            r.stroke(color='lightgray')
            combined.add(r)

        print('SVG saving...')
        combined.save(pretty=True)
Пример #8
0
    def make_svg(self, data):
        layers = data["layers"]
        _PROPORTION = 10
        _SHIFT_PROP = _PROPORTION / 1.5
        for f in self.forms:
            structures = [None] * len(f.id.split("_"))
            linkers    = []
            centers    = {}
            order      = {}
            maxW, maxH = 0, 0
            for cx, x in enumerate(f.id.split("_")):
                order[x] = cx
            for cl, l in enumerate(layers):
                for cs, s in enumerate(l):
                    name = f.id + "__" + s["id"]
                    if s["type"] == "H":
                        color  = "cornflowerblue" if "ref" not in s else "gainsboro"
                        shape = Circle( center = (s["shift_x"] * _SHIFT_PROP, s["shift_z"] * _SHIFT_PROP),
                                        r = 2.3 * _PROPORTION, id = name,
                                        fill = color, stroke="black",
                                        stroke_width = "2")
                    elif s["type"] == "E":
                        color  = "indianred" if "ref" not in s else "salmon"
                        rotate = f.get_ss_by_id(s["id"]).struc.goes_down()
                        shape = Triangle(center = (s["shift_x"] * _SHIFT_PROP, s["shift_z"] * _SHIFT_PROP),
                                         rc = 2.3 * _PROPORTION, id = name, fill=color,
                                         stroke = "black", stroke_width = "2",
                                         rotate = rotate)
                    else:
                        color  = "darkgreen" if "ref" not in s else "lightgreen"
                        shape = Cross(center = (s["shift_x"] * _SHIFT_PROP, s["shift_z"] * _SHIFT_PROP), r = 2.3 * _PROPORTION,
                                      fill=color, stroke="black", stroke_width = "2",
                                      id = name)
                    structures[order[s["id"]]] = shape
                    centers[s["id"]] = [s["shift_x"] * _SHIFT_PROP, s["shift_z"] * _SHIFT_PROP]
                    if s["shift_x"] * _SHIFT_PROP > maxW: maxW = s["shift_x"] * _SHIFT_PROP
                    if s["shift_z"] * _SHIFT_PROP > maxH: maxH = s["shift_z"] * _SHIFT_PROP

            for cx, x in enumerate(f.id.split("_")):
                if cx == 0 or cx == len(f.id.split("_")) - 1:
                    init = [0, 0]
                    if (ord(x[0]) - 64) <= len(layers) / 2:
                        init[1] = centers[x][1] - (2.3 * _PROPORTION * 2)
                    else:
                        init[1] = centers[x][1] + (2.3 * _PROPORTION * 2)
                    if int(re.search("(\d+)", x).group(1)) <= len(layers[ord(x[0]) - 65]) / 2:
                        init[0] = centers[x][0] - (2.3 * _PROPORTION * 2)
                    else:
                        init[0] = centers[x][0] + (2.3 * _PROPORTION * 2)
                    if cx == 0:
                        shape = Line(init, centers[x], stroke="darkblue", stroke_width = "4")
                    elif cx == len(f.id.split("_")) - 1:
                        shape = Line(centers[x], init, stroke="darkred", stroke_width = "4")
                    linkers.append(shape)
                for cy, y in enumerate(f.id.split("_")):
                    if cy == cx + 1:
                        shape = Line(centers[x], centers[y], stroke="black", stroke_width = "4")
                        linkers.append(shape)

            # Intercalate
            toplink = []
            dowlink = []
            if f.sslist[0].struc.goes_up():
                dowlink = linkers[0:][::2]
                toplink = linkers[1:][::2]
            else:
                dowlink = linkers[1:][::2]
                toplink = linkers[0:][::2]

            g = Group()
            for x in dowlink:
                g.add(x)
            for x in structures:
                g.add(x)
            for x in toplink:
                g.add(x)
            g.translate(2.3 * _PROPORTION * 3, 2.3 * _PROPORTION * 3)
            d = Drawing(size = (maxW + ((2.3 * _PROPORTION * 3) * 2),
                                maxH + ((2.3 * _PROPORTION * 3) * 2)),
                        id = f.id + "__image")
            d.add(g)
            for x in data["forms"]:
                if x["id"] == f.id:
                    x["svg"] = d.tostring()