Пример #1
0
def plot(*auts, filename='plot.svg', diagonal=True, endpoints=False, display_scale=1):
	assert len({aut.signature for aut in auts}) == 1
	from svgwrite.path      import Path
	from svgwrite.shapes    import Line, Polyline
	from svgwrite.container import Group
	dwg, canvas = new_drawing(filename, display_scale)
	include_markers(dwg, endpoints)
	draw_grid(canvas, auts[0].signature)
	
	x_axis = Polyline([(0, 0), (SCALE, 0)], class_="axis")
	y_axis = Polyline([(0, 0), (0, SCALE)], class_="axis")
	canvas.add(x_axis)
	canvas.add(y_axis)
	
	if diagonal:
		diag = Line((0,0), (SCALE, SCALE), class_="grid depth0")
		canvas.add(diag)
	
	for i, aut in enumerate(auts):
		group = Group(class_="graph", id='graph_' + str(i))
		canvas.add(group)
		last = (None, None)
		for (x0, y0, x1, y1) in graph_segments(aut):
			if last != (x0, y0):
				graph = Path(class_='graph_segment')
				group.add(graph)
				graph.push('M', SCALE * x0, SCALE * y0)
			graph.push('L', SCALE * x1, SCALE * y1)
			last = (x1, y1)
		
	dwg.save()
Пример #2
0
def load_death_symbol(drawing):
    # DEATH SYMBOL
    death_symbol = Group()
    death_symbol.add(
        Path(id="death", d="M 10 0 L 10 40 M 0 12 L 20 12", stroke_width="5"))
    drawing.defs.add(death_symbol)
    return death_symbol
Пример #3
0
def get_parallax_lines():
    groups = [Group() for i in range(3)]
    duplicated_groups = [Group() for i in range(3)]
    longest = [0 for i in range(3)]

    current_y = anim['verticalInterval']
    while current_y < anim['height']:
        line_quantity = randint(1, 9)
        lengths = [randint(5, 30) for l in range(line_quantity)]
        position = sample(range(anim['width'] * 2), line_quantity)
        for i, (length, pos) in enumerate(zip(lengths, position)):
            if i % 3 is 0 or i is 0: n = 2
            elif i % 2 is 0: n = 1
            else: n = 0
            if pos + length > longest[n]:
                longest[n] = pos + length
            line = Line((pos, current_y), (pos + length, current_y))
            if pos < anim['height']:
                duplicated_groups[n].add(line)
            groups[n].add(line)
        current_y += randint(1,5) * anim['verticalInterval']

    dur = 2
    containers = [Group(**anim['style']) for i in range(3)]
    for c, g, dg, l in zip(containers, groups, duplicated_groups, longest):
        c.add(g)
        dg['transform'] = 'translate({}, 0)'.format(l)
        c.add(dg)
        c.add(animate(l, dur))
        dur += 0.5

    return containers
Пример #4
0
def draw_numbers(*args):
    numbers = Group()
    for i, num in enumerate(args):
        assert isinstance(i, int)
        num_drawing = number(num)
        num_drawing.translate((35 * i, 0))
        numbers.add(num_drawing)
    return numbers
Пример #5
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()
Пример #6
0
 def get_runner_end(self, line, is_out):
     x, y = self.get_line_end(line)
     if is_out:
         g = Group()
         g['class'] = 'out'
         g.add(Line((x - X_SIZE, y - X_SIZE), (x + X_SIZE, y + X_SIZE)))
         g.add(Line((x - X_SIZE, y + X_SIZE), (x + X_SIZE, y - X_SIZE)))
         return g
     else:
         return Circle((x, y), CIRCLE_R)
Пример #7
0
 def test_simple_defs(self):
     dwg = Drawing()
     g = dwg.defs.add(Group(id='test'))
     inner_g = g.add(Group(id='innerTest'))
     result = dwg.tostring()
     self.assertEqual(result, '<svg baseProfile="full" height="100%" version="1.1" '
                              'width="100%" xmlns="http://www.w3.org/2000/svg" '
                              'xmlns:ev="http://www.w3.org/2001/xml-events" '
                              'xmlns:xlink="http://www.w3.org/1999/xlink">'
                              '<defs><g id="test"><g id="innerTest" /></g></defs></svg>')
Пример #8
0
    def add_y_label(self):
        y_coord = self.margin_top + (self.plottable_y / 2)
        text_group = Group(
            transform=f"rotate(270, {self.font_size}, {y_coord})")

        text_group.add(
            Text(self.y_label,
                 insert=(0, y_coord),
                 fill=self.graph_colour,
                 font_size="15",
                 stroke_width=0))
        self.plot.add(text_group)
Пример #9
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
Пример #10
0
    def _draw_attachment(self):
        """
        Return an SVG group containing a line element and "Attachment" label.
        """
        group = Group(class_='connector')

        # Draw attachment (line)
        start = (OFFSET + self.center, OFFSET + self.cursor)
        height = PADDING * 2 + LINE_HEIGHT + PADDING * 2
        end = (start[0], start[1] + height)
        line = Line(start=start, end=end, class_='attachment')
        group.add(line)
        self.cursor += PADDING * 4

        return group
Пример #11
0
 def draw_atbat(self, atbat, is_home_team_batting):
     atbat_group = Group()
     atbat_group.set_desc(atbat.get_description())
     atbat_group.add(self.get_batter_name_text(atbat))
     atbat_group.add(self.get_scoring_text(atbat))
     self.runner_drawer.execute(self.y, atbat, atbat_group,
                                is_home_team_batting)
     self.dwg.add(atbat_group)
Пример #12
0
 def test_object_link_change_id(self):
     g = Group(id=999)
     self.assertEqual(g['id'], 999)
     use = Use(g)
     # change 'id' after assigning to <Use> object
     g['id'] = 'newid'
     self.assertEqual(use.tostring(), '<use xlink:href="#newid" />')
Пример #13
0
 def test_add_subelement_with_autoid(self):
     marker = Marker(debug=True, profile='full')
     marker.add(Group())
     self.assertTrue(
         re.match(r'^<marker id="id\d+"><g /></marker>$',
                  marker.tostring()),
         "getting an autoid for class Marker failed.")
Пример #14
0
def get_lines():
    group = Group(**img['style'])

    current_y = 6
    current_x = randint(-10 , 150)

    for y in range(0, img['verticalLines']):
        while current_x < img['width']:
            rand_x = randint(2, 6) + current_x
            line = Line((current_x, current_y), (rand_x, current_y))
            group.add(line)
            current_x = rand_x + randint(50, 150)
        current_x = randint(-10, 150)
        current_y = round(current_y + img['verticalInterval'], 1)

    return group
Пример #15
0
    def add_x_column_labels(self,
                            column_positions,
                            column_labels,
                            rotate=None):
        for gene in column_labels:
            text_group = Group(
                transform=
                f"rotate({rotate if rotate else 0},{column_positions[gene]},"
                f"{self.margin_top + self.plottable_y + 17})")

            text_group.add(
                Text(gene,
                     insert=(column_positions[gene],
                             self.margin_top + self.plottable_y + 17),
                     fill=self.graph_colour,
                     font_size=self.font_size,
                     stroke_width=0))
            self.plot.add(text_group)
Пример #16
0
 def get_team_box(self, id, ht):
     box = Group()
     box['id'] = id
     box['class'] = 'team-box'
     box.add(Rect((ORIGIN_X, ORIGIN_Y), (ATBAT_W, ht)))
     box.add(
         Line((ORIGIN_X + NAME_W, ORIGIN_Y),
              (ORIGIN_X + NAME_W, ORIGIN_Y + ht)))
     box.add(
         Line((ORIGIN_X + NAME_W + SCORE_W, ORIGIN_Y),
              (ORIGIN_X + NAME_W + SCORE_W, ORIGIN_Y + ht)))
     return box
Пример #17
0
    def text_to_paths(self, text, path_type, style, translate_x=0):
        glyphs = self.glyphs[path_type]
        glyphs_paths = Group(**style)
        text_len = len(text) - 1

        for i, glyph in enumerate(text):
            if glyph is not ' ':
                glyphs_paths.add(
                    self.get_path(glyphs[glyph], round(translate_x, 2)))
                if glyph is '/' or (i + 1 <= text_len and text[i + 1] is '/'):
                    translate_x += self.glyph_width + self.slash_space
                elif glyph is 'l':
                    translate_x += 1.6 + self.inner_space
                else:
                    translate_x += self.glyph_width + self.inner_space
            else:
                translate_x += self.space

        return glyphs_paths
Пример #18
0
    def _draw_wirelesslink(self, url, labels):
        """
        Draw a line with labels representing a WirelessLink.

        :param url: Hyperlink URL
        :param labels: Iterable of text labels
        """
        group = Group(class_='connector')

        # Draw the wireless link
        start = (OFFSET + self.center, self.cursor)
        height = PADDING * 2 + LINE_HEIGHT * len(labels) + PADDING * 2
        end = (start[0], start[1] + height)
        line = Line(start=start, end=end, class_='wireless-link')
        group.add(line)

        self.cursor += PADDING * 2

        # Add link
        link = Hyperlink(href=f'{self.base_url}{url}', target='_blank')

        # Add text label(s)
        for i, label in enumerate(labels):
            self.cursor += LINE_HEIGHT
            text_coords = (self.center + PADDING * 2,
                           self.cursor - LINE_HEIGHT / 2)
            text = Text(label,
                        insert=text_coords,
                        class_='bold' if not i else [])
            link.add(text)

        group.add(link)
        self.cursor += PADDING * 2

        return group
Пример #19
0
 def group_runner(self, line, line_end, to_score):
     runner_group = Group()
     runner_group.add(line)
     runner_group.add(line_end)
     if to_score:
         runner_group['class'] = 'runner to-score'
     else:
         runner_group['class'] = 'runner'
     return runner_group
Пример #20
0
    def get_svg(self, **kwargs):
        """Returns the svg code of this shape with annotation.

        Args:
            kwargs: The options for the group.

        Returns:
            svgwrite.container.Group: The group of the shape and annotations.

        """
        group = Group(**kwargs)
        group.add(self.shape.get_svg(fill=self.color))
        if len(self.annot_txt) > 0 and self.show_annot:
            group.add(Annotation(self.annot_txt, self.annot_pos, self.shape))
        if self.show_value_txt:
            group.add(Value(self.value, self.shape))
        return group
Пример #21
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)
Пример #22
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()
Пример #23
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)
Пример #24
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
Пример #25
0
    def _draw_cable(self, color, url, labels):
        """
        Return an SVG group containing a line element and text labels representing a Cable.

        :param color: Cable (line) color
        :param url: Hyperlink URL
        :param labels: Iterable of text labels
        """
        group = Group(class_='connector')

        # Draw a "shadow" line to give the cable a border
        start = (OFFSET + self.center, self.cursor)
        height = PADDING * 2 + LINE_HEIGHT * len(labels) + PADDING * 2
        end = (start[0], start[1] + height)
        cable_shadow = Line(start=start, end=end, class_='cable-shadow')
        group.add(cable_shadow)

        # Draw the cable
        cable = Line(start=start, end=end, style=f'stroke: #{color}')
        group.add(cable)

        self.cursor += PADDING * 2

        # Add link
        link = Hyperlink(href=f'{self.base_url}{url}', target='_blank')

        # Add text label(s)
        for i, label in enumerate(labels):
            self.cursor += LINE_HEIGHT
            text_coords = (self.center + PADDING * 2,
                           self.cursor - LINE_HEIGHT / 2)
            text = Text(label,
                        insert=text_coords,
                        class_='bold' if not i else [])
            link.add(text)

        group.add(link)
        self.cursor += PADDING * 2

        return group
Пример #26
0
    def translate(
        self,
        data: DataContainer,
        width: Width,
        height: Height,
        x_key: str = "x",
        y_key: str = "y",
        v_key: str = "value",
        is_1d: bool = False,
        **kwargs: Any,
    ) -> Group:
        """Base translator for SVG Heatmap renderer.

        :param data: point datum array.
            point datum represent by dict consists with x, y positions and value.
        :param width: drawing area width.
        :param height: drawing area height.
        :param x_key: key name of x for points.
        :param y_key: key name of y for points.
        :param v_key: key name of value for points.
        :param is_1d: render rect as full width (One-dimensional heatmap).
        :return: Rect nodes enclosed with Group node.
        """
        return Group()
Пример #27
0
def create_svg_document_with_light(elements,
                                   size,
                                   viewbox=None,
                                   background_color="white",
                                   background_opacity=1.0):
    """Create the full SVG document, with a lighting filter.

    Resources:

    - https://www.w3.org/TR/SVG11/filters.html#LightSourceDefinitions
    - https://svgwrite.readthedocs.io/en/master/classes/filters.html
    - http://www.svgbasics.com/filters2.html
    - https://css-tricks.com/look-svg-light-source-filters/

    :param viewbox: (minx, miny, width, height)
    """
    # TODO work in progress
    # TODO have a look at how threejs is converted to SVG:
    # https://github.com/mrdoob/three.js/blob/master/examples/jsm/renderers/SVGRenderer.js
    dwg = Drawing("ase.svg", profile="full", size=size)

    light_filter = dwg.defs.add(Filter(size=("100%", "100%")))
    diffuse_lighting = light_filter.feDiffuseLighting(size=size,
                                                      surfaceScale=10,
                                                      diffuseConstant=1,
                                                      kernelUnitLength=1,
                                                      color="white")
    diffuse_lighting.fePointLight(source=(size[0], 0, 1000))
    light_filter.feComposite(operator="arithmetic", k1=1)

    root = Group(id="root", filter=light_filter.get_funciri())
    dwg.add(root)
    # if Color(background_color).web != "white":
    # apparently the best way, see: https://stackoverflow.com/a/11293812/5033292
    root.add(
        shapes.Rect(size=size,
                    fill=background_color,
                    fill_opacity=background_opacity))
    for element in elements:
        root.add(element)
    if viewbox:
        dwg.viewbox(*viewbox)
    return dwg
Пример #28
0
def create_svg_document(elements,
                        size,
                        viewbox=None,
                        background_color="white",
                        background_opacity=1.0):
    """Create the full SVG document.

    :param viewbox: (minx, miny, width, height)
    """
    dwg = Drawing("ase.svg", profile="tiny", size=size)
    root = Group(id="root")
    dwg.add(root)
    # if Color(background_color).web != "white":
    # apparently the best way, see: https://stackoverflow.com/a/11293812/5033292
    root.add(
        shapes.Rect(size=size,
                    fill=background_color,
                    fill_opacity=background_opacity))
    for element in elements:
        root.add(element)
    if viewbox:
        dwg.viewbox(*viewbox)
    return dwg
Пример #29
0
    def generate_object(self, specimen_number, doc_type):
        style = self.styles[doc_type]
        width = round(self.width + style['margin'] * 2, 7)
        height = round(self.height + style['margin'] * 2, 7)

        document = self.get_SVG_document(specimen_number, width, height)
        elements = Group()
        elements['transform'] = 'translate({}, {})'.format(
            style['margin'], style['margin'])
        document.add(elements)

        outline = self.get_path(self.ruler_outline,
                                0,
                                style=style['outlineStyle'])
        elements.add(outline)

        text = number_to_string(specimen_number) + self.ruler_total
        text = self.text_to_paths(text, style['numbersPathType'],
                                  style['numbersStyle'])
        text['transform'] = 'translate(12.5, 20.5)'
        elements.add(text)

        return document
Пример #30
0
 def test_constructor(self):
     g = Group()
     self.assertEqual(g.tostring(), "<g />")
Пример #31
0
 def test_object_link_auto_id(self):
     AutoID(999)  # set next id to 999
     g = Group()
     use = Use(g)
     self.assertEqual(use.tostring(), '<use xlink:href="#id999" />')
Пример #32
0
 def test_object_link(self):
     g = Group(id='test')
     use = Use(g)
     self.assertEqual(use.tostring(), '<use xlink:href="#test" />')
Пример #33
0
#!/usr/bin/env python3

from svgwrite import inch, Drawing
from svgwrite.container import Group, Defs

from utmtool.rulers import corner_ruler
from utmtool.utils import write_to_pdf, UseInch, translate_inch
from utmtool.template import tool_template

#-------------------------------------------------------------------------------
# Build UTM Tool
#-------------------------------------------------------------------------------
tool_size = 2.48
utm_tool = Group(id='utm_tool', stroke="black", stroke_width=0.5)

utm_tool.add(tool_template("ВТ", tool_size))

# Large map ruler
scale = 2500
diag_shift = 0.40
r = corner_ruler(scale=scale,
                 length=100,
                 major_interval=10,
                 minor_per_major=10)
translate_inch(r, tool_size - diag_shift, diag_shift)
utm_tool.add(r)

# Small map ruler
scale = 8000
diag_shift = 0.85
r = corner_ruler(scale=scale, length=200, major_interval=50, minor_per_major=5)
    def generate_pcb(self, footprint_name, specs):

        total_pincount     = eval(specs['total_pincount'])
        pad_pitch          = eval(specs['pad_pitch'])
        pad_width          = eval(specs['pad_width'])
        pad_length         = eval(specs['pad_length'])
        lead_to_lead_length= eval(specs['lead_to_lead_length'])
        if specs.has_key('sides'):
		    sides          = eval(specs['sides'])
        else:
			sides          = 2
        if specs.has_key('top_margin'):
			top_margin     = eval(specs['top_margin'])
        else:
			top_margin	   = 1	
        if specs.has_key('left_margin'):
            left_margin    = eval(specs['left_margin'])
        else:
            left_margin    = 1
        if specs.has_key('ic_label'):
			ic_label       = eval(specs['ic_label'])
        else:
		    ic_label       = 'IC'

        footprint_width    = str((2 * left_margin) + (pad_pitch * (total_pincount / sides)))
        footprint_height   = str((2 * top_margin) + (pad_length * 2) + lead_to_lead_length)

        # Create the document        
        svg_document = svgwrite.Drawing(filename = footprint_name + ".svg",size=(footprint_width+'mm', footprint_height+'mm'), 
                                        viewBox=('0 0 ' + str(footprint_width) + ' ' + str(footprint_height)))

        # Create the silkscreen
        silkscreen = Group(id='Silkscreen')
        if sides==2:
			# x
            line_1     = left_margin - pad_width
            line_2     = left_margin + ((total_pincount / sides) * pad_pitch) 
			# y
            line_start = top_margin + (pad_length / 2)
            line_end   = top_margin + lead_to_lead_length + + (pad_length / 2)
            silkscreen.add(svg_document.line(start=(line_1, line_start), end=(line_1,line_end),
                                               stroke_width = pad_width,
                                               stroke = "white",
                                               fill = "rgb(255,255,255)"))
            silkscreen.add(svg_document.line(start=(line_2, line_start), end=(line_2,line_end),
                                               stroke_width = pad_width,
                                               stroke = "white",
                                               fill = "rgb(255,255,255)"))
			
            # silkscreen.add(svg_document.text(ic_label,insert = (30, 30)))
        svg_document.add(silkscreen)

        copper_layer = Group(id='copper1')
        if sides >= 1:
            for s in range(0,sides):

                if s==0:
                    side_start = top_margin
                elif s==1:
                    side_start = top_margin + lead_to_lead_length
            
                for p in range(0,total_pincount / sides):

                    # svg_document.add(svg_document.translate((s, 40)))

                    copper_layer.add(svg_document.rect(insert = (left_margin + (p * pad_pitch), side_start),
                                       size = (pad_width, pad_length),
                                       stroke_width = "0",
                                       # connectorname = '\"' + str(((s+1) * (total_pincount/sides))+p) + '\"',
                                       fill = "#ffbf00"))
        
        svg_document.add(copper_layer)
        
        # Write the file
        svg_document.save()
        
        # Rewrite the file adding in the connectors                   
        import xml.dom.minidom
        xmldoc = xml.dom.minidom.parse(footprint_name + ".svg")
        pretty_xml_as_string = xmldoc.toprettyxml()
        
        doclist = pretty_xml_as_string.split('\n')
        newdoc = ""
        cnum = 1 
        for l in doclist:
            if "#ffbf00" in l:
                print "Found"
                l = l.replace("<rect fill=\"#ffbf00\"","<rect fill=\"#ffbf00\" connector=\"%d\" id=\"connector%dpin\"" % (cnum,cnum))
                cnum += 1
                
            newdoc = newdoc + l + '\n'
            
        f = open(footprint_name + ".svg", 'w')
        f.write(newdoc)
Пример #35
0
 def test_add_subelement(self):
     group = Group(id='group')
     subgroup = Group(id='subgroup')
     group.add(subgroup)
     self.assertEqual(group.tostring(), '<g id="group"><g id="subgroup" /></g>')
Пример #36
0
 def test_add_group(self):
     group = Group(id='group')
     subgroup = group.add(Group(id='subgroup'))
     self.assertEqual(group.tostring(), '<g id="group"><g id="subgroup" /></g>')
Пример #37
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)