Ejemplo n.º 1
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
Ejemplo n.º 2
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>')
Ejemplo n.º 3
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.")
Ejemplo n.º 4
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
Ejemplo n.º 5
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" />')
Ejemplo n.º 6
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
Ejemplo n.º 7
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
Ejemplo n.º 8
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)
Ejemplo n.º 9
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
Ejemplo n.º 10
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
Ejemplo n.º 11
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)
Ejemplo n.º 12
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()
Ejemplo n.º 13
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
Ejemplo n.º 14
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)
Ejemplo n.º 15
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
Ejemplo n.º 16
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
Ejemplo n.º 17
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
Ejemplo n.º 18
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)
Ejemplo n.º 19
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
Ejemplo n.º 20
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
Ejemplo n.º 21
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)
Ejemplo n.º 22
0
def tool_template(name, width_in):
    g = Group(
        stroke="black",
        stroke_width=0.5,
        font_family="Arial, Helvetica",
    )

    # Border
    g.add(Rect(
        (0, 0),
        (width_in * inch, width_in * inch),
        fill="none",
    ))

    # Lanyard punch
    g.add(
        Circle(
            (0.4 * inch, (width_in - 0.4) * inch),
            3.5 * mm,
            fill="none",
        ))

    # plast-karto!
    g.add(
        Text(
            "https://plast-karto.readthedocs.io",
            ((width_in / 2) * inch, (width_in - 0.3) * inch),
            text_anchor="middle",
            font_size=2 * mm,
        ))

    g.add(
        Text(
            name,
            ((0.75) * inch, (width_in - 0.75) * inch),
            text_anchor="middle",
            font_size=4 * mm,
        ))

    g.add(square_rose(width_in))
    return g
Ejemplo n.º 23
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
Ejemplo n.º 24
0
def corner_ruler(scale, length, major_interval, minor_per_major):
    g = Group(stroke="black", stroke_width=0.4)

    ruler_length_mm = (length / scale) * 1000

    # Horizontal Ruler
    g.add(Line((-ruler_length_mm * mm, 0 * mm), ((3) * mm, 0 * mm)))
    r = ruler(scale=scale,
              length=length,
              major_interval=major_interval,
              minor_per_major=minor_per_major,
              reverse=True,
              vertical=False)
    g.add(r)

    # Vertical Ruler
    g.add(Line((0 * mm, -3 * mm), (0 * mm, (ruler_length_mm) * mm)))
    r = ruler(scale=scale,
              length=length,
              major_interval=major_interval,
              minor_per_major=minor_per_major,
              reverse=False,
              vertical=True)
    g.add(r)

    g.add(Circle((0, 0), r=0.5 * mm, fill="white"))

    # Scale label
    g.add(
        Text(
            f"1:{scale}",
            x=[(-ruler_length_mm / 2) * mm],
            y=[-1 * mm],
            text_anchor="middle",
            font_size=2 * mm,
            font_weight="bold",
        ))

    return g
Ejemplo n.º 25
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
Ejemplo n.º 26
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
Ejemplo n.º 27
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()
Ejemplo n.º 28
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)
Ejemplo n.º 29
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" />')
Ejemplo n.º 30
0
 def test_object_link(self):
     g = Group(id='test')
     use = Use(g)
     self.assertEqual(use.tostring(), '<use xlink:href="#test" />')