Beispiel #1
0
    def test_group_with_number_of_rects_translated(self):

        group = Group()

        dx, dy = 5, 10

        xmin, ymin = 1000, 1000
        xmax, ymax = -1000, -1000
        rects = []

        for x, y, w, h in [
            (10, 20, 5, 7),
            (30, 40, 5, 7),
        ]:
            rect = Rectangle(width=str(w), height=str(h), x=str(x), y=str(y))
            rects.append(rect)

            xmin = min(xmin, x)
            xmax = max(xmax, x + w)
            ymin = min(ymin, y)
            ymax = max(ymax, y + h)

            group.add(rect)

        group.transform = Transform(translate=(dx, dy))

        self.assert_bounding_box_is_equal(group, (dx + xmin,
                                                  dx + xmax),
                                          (dy + ymin,
                                           dy + ymax))
Beispiel #2
0
    def test_group_with_regular_rect(self):
        group = Group()
        x, y = 10, 20
        w, h = 7, 20

        rect = Rectangle(width=str(w), height=str(h), x=str(x), y=str(y))

        group.add(rect)

        self.assert_bounding_box_is_equal(group, (x, x + w),
                                          (y, y + h))
 def getNumbers( self, ticks: int, fmtstr: str, intan: float, inrad: float, style: Style ):
   "The numbers at the main-ticks. intan: shift perpendicular to axis, inrad: shift in axis."
   
   group = Group()
   if ticks <= 0:
     return group
   
   step = (self.max-self.min) / ticks
   for i in range(ticks+1):
     val = self.min + i * step
     point = self.transform(val)
     group.add( textAt( point.x-intan*self.sin+inrad*self.cos, point.y+intan*self.cos+inrad*self.sin, ("{0:"+fmtstr+"}").format(val), style) )
   return group
Beispiel #4
0
    def _create_lines(self, triangles):
        'Render triangles as individual SVG lines.'
        # First, find all unique lines.
        lines = set()
        for tri in triangles:
            if len(tri) != 3:
                sys.exit(
                    inkex.utils.errormsg(
                        _('Internal error: Encountered a non-triangle.')))
            for i, j in [(0, 1), (0, 2), (1, 2)]:
                xy1 = tuple(tri[i])
                xy2 = tuple(tri[j])
                if xy1 < xy2:
                    lines.update([(xy1, xy2)])
                else:
                    lines.update([(xy2, xy1)])

        # Then, create SVG line elements.
        styles = self._create_styles(len(lines))
        group = self.svg.get_current_layer().add(Group())
        for ([(x1, y1), (x2, y2)], style) in zip(lines, styles):
            line = Line()
            line.set('x1', x1)
            line.set('y1', y1)
            line.set('x2', x2)
            line.set('y2', y2)
            line.style = style
            group.add(line)
Beispiel #5
0
        def generateSecureCircles():
            def generateSecureCircle(row, column):
                isSecureBox = getIsSecureBox(row, column)
                if (isSecureBox):
                    isHomeBox = getIsHomeBox(row, column)
                    fillSecure = getFillColor(isHomeBox,
                                              self.secureNotHomeBoxFillColor)
                    xBox = initialX + column * xBoxSize
                    yBox = initialY - (row + 1) * yBoxSize
                    centerX = xBox + xBoxSize / 2
                    centerY = yBox + yBoxSize / 2
                    radius = yBoxSize * .5 / 2
                    name = 'secure-circle-{}-{}'.format(nSector + 1, column)

                    circle = self.generateCircle(centerX, centerY, radius,
                                                 strokeWidth, stroke,
                                                 fillSecure, name)
                    secureCircles.add(circle)

            secureCircles = Group.new('secure-circles-{}'.format(nSector + 1))

            row = 4
            for column in range(0, nColumns):
                generateSecureCircle(row, column)

            row = 0
            column = nColumns - 2
            generateSecureCircle(row, column)

            return secureCircles
Beispiel #6
0
    def generate(self):
        if numpy is None:
            raise inkex.AbortExtension("numpy is required.")
        so = self.options

        obj = WavefrontObj(self.get_filename())

        scale = self.svg.unittouu('1px')  # convert to document units
        st = Style(so)  # initialise style

        # we will put all the rotations in the object name, so it can be repeated in
        poly = Group.new(obj.name + ':' + make_rotation_log(so))
        (pos_x, pos_y) = self.svg.namedview.center
        poly.transform.add_translate(pos_x, pos_y)
        poly.transform.add_scale(scale)

        # TRANSFORMATION OF THE OBJECT (ROTATION, SCALE, ETC)
        trans_mat = numpy.identity(3, float)  # init. trans matrix as identity matrix
        for i in range(1, 7):  # for each rotation
            axis = getattr(so, 'r{}_ax'.format(i))
            angle = getattr(so, 'r{}_ang'.format(i)) * pi / 180
            trans_mat = rotate(trans_mat, angle, axis)
        # scale by linear factor (do this only after the transforms to reduce round-off)
        trans_mat = trans_mat * so.scl

        # the points as projected in the z-axis onto the viewplane
        transformed_pts = obj.get_transformed_pts(trans_mat)
        so.show(obj, st, poly, transformed_pts)
        return poly
Beispiel #7
0
    def effect(self):
        """Performs the effect."""
        # Determine common properties.
        width = self.options.width
        style = inkex.Style({'stroke-width': width})
        style.set_color(self.options.fill_color, 'fill')
        style.set_color(self.options.stroke_color, 'stroke')
        layer = self.svg.get_current_layer()

        for node in self.svg.selected.values():
            box = node.bounding_box()
            if self.options.position == 'outside':
                box = size_box(box, (width / 2))
            else:
                box = size_box(box, -(width / 2))

            frame = self.add_frame("Frame", box, style,
                                   self.options.corner_radius)
            if self.options.clip:
                self.add_clip(node, frame)
            if self.options.group:
                group = layer.add(Group())
                group.append(node)
                group.append(frame)
            else:
                layer.append(frame)
        return None
Beispiel #8
0
 def generateVerticalLines():
     nSectorPlusOne = nSector + 1
     lines = Group.new('vlines-{}'.format(nSectorPlusOne))
     for column in range(1, nColumns):
         x = initialX + xBoxSize * (column)
         name = 'vline-{}-{}'.format(nSectorPlusOne, column)
         line = self.generateLine(x, initialY, x, 0, strokeWidth,
                                  stroke, name)
         lines.add(line)
     return lines
Beispiel #9
0
 def generateHorizontalLines():
     nSectorPlusOne = nSector + 1
     lines = Group.new('hlines-{}'.format(nSectorPlusOne))
     for row in range(1, nBoxesPerColumn):
         y = initialY - yBoxSize * (row)
         name = 'hline-{}-{}'.format(nSectorPlusOne, row)
         line = self.generateLine(initialX, y, -initialX, y,
                                  strokeWidth, stroke, name)
         lines.append(line)
     return lines
Beispiel #10
0
    def prepareSelectionList(self):
        # first selected->pattern, all but first selected-> skeletons
        pattern_node = self.svg.selected.pop()

        self.gNode = Group()
        pattern_node.getparent().append(self.gNode)

        if self.options.copymode == "copy":
            self.patternNode = pattern_node.duplicate()
        elif self.options.copymode == "clone":
            # TODO: allow 4th option: duplicate the first copy and clone the next ones.
            self.patternNode = self.gNode.add(Use())
            self.patternNode.href = pattern_node
        else:
            self.patternNode = pattern_node

        self.skeletons = self.svg.selected
        self.expand_clones(self.skeletons, True, False)
        self.objects_to_paths(self.skeletons, False)
Beispiel #11
0
 def _create_polygons(self, triangles):
     'Render triangles as SVG polygons.'
     styles = self._create_styles(len(triangles))
     group = self.svg.get_current_layer().add(Group())
     for tri, style in zip(triangles, styles):
         tri_str = ' '.join(['%.10g %.10g' % (pt[0], pt[1]) for pt in tri])
         poly = Polygon()
         poly.set('points', tri_str)
         poly.style = style
         group.add(poly)
Beispiel #12
0
    def effect(self):
        if len(self.svg.selected) != 2:
            errormsg(
                _("Please select exact two objects:\n1. object representing path,\n2. object representing dots."
                  ))
            return

        (iddot, dot) = self.svg.selected.popitem()
        (idpath, path) = self.svg.selected.popitem()

        bb = dot.bounding_box()
        parent = path.find('..')
        group = Group()
        parent.add(group)
        for point in path.path.end_points:
            clone = Use()
            clone.set('xlink:href', '#' + iddot)
            clone.set('x', point.x - bb.center.x)
            clone.set('y', point.y - bb.center.y)
            group.add(clone)
 def getTicks( self, ticks: int, linevon: float, linebis: float, style: Style):
   "The main ticks, linevon and linebis are the start- and end-point perpendicular to the axis in svg-coordinates."
   
   group = Group()
   if ticks <= 0:
     return group
   
   step = (self.max-self.min) / ticks
   for i in range(ticks+1):
     val = self.min + i * step
     point = self.transform(val)
     line = Line(
       x1=str(point.x-linevon*self.sin),
       y1=str(point.y+linevon*self.cos),
       x2=str(point.x-linebis*self.sin),
       y2=str(point.y+linebis*self.cos)
     )
     line.style = style
     group.add(line)
   return group
Beispiel #14
0
    def test_group_nested_transform(self):
        group = Group()

        x, y = 10, 20
        w, h = 7, 20

        scale = 2

        rect = Rectangle(width=str(w), height=str(h), x=str(x), y=str(y))

        rect.transform = Transform(rotate=45, scale=scale)

        group.add(rect)

        group.transform = Transform(rotate=-45)  # rotation is compensated, but scale is not

        a = rect.composed_transform()
        self.assert_bounding_box_is_equal(group, (scale * x,
                                                  scale * (x + w)),
                                          (scale * y,
                                           scale * (y + h)))
    def effect(self):
        if len(self.svg.selected) != 2:
            errormsg(
                _("Please select exact two objects:\n1. object representing path,\n2. object representing dots."
                  ))
            return

        (iddot, dot) = self.svg.selected.popitem()
        (idpath, path) = self.svg.selected.popitem()

        bb = dot.bounding_box()
        parent = path.find('..')
        group = Group()
        parent.add(group)

        end_points = list(path.path.end_points)
        control_points = []
        for cp in path.path.control_points:
            is_endpoint = False
            for ep in end_points:
                if cp.x == ep.x and cp.y == ep.y:
                    is_endpoint = True
                    break
            if not is_endpoint:
                control_points.append(cp)

        pointlist = []
        if self.options.endpoints:
            pointlist += end_points
        if self.options.controlpoints:
            pointlist += control_points

        for point in pointlist:
            clone = Use()
            clone.set('xlink:href', '#' + iddot)
            clone.set('x', point.x - bb.center.x)
            clone.set('y', point.y - bb.center.y)
            group.add(clone)
Beispiel #16
0
    def generate(self):
        self.parse_arguments

        units = self.options.units
        boardSize = self.svg.unittouu(str(self.options.boardSize) + units)
        boardMargin = self.svg.unittouu(str(self.options.boardMargin) + units)

        self.useLaser = self.options.useLaser
        self.nPlayers = self.options.nPlayers
        nBoxesPerColumn = self.options.nBoxesPerColumn
        nColumns = self.options.nColumns
        self.generateCenter = self.options.generateCenter
        self.generateNumbers = self.options.generateNumbers
        self.useImages = self.options.useImages

        fill = (self.getColorString(self.options.fillColor),
                'none')[self.useLaser]
        # inkex.utils.debug(fill)

        strokeWidth = self.options.strokeWidth

        sectorStroke = ('black', 'red')[self.useLaser]
        boardStroke = ('gray', 'black')[self.useLaser]
        homeSafeStroke = (sectorStroke, 'yellow')[self.useImages
                                                  and self.useLaser]

        self.sectorColors = [
            'yellow', 'royalblue', 'red', 'green', 'orange', 'hotpink', 'gold',
            'darkkhaki'
        ]

        self.regularBoxFillColor = ('white', 'none')[self.useLaser]
        self.secureNotHomeBoxFillColor = 'gray'

        # Generate Board
        board = Group.new('board')

        # Generate Border
        border = self.generateRectangle(0, 0, boardSize, boardSize,
                                        strokeWidth, boardStroke, fill,
                                        'border')
        board.add(border)

        # Generate Sectors
        sectors = self.generateSectors(nBoxesPerColumn, nColumns, boardSize,
                                       boardMargin, strokeWidth, sectorStroke,
                                       homeSafeStroke)
        board.add(sectors)

        return board
Beispiel #17
0
    def test_group_with_number_of_rects(self):

        group = Group()

        xmin, ymin = 1000, 1000
        xmax, ymax = -1000, -1000

        rects = []

        for x, y, w, h in [
            (10, 20, 5, 7),
            (30, 40, 5, 7),
        ]:
            rect = Rectangle(width=str(w), height=str(h), x=str(x), y=str(y))
            rects.append(rect)

            xmin = min(xmin, x)
            xmax = max(xmax, x + w)
            ymin = min(ymin, y)
            ymax = max(ymax, y + h)

            group.append(rect)

        self.assert_bounding_box_is_equal(group, (xmin, xmax), (ymin, ymax))
Beispiel #18
0
    def load(self, stream):
        """Load the steam as if it were an open DHW file"""
        header = list(struct.unpack('<32sBHHBxx', stream.read(40)))
        doc = header.pop(0).decode()
        if doc != 'ACECAD_DIGIMEMO_HANDWRITING_____':
            raise AbortExtension('Could not load file, not a ACECAD DHW file!')

        height = int(header[2])
        doc = self.get_template(**dict(zip(('v', 'w', 'h', 'p'), header)))
        svg = doc.getroot()

        timestamp = 0
        layer = svg.getElementById('layer1')

        while True:
            tag = stream.read(1)
            if tag == b'':
                break

            if ord(tag) <= 128:
                errormsg('Unsupported tag: {}\n'.format(tag))
                continue

            if tag == b'\x90':
                # New Layer element
                timestamp = 0
                name = 'layer{:d}'.format(ord(stream.read(1)) + 1)
                layer = svg.add(Group(inkscape_groupmode="layer", id=name))
            elif tag == b'\x88':
                # Read the timestamp next
                timestamp += ord(stream.read(1)) * 20
            else:
                # Pen down
                coords = [
                    p for p in iter(lambda: read_point(stream, height), None)
                ]
                # Pen up
                coords.append(read_point(stream, height))

                poly = layer.add(Polyline())
                poly.path = coords
                poly.set('dm:timestamp', timestamp)

        return doc
    def render_svg(self, grp, drawtype):
        """Render to svg"""
        drawer = getattr(self, f"render_{drawtype}", self.render_obsolete)
        if drawer is None:
            raise Exception("Unknown draw type: " + drawtype)

        canvas_width = (self.draw.col_count() + 2 * self.margin) * self.boxsize
        canvas_height = (self.draw.row_count() +
                         2 * self.margin) * self.boxsize

        # white background providing margin:
        rect = grp.add(Rectangle.new(0, 0, canvas_width, canvas_height))
        rect.style['stroke'] = 'none'
        rect.style['fill'] = "black" if self.invert_code else "white"

        qrg = grp.add(Group())
        qrg.style['stroke'] = 'none'
        qrg.style['fill'] = "white" if self.invert_code else "black"
        qrg.add(drawer())
Beispiel #20
0
 def get_slicer_layer(self, force_creation=False):
     # Test if webslicer-layer layer existis
     layer = self.svg.getElement(
         '//*[@id="webslicer-layer" and @inkscape:groupmode="layer"]')
     if layer is None:
         if force_creation:
             # Create a new layer
             layer = Group(id='webslicer-layer')
             layer.set('inkscape:label', 'Web Slicer')
             layer.set('inkscape:groupmode', 'layer')
             self.document.getroot().append(layer)
         else:
             layer = None
     return layer
Beispiel #21
0
    def generateSectors(self, nBoxesPerColumn, nColumns, boardSize,
                        boardMargin, strokeWidth, stroke, homeSafeStroke):
        sectors = Group.new('sectors')
        for nSector in range(self.nPlayers):
            sector = self.generateSector(nSector, nBoxesPerColumn, nColumns,
                                         boardSize, strokeWidth, stroke,
                                         homeSafeStroke)
            sectors.add(sector)

        ((x1, x2), (y1, y2)) = sectors.bounding_box()
        sizeX = x2 - x1
        sizeY = y2 - y1

        sizeMinusMargin = boardSize - 2 * boardMargin
        scaleX = sizeMinusMargin / sizeX
        scaleY = sizeMinusMargin / sizeY
        sectors.transform.add_scale(scaleX, scaleY)

        translateX = -x1 + boardMargin / scaleX
        translateY = -y1 + boardMargin / scaleY
        sectors.transform.add_translate(translateX, translateY)

        return sectors
    def generate(self):

        scale = self.svg.unittouu('1px')  # convert to document units
        opt = self.options

        if not opt.text:
            raise inkex.AbortExtension('Please enter an input text')
        elif opt.drawtype == "symbol" and opt.symbolid == "":
            raise inkex.AbortExtension('Please enter symbol id')

        # for Python 3 ugly hack to represent bytes as str for Python2 compatibility
        text_bytes = bytes(opt.text, opt.encoding).decode("latin_1")
        text_str = str(opt.text)

        grp = Group()
        grp.set('inkscape:label', 'QR Code: ' + text_str)
        if opt.groupid:
            grp.set('id', opt.groupid)
        pos_x, pos_y = self.svg.namedview.center
        grp.transform.add_translate(pos_x, pos_y)
        if scale:
            grp.transform.add_scale(scale)

        # GENERATE THE QRCODE
        if opt.typenumber == 0:
            # Automatic QR code size`
            code = QRCode.getMinimumQRCode(text_bytes, opt.correctionlevel)
        else:
            # Manual QR code size
            code = QRCode(correction=opt.correctionlevel)
            code.setTypeNumber(int(opt.typenumber))
            code.addData(text_bytes)
            code.make()

        self.boxsize = opt.modulesize
        self.invert_code = opt.invert
        self.margin = 4
        self.draw = GridDrawer(opt.invert, opt.smoothval)
        self.draw.set_grid(code.modules)
        self.render_svg(grp, opt.drawtype)
        return grp
Beispiel #23
0
    def generate(self):
        """Generate the actual svg from the coding"""
        string = self.encode(self.text)

        if string == 'ERROR':
            return

        name = self.get_id('barcode')

        # use an svg group element to contain the barcode
        barcode = Group()
        barcode.set('id', name)
        barcode.set('style', 'fill: black;')

        barcode.transform.add_translate(self.pos_x, self.pos_y)
        if self.scale:
            barcode.transform.add_scale(self.scale)

        bar_id = 1
        bar_offset = 0
        tops = set()

        for datum in self.graphical_array(string):
            # Datum 0 tells us what style of bar is to come next
            style = self.get_style(int(datum[0]))
            # Datum 1 tells us what width in units,
            # style tells us how wide a unit is
            width = int(datum[1]) * int(style['width'])

            if style['write']:
                tops.add(style['top'])
                rect = Rectangle()
                rect.set('x', str(bar_offset))
                rect.set('y', str(style['top']))
                if self.pos_text == TEXT_POS_TOP:
                    rect.set('y', str(style['top'] + self.font_size))
                rect.set('id', "{}_bar{:d}".format(name, bar_id))
                rect.set('width', str(width))
                rect.set('height', str(style['height']))
                barcode.append(rect)
            bar_offset += width
            bar_id += 1

        for extra in self._extra:
            if extra is not None:
                barcode.append(extra)

        bar_width = bar_offset
        # Add text at the bottom of the barcode
        text = TextElement()
        text.set('x', str(int(bar_width / 2)))
        text.set('y', str(min(tops) + self.font_size - 1))
        if self.pos_text == TEXT_POS_BOTTOM:
            text.set('y', str(self.height + max(tops) + self.font_size))
        text.set('style', TEXT_TEMPLATE % self.font_size)
        text.set('xml:space', 'preserve')
        text.set('id', '{}_text'.format(name))
        text.text = str(self.text)
        barcode.append(text)
        return barcode
Beispiel #24
0
 def test_empty_group_with_translation(self):
     group = Group()
     group.transform = Transform(translate=(10, 15))
     self.assert_bounding_box_is_equal(group, None, None)
Beispiel #25
0
 def test_empty_group(self):
     group = Group()
     self.assert_bounding_box_is_equal(group, None, None)
Beispiel #26
0
def split_fill_and_stroke(path_node):
    """Split a path into two paths, one filled and one stroked

    Returns a the list [fill, stroke], where each is the XML element of the
    fill or stroke, or None.
    """
    style = dict(inkex.Style.parse_str(path_node.get("style", "")))

    # If there is only stroke or only fill, don't split anything
    if "fill" in style and style["fill"] == "none":
        if "stroke" not in style or style["stroke"] == "none":
            return [None, None]  # Path has neither stroke nor fill
        else:
            return [None, path_node]
    if "stroke" not in style.keys() or style["stroke"] == "none":
        return [path_node, None]


    group = Group()
    fill = group.add(PathElement())
    stroke = group.add(PathElement())

    d = path_node.pop('d')
    if d is None:
        raise AssertionError("Cannot split stroke and fill of non-path element")

    nodetypes = path_node.pop('sodipodi:nodetypes', None)
    path_id = path_node.pop('id', str(id(path_node)))
    transform = path_node.pop('transform', None)
    path_node.pop('style')

    # Pass along all remaining attributes to the group
    for attrib_name, attrib_value in path_node.attrib.items():
        group.set(attrib_name, attrib_value)

    group.set("id", path_id)

    # Next split apart the style attribute
    style_group = {}
    style_fill = {"stroke": "none", "fill": "#000000"}
    style_stroke = {"fill": "none", "stroke": "none"}

    for key in style.keys():
        if key.startswith("fill"):
            style_fill[key] = style[key]
        elif key.startswith("stroke"):
            style_stroke[key] = style[key]
        elif key.startswith("marker"):
            style_stroke[key] = style[key]
        elif key.startswith("filter"):
            style_group[key] = style[key]
        else:
            style_fill[key] = style[key]
            style_stroke[key] = style[key]

    if len(style_group) != 0:
        group.set("style", str(inkex.Style(style_group)))

    fill.set("style", str(inkex.Style(style_fill)))
    stroke.set("style", str(inkex.Style(style_stroke)))

    # Finalize the two paths
    fill.set("d", d)
    stroke.set("d", d)
    if nodetypes is not None:
        fill.set('sodipodi:nodetypes', nodetypes)
        stroke.set('sodipodi:nodetypes', nodetypes)
    fill.set("id", path_id + "-fill")
    stroke.set("id", path_id + "-stroke")
    if transform is not None:
        fill.set("transform", transform)
        stroke.set("transform", transform)

    # Replace the original node with the group
    path_node.getparent().replace(path_node, group)

    return [fill, stroke]
Beispiel #27
0
 def test_bounding_box(self):
     """A group returns a bounding box"""
     empty = self.svg.add(Group(Group()))
     self.assertEqual(empty.bounding_box(), None)
     self.assertEqual(int(self.svg.getElementById('A').bounding_box().width), 783)
     self.assertEqual(int(self.svg.getElementById('B').bounding_box().height), 114)
Beispiel #28
0
 def test_new_group(self):
     """Test creating groups"""
     svg = Layer.new('layerA', Group.new('groupA', Rectangle()))
     self.assertElement(svg,\
         b'<g inkscape:groupmode="layer" inkscape:label="layerA">'\
         b'<g inkscape:label="groupA"><rect/></g></g>')
Beispiel #29
0
    def effect(self):
        self.is_installed()

        for name in list(self.options.__dict__):
            if '_' in name:
                self.set_options(self.options, name,
                                 self.options.__dict__.pop(name))

        # Remove old master slide property
        for node in self.svg.xpath(
                "//svg:g[@jessyink:customKeyBindings='customKeyBindings']"):
            node.delete()

        # Set custom key bindings.
        node_text = """function getCustomKeyBindingsSub()
{
    var keyDict = new Object();
    keyDict[SLIDE_MODE] = new Object();
    keyDict[INDEX_MODE] = new Object();
    keyDict[DRAWING_MODE] = new Object();
"""

        for key, value in self.options.slideKeyCodes.items():
            node_text += f"    keyDict[SLIDE_MODE][{key}] = function() {{ {value} }};\n"

        for key, value in self.options.drawingKeyCodes.items():
            node_text += f"    keyDict[DRAWING_MODE][{key}] = function() {{ {value} }};\n"

        for key, value in self.options.indexKeyCodes.items():
            node_text += f"    keyDict[INDEX_MODE][{key}] = function() {{ {value} }};\n"

        # Set custom char bindings.
        node_text += """    return keyDict;
}

function getCustomCharBindingsSub()
{
    var charDict = new Object();
    charDict[SLIDE_MODE] = new Object();
    charDict[INDEX_MODE] = new Object();
    charDict[DRAWING_MODE] = new Object();
"""

        for key, value in self.options.slideCharCodes.items():
            node_text += f'    charDict[SLIDE_MODE]["{key}"] = function() {{ {value} }};\n'

        for key, value in self.options.drawingCharCodes.items():
            node_text += f'    charDict[DRAWING_MODE]["{key}"] = function() {{ {value} }};\n'

        for key, value in self.options.indexCharCodes.items():
            node_text += f'    charDict[INDEX_MODE]["{key}"] = function() {{ {value} }};\n'

        node_text += "    return charDict;" + "\n"
        node_text += "}" + "\n"

        # Create new script node
        group = self.svg.add(Group())
        script = group.add(Script())
        script.text = node_text
        group.set("jessyink:customKeyBindings", "customKeyBindings")
        group.set("onload", "this.getCustomCharBindings = function() { "\
            "return getCustomCharBindingsSub(); }; "\
            "this.getCustomKeyBindings = function() { return getCustomKeyBindingsSub(); };")
Beispiel #30
0
    def effect(self):
        # Check that elements have been selected
        if not self.svg.selected:
            inkex.errormsg(_("Please select objects!"))
            return

        linestyle = {
            'stroke': '#000000',
            'stroke-width': str(self.svg.unittouu('1px')),
            'fill': 'none',
            'stroke-linecap': 'round',
            'stroke-linejoin': 'round'
        }

        facestyle = {
            'stroke': '#000000',
            'stroke-width': str(self.svg.unittouu('1px')),
            'fill': 'none',
            'stroke-linecap': 'round',
            'stroke-linejoin': 'round'
        }

        parent_group = self.svg.selection.first().getparent()
        trans = parent_group.composed_transform()

        invtrans = None
        if trans:
            invtrans = -trans

        # Recovery of the selected objects
        pts = []
        nodes = []
        seeds = []
        fills = []

        for node in self.svg.selected.values():
            nodes.append(node)
            bbox = node.bounding_box()
            if bbox:
                center_x, center_y = bbox.center
                point = [center_x, center_y]
                if trans:
                    point = trans.apply_to_point(point)
                pts.append(Point(*point))
                if self.options.delaunayFillOptions != "delaunay-no-fill":
                    fills.append(node.style.get('fill', 'none'))
                seeds.append(Point(center_x, center_y))

        # Creation of groups to store the result
        if self.options.diagramType != 'Delaunay':
            # Voronoi
            group_voronoi = parent_group.add(Group())
            group_voronoi.set('inkscape:label', 'Voronoi')
            if invtrans:
                group_voronoi.transform *= invtrans
        if self.options.diagramType != 'Voronoi':
            # Delaunay
            group_delaunay = parent_group.add(Group())
            group_delaunay.set('inkscape:label', 'Delaunay')

        # Clipping box handling
        if self.options.diagramType != 'Delaunay':
            # Clipping bounding box creation
            group_bbox = sum([node.bounding_box() for node in nodes], None)

            # Clipbox is the box to which the Voronoi diagram is restricted
            if self.options.clip_box == 'Page':
                svg = self.document.getroot()
                width = self.svg.unittouu(svg.get('width'))
                height = self.svg.unittouu(svg.get('height'))
                clip_box = (0, width, 0, height)
            else:
                clip_box = (group_bbox.left,
                            group_bbox.right,
                            group_bbox.top,
                            group_bbox.bottom)

            # Safebox adds points so that no Voronoi edge in clip_box is infinite
            safe_box = (2 * clip_box[0] - clip_box[1],
                        2 * clip_box[1] - clip_box[0],
                        2 * clip_box[2] - clip_box[3],
                        2 * clip_box[3] - clip_box[2])
            pts.append(Point(safe_box[0], safe_box[2]))
            pts.append(Point(safe_box[1], safe_box[2]))
            pts.append(Point(safe_box[1], safe_box[3]))
            pts.append(Point(safe_box[0], safe_box[3]))

            if self.options.showClipBox:
                # Add the clip box to the drawing
                rect = group_voronoi.add(Rectangle())
                rect.set('x', str(clip_box[0]))
                rect.set('y', str(clip_box[2]))
                rect.set('width', str(clip_box[1] - clip_box[0]))
                rect.set('height', str(clip_box[3] - clip_box[2]))
                rect.style = linestyle

        # Voronoi diagram generation
        if self.options.diagramType != 'Delaunay':
            vertices, lines, edges = voronoi.computeVoronoiDiagram(pts)
            for edge in edges:
                vindex1, vindex2 = edge[1:]
                if (vindex1 < 0) or (vindex2 < 0):
                    continue  # infinite lines have no need to be handled in the clipped box
                else:
                    segment = self.clip_edge(vertices, lines, edge, clip_box)
                    # segment = [vertices[vindex1],vertices[vindex2]] # deactivate clipping
                    if len(segment) > 1:
                        x1, y1 = segment[0]
                        x2, y2 = segment[1]
                        cmds = [['M', [x1, y1]], ['L', [x2, y2]]]
                        path = group_voronoi.add(PathElement())
                        path.set('d', str(inkex.Path(cmds)))
                        path.style = linestyle

        if self.options.diagramType != 'Voronoi':
            triangles = voronoi.computeDelaunayTriangulation(seeds)
            i = 0
            if self.options.delaunayFillOptions == "delaunay-fill":
                random.seed("inkscape")
            for triangle in triangles:
                pt1 = seeds[triangle[0]]
                pt2 = seeds[triangle[1]]
                pt3 = seeds[triangle[2]]
                cmds = [['M', [pt1.x, pt1.y]],
                        ['L', [pt2.x, pt2.y]],
                        ['L', [pt3.x, pt3.y]],
                        ['Z', []]]
                if self.options.delaunayFillOptions == "delaunay-fill" \
                    or self.options.delaunayFillOptions == "delaunay-fill-random":
                    facestyle = {
                        'stroke': fills[triangle[random.randrange(0, 2)]],
                        'stroke-width': str(self.svg.unittouu('0.005px')),
                        'fill': fills[triangle[random.randrange(0, 2)]],
                        'stroke-linecap': 'round',
                        'stroke-linejoin': 'round'
                    }
                path = group_delaunay.add(PathElement())
                path.set('d', str(inkex.Path(cmds)))
                path.style = facestyle
                i += 1