def load(self, node, trans):
        a = node.get('style').split(";")
        d = dict(s.split(':') for s in a)
        if d['stroke'] == "#ff0000":
            self.cut_style = 2
        elif d['stroke'] == "#0000ff":
            self.cut_style = 3
        else:
            pass

        d = node.get('d')
        p = Path(d)
        if len(p) == 0:
            return
        p = CubicSuperPath(p)
        p = p.transform(trans)

        # p is now a list of lists of cubic beziers [ctrl p1, ctrl p2, endpoint]
        # where the start-point is the last point in the previous segment
        self.segments = []
        for sp in p:
            points = []
            sub_divide_cubic_path(sp, 0.2)  # TODO: smoothness preference
            for csp in sp:
                points.append((csp[1][0], csp[1][1]))
            self.segments.append(points)
Esempio n. 2
0
    def test_path_TepidQuadratic(self):
        path = Path("M 10 5 Q 15 30 25 15 T 50 40")
        pe = PathElement()
        pe.path = path
        ibb = (10, 50), (5, 40)

        self.assert_bounding_box_is_equal(pe, *ibb)
Esempio n. 3
0
def get_points(el):
    if el.typename == 'Line':
        pts = [Vector2d(el.get('x1'),el.get('y1')),\
               Vector2d(el.get('x2'),el.get('y2'))]
    elif el.typename == 'PathElement':
        pth = Path(el.get_path())
        pts = list(pth.control_points)
    elif el.typename == 'Rectangle':
        x = float(el.get('x'))
        y = float(el.get('y'))
        w = float(el.get('width'))
        h = float(el.get('height'))
        pts = [
            Vector2d(x, y),
            Vector2d(x + w, y),
            Vector2d(x + w, y + h),
            Vector2d(x, y + h),
            Vector2d(x, y)
        ]

    ct = el.composed_transform()
    xs = []
    ys = []
    for p in pts:
        p = ct.apply_to_point(p)
        xs.append(p.x)
        ys.append(p.y)
    return xs, ys
Esempio n. 4
0
    def scaleCubicSuper(self, cspath, scaleFactor, scaleFrom):
        bbox = Path(cspath).bounding_box()

        if (scaleFrom == 'topLeft'):
            oldOrigin = [bbox.left, bbox.bottom]
        elif (scaleFrom == 'topRight'):
            oldOrigin = [bbox.right, bbox.bottom]
        elif (scaleFrom == 'bottomLeft'):
            oldOrigin = [bbox.left, bbox.top]
        elif (scaleFrom == 'bottomRight'):
            oldOrigin = [bbox.right, bbox.top]
        else:  #if(scaleFrom == 'center'):
            oldOrigin = [
                bbox.left + (bbox.right - bbox.left) / 2.,
                bbox.bottom + (bbox.top - bbox.bottom) / 2.
            ]

        newOrigin = [oldOrigin[0] * scaleFactor, oldOrigin[1] * scaleFactor]

        for subpath in cspath:
            for bezierPt in subpath:
                for i in range(0, len(bezierPt)):

                    bezierPt[i] = [
                        bezierPt[i][0] * scaleFactor,
                        bezierPt[i][1] * scaleFactor
                    ]

                    bezierPt[i][0] += (oldOrigin[0] - newOrigin[0])
                    bezierPt[i][1] += (oldOrigin[1] - newOrigin[1])
Esempio n. 5
0
    def test_path_combined_1(self):
        path = Path("M 0 0 C 11 14 33 3 85 98 H 84 V 91 L 13 78 C 26 83 65 24 94 77")
        # path = Path("M 0 0 C 11 14 33 3 85 98")
        pe = PathElement()
        pe.path = path
        ibb = self.get_inkscape_bounding_box(pe)

        self.assert_bounding_box_is_equal(pe, *ibb, disable_inkscape_check=True)
 def load(self, node, trans):
     new_path = self.new_path_from_node(node)
     x1 = float(node.get('x1'))
     y1 = float(node.get('y1'))
     x2 = float(node.get('x2'))
     y2 = float(node.get('y2'))
     a = [['M', [x1, y1]], ['L', [x2, y2]]]
     new_path.set('d', str(Path(a)))
     SvgPath.load(self, new_path, trans)
    def load(self, node, trans):
        new_path = self.new_path_from_node(node)
        x = float(node.get('x'))
        y = float(node.get('y'))
        w = float(node.get('width'))
        h = float(node.get('height'))
        a = [['M', [x, y]], ['l', [w, 0]], ['l', [0, h]], ['l', [-w, 0]], ['Z', []]]

        new_path.set('d', str(Path(a)))
        SvgPath.load(self, new_path, trans)
Esempio n. 8
0
    def path(self):
        # A polyline is a series of connected line segments described by their
        # points.  In order to make use of the existing logic for incorporating
        # svg transforms that is in our superclass, we'll convert the polyline
        # to a degenerate cubic superpath in which the bezier handles are on
        # the segment endpoints.
        path = self.node.get_path()
        path = Path(path).to_superpath()

        return path
Esempio n. 9
0
    def effect(self):
        starttime = time.time()
        sel = self.svg.selection
        # an ElementList
        # inkex.utils.debug(sel)
        els = [sel[k] for k in sel.id_dict().keys()]

        poptext = self.options.poptext
        poprest = self.options.poprest
        removerectw = self.options.removerectw
        removerectb = self.options.removerectb

        gpe = sel.get()
        els = [gpe[k] for k in gpe.id_dict().keys()]
        gs = [el for el in els if el.typename == 'Group']
        os = [el for el in els if not (el.typename == 'Group')]

        # inkex.utils.debug(self.svg.get_selected_bbox().width)
        #        dh.ungroup(gs[0]);
        if poprest:
            for g in list(reversed(gs)):
                dh.ungroup(g)

        for el in list(reversed(os)):
            if el.typename == 'TextElement' and poptext:
                dh.split_distant(el)
                dh.pop_tspans(el)

        if removerectb or removerectw:
            for el in os:
                isrect = False
                if el.typename == 'Rectangle':
                    isrect = True
                elif el.typename == 'PathElement':
                    pth = Path(el.get_path())
                    pts = list(pth.control_points)
                    xs = [p.x for p in pts]
                    ys = [p.y for p in pts]
                    if len(pts) == 5 and len(set(xs)) == 2 and len(
                            set(ys)) == 2:
                        isrect = True
                        # if path has 2 unique x, 2 unique y, and exactly 5 pts


#                inkex.utils.debug(el.get_id()+el.typename+str(isrect))
                if isrect:
                    sty = el.composed_style()
                    fill = sty.get('fill')
                    strk = sty.get('stroke')
                    if (removerectw and fill in ['#ffffff','white'] and strk in [None,'none'])\
                        or (removerectb and fill in ['#000000','black'] and strk in [None,'none']):
                        el.delete()
Esempio n. 10
0
    def test_random_path_1(self):
        import random

        from inkex.paths import Line, Vert, Horz, Curve, Move, Arc, Quadratic, TepidQuadratic, Smooth, ZoneClose

        klasses = (Line, Vert, Horz, Curve, Move, Quadratic)  # , ZoneClose, Arc

        def random_segment(klass):
            args = [random.randint(1, 100) for _ in range(klass.nargs)]
            if klass is Arc:
                args[2] = 0  # random.randint(0, 1)
                args[3] = 0  # random.randint(0, 1)
                args[4] = 0  # random.randint(0, 1)
            return klass(*args)

        random.seed(2128506)
        # random.seed(datetime.now())
        n_trials = 10
        n_elements = 15

        for i in range(n_trials):
            path = Path()
            path.append(Move(0, 0))

            for j in range(n_elements):
                k = random.choice(klasses)
                path.append(random_segment(k))
                if k is Curve:
                    while random.randint(0, 1) == 1:
                        path.append(random_segment(Smooth))
                if k is Quadratic:
                    while random.randint(0, 1) == 1:
                        path.append(random_segment(TepidQuadratic))

            pe = PathElement()
            pe.path = path
            ibb = self.get_inkscape_bounding_box(pe)

            self.assert_bounding_box_is_equal(pe, *ibb, disable_inkscape_check=True)
Esempio n. 11
0
 def test_path_TepidQuadratic_2(self):
     path = Path("M 10 5 Q 15 30 25 15 T 50 40 T 15 20")
     pe = PathElement()
     pe.path = path
     ibb = (10, 10 + 43.462), (5, 56)
     self.assert_bounding_box_is_equal(pe, *ibb)
Esempio n. 12
0
 def test_path_Arc_long_sweep_on_axis_x_25(self):
     path = Path("M 10 20 A 10 20 25 1 1 20 15")
     path_element = PathElement()
     path_element.path = path
     self.assert_bounding_box_is_equal(path_element, (4.723, 4.723 + 24.786), (-17.149, -17.149 + 37.149))
Esempio n. 13
0
 def test_path_Arc_short_sweep_on(self):
     path = Path("M 10 20 A 10 20 0 0 1 20 15")
     path_element = PathElement()
     path_element.path = path
     self.assert_bounding_box_is_equal(path_element, (10, 20), (14.127, 14.127 + 5.873))
Esempio n. 14
0
 def test_path_Arc_long_sweep_off(self):
     path = Path("M 10 20 A 10 20 0 1 0 20 15")
     path_element = PathElement()
     path_element.path = path
     self.assert_bounding_box_is_equal(path_element, (7.078, 20 + 7.078), (15.0, 15.0 + 39.127))
Esempio n. 15
0
 def test_path_vert(self):
     path = Path("M 15 30 v 20")
     pe = PathElement()
     pe.path = path
     self.assert_bounding_box_is_equal(pe, (15, 15), (30, 50))
Esempio n. 16
0
 def test_path_Curve(self):
     path = Path("M10 10 C 20 20, 40 20, 50 10")
     pe = PathElement()
     pe.path = path
     self.assert_bounding_box_is_equal(pe, (10, 50), (10, 17.5))
Esempio n. 17
0
 def test_path_Zone(self):
     path = Path("M 15 30 Z")
     pe = PathElement()
     pe.path = path
     self.assert_bounding_box_is_equal(pe, (15, 15), (30, 30))
Esempio n. 18
0
 def test_path_horz(self):
     path = Path("M 15 30 h 20")
     pe = PathElement()
     pe.path = path
     self.assert_bounding_box_is_equal(pe, (15, 35), (30, 30))
Esempio n. 19
0
 def test_path_line(self):
     path = Path("M 15 30 l 10 20")
     pe = PathElement()
     pe.path = path
     self.assert_bounding_box_is_equal(pe, (15, 25), (30, 50))
Esempio n. 20
0
 def test_path_Line(self):
     path = Path("M 15 30 L 10 20")
     pe = PathElement()
     pe.path = path
     self.assert_bounding_box_is_equal(pe, (10, 15),( 20, 30))
Esempio n. 21
0
 def test_path_Move(self):
     path = Path("M 10 20")
     pe = PathElement()
     pe.path = path
     self.assert_bounding_box_is_equal(pe, (10, 10),( 20, 20))
Esempio n. 22
0
def path_to_bline_list(path_d,
                       nodetypes=None,
                       mtx=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
    """
    Convert a path to a BLine List

    bline_list format:

    Vertex:
    [[tg1x, tg1y], [x,y], [tg2x, tg2y], split = T/F]
    Vertex list:
    [ vertex, vertex, vertex, ...]
    Bline:
    {
    "points"    : vertex_list,
    "loop"      : True / False
    }
    """

    # Exit on empty paths
    if not path_d:
        return []

    # Parse the path
    path = Path(path_d).to_arrays()

    # Append (more than) enough c's to the nodetypes
    if nodetypes is None:
        nt = ""
    else:
        nt = nodetypes

    for _ in range(len(path)):
        nt += "c"

    # Create bline list
    #     borrows code from cubicsuperpath.py

    # bline_list := [bline, bline, ...]
    # bline := {
    #           "points":[vertex, vertex, ...],
    #           "loop":True/False,
    #          }

    bline_list = []

    subpathstart = []
    last = []
    lastctrl = []
    lastsplit = True

    for s in path:
        cmd, params = s
        if cmd != "M" and bline_list == []:
            raise MalformedSVGError(
                "Bad path data: path doesn't start with moveto, {}, {}".format(
                    s, path))
        elif cmd == "M":
            # Add previous point to subpath
            if last:
                bline_list[-1]["points"].append(
                    [lastctrl[:], last[:], last[:], lastsplit])
            # Start a new subpath
            bline_list.append({"nodetypes": "", "loop": False, "points": []})
            # Save coordinates of this point
            subpathstart = params[:]
            last = params[:]
            lastctrl = params[:]
            lastsplit = False if nt[0] == "z" else True
            nt = nt[1:]
        elif cmd in "LHV":
            bline_list[-1]["points"].append(
                [lastctrl[:], last[:], last[:], lastsplit])
            if cmd == 'H':
                last = [params[0], last[1]]
                lastctrl = [params[0], last[1]]
            elif cmd == 'V':
                last = [last[0], params[0]]
                lastctrl = [last[0], params[0]]
            else:
                last = params[:]
                lastctrl = params[:]
            lastsplit = False if nt[0] == "z" else True
            nt = nt[1:]
        elif cmd == 'C':
            bline_list[-1]["points"].append(
                [lastctrl[:], last[:], params[:2], lastsplit])
            last = params[-2:]
            lastctrl = params[2:4]
            lastsplit = False if nt[0] == "z" else True
            nt = nt[1:]
        elif cmd == 'Q':
            q0 = last[:]
            q1 = params[0:2]
            q2 = params[2:4]
            x0 = q0[0]
            x1 = 1. / 3 * q0[0] + 2. / 3 * q1[0]
            x2 = 2. / 3 * q1[0] + 1. / 3 * q2[0]
            x3 = q2[0]
            y0 = q0[1]
            y1 = 1. / 3 * q0[1] + 2. / 3 * q1[1]
            y2 = 2. / 3 * q1[1] + 1. / 3 * q2[1]
            y3 = q2[1]
            bline_list[-1]["points"].append(
                [lastctrl[:], [x0, y0], [x1, y1], lastsplit])
            last = [x3, y3]
            lastctrl = [x2, y2]
            lastsplit = False if nt[0] == "z" else True
            nt = nt[1:]
        elif cmd == 'A':
            from inkex.paths import arc_to_path
            arcp = arc_to_path(last[:], params[:])
            arcp[0][0] = lastctrl[:]
            last = arcp[-1][1]
            lastctrl = arcp[-1][0]
            lastsplit = False if nt[0] == "z" else True
            nt = nt[1:]
            for el in arcp[:-1]:
                el.append(True)
                bline_list[-1]["points"].append(el)
        elif cmd == "Z":
            if len(bline_list[-1]["points"]) == 0:
                # If the path "loops" after only one point
                #  e.g. "M 0 0 Z"
                bline_list[-1]["points"].append(
                    [lastctrl[:], last[:], last[:], False])
            elif last == subpathstart:
                # If we are back to the original position
                # merge our tangent into the first point
                bline_list[-1]["points"][0][0] = lastctrl[:]
            else:
                # Otherwise draw a line to the starting point
                bline_list[-1]["points"].append(
                    [lastctrl[:], last[:], last[:], lastsplit])

            # Clear the variables (no more points need to be added)
            last = []
            lastctrl = []
            lastsplit = True

            # Loop the subpath
            bline_list[-1]["loop"] = True
    # Append final superpoint, if needed
    if last:
        bline_list[-1]["points"].append(
            [lastctrl[:], last[:], last[:], lastsplit])

    # Apply the transformation
    if mtx != [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]:
        for bline in bline_list:
            for vertex in bline["points"]:
                for point in vertex:
                    if not isinstance(point, bool):
                        pnt = Transform(mtx).apply_to_point(point)
                        point[0], point[1] = pnt[0], pnt[1]

    return bline_list
Esempio n. 23
0
 def test_path_Arc_long_sweep_on(self):
     path = Path("M 10 20 A 10 20 0 1 1 20 15")
     path_element = PathElement()
     path_element.path = path
     self.assert_bounding_box_is_equal(path_element, (2.922, 2.922 + 20), (-19.127, -19.127 + 39.127))