Esempio n. 1
0
    def saveSVG(self, fn):
        pathsCK = self.paths['ck']
        pathsLL0 = self.paths['ll0']

        def getSegment(path):
            return CubicBezier(complex(path['p0'][0], path['p0'][1]),
                               complex(path['c0'][0], path['c0'][1]),
                               complex(path['c1'][0], path['c1'][1]),
                               complex(path['p1'][0], path['p1'][1]))

        # C/K
        ck = Path(getSegment(pathsCK[0]), getSegment(pathsCK[1]),
                  getSegment(pathsCK[2]), getSegment(pathsCK[3]))

        # L/L0
        ll0 = Path(getSegment(pathsLL0[0]))

        paths = [ck, ll0]
        pathAttributes = {
            "stroke-width": self.width,
            "stroke": "#000",
            "fill": "#fff"
        }

        svg_attributes = {"viewBox": "0 0 600 600", "x": "0px", "y": "0px"}

        attributes = [pathAttributes, pathAttributes]
        wsvg(paths,
             attributes=attributes,
             svg_attributes=svg_attributes,
             filename=fn)
Esempio n. 2
0
def test_jump_reduction():
    paths = []
    rect_width = 100
    rect_height = rect_width / 2
    for i in range(3):
        y_offset = rect_width*i*1j
        corners = [rect_height, rect_width+rect_height,
                   rect_width+rect_height + rect_height*1j,
                   rect_height*1j+ rect_height]
        corners = [c+y_offset for c in corners]
        lines = [Line(start=corners[j], end=corners[(j+1) % len(corners)])
                 for j in range(len(corners))]
        _path = Path(*lines)
        _path = _path.rotated(i*20)
        paths += list(_path)

    max_y = max([p.start.imag for p in paths]+[p.end.imag for p in paths])
    max_x = max([p.start.real for p in paths]+[p.end.real for p in paths])
    filename = "test_jump_reduction.svg"
    viewbox = [0, -rect_height, max_x+2*rect_height, max_y+2*rect_height]
    dwg = Drawing(filename, width="10cm",
                  viewBox=" ".join([str(b) for b in viewbox]))
    dwg.add(dwg.path(d=Path(*paths).d()))
    dwg.save()
    dig = Digitizer()
    dig.filecontents = open(filename, "r").read()
    dig.svg_to_pattern()
    pattern_to_svg(dig.pattern, join(filename + ".svg"))
Esempio n. 3
0
 def fill_trap(self, paths, color="gray"):
     side = shorter_side(paths)
     shapes = [[Path(*paths), "none", "black"],
               [Path(*paths[side:side + 3]), color, "none"]]
     side2 = side + 2
     shapes = self.fill_shape(side, side2, paths, shapes)
     write_debug("fill", shapes)
     return side, side2
Esempio n. 4
0
 def fill_triangle(self, paths, color="green"):
     triangle_sides = [
         paths[0], paths[1],
         Line(start=paths[2].start, end=paths[0].start)
     ]
     shapes = [[Path(*paths), "none", "black"],
               [Path(*triangle_sides), color, "none"]]
     lengths = [p.length() for p in triangle_sides]
     side1 = argmax(lengths)
     lengths[side1] = 0
     side2 = argmax(lengths)
     shapes = self.fill_shape(side1, side2, triangle_sides, shapes)
     write_debug("fill", shapes)
def augment(path_nested, num):
    path_list = []

    path = Path()
    for p in path_nested:
        for segment in p:
            path.append(segment)

    end_points_list = []
    for segment in path:
        s = segment.bpoints()[0]
        e = segment.bpoints()[-1]
        end_points_list.append((s.real, s.imag))
        end_points_list.append((e.real, e.imag))
    end_points = np.array(end_points_list)
    hull_points = end_points[ConvexHull(end_points).vertices]
    idx_xmin, idx_ymin = np.argmin(hull_points, axis=0)
    idx_xmax, idx_ymax = np.argmax(hull_points, axis=0)
    x_range = 0.15 * (hull_points[idx_xmax][0] - hull_points[idx_xmin][0])
    y_range = 0.15 * (hull_points[idx_ymax][1] - hull_points[idx_ymin][1])
    idx_min_max = np.unique([idx_xmin, idx_ymin, idx_xmax, idx_ymax])

    for _ in range(num):
        # global deformation
        p = hull_points
        q = hull_points.copy()
        for idx in idx_min_max:
            x, y = p[idx]
            q[idx] = (x + random.gauss(0, x_range),
                      y + y_range * random.gauss(0, y_range))

        path_deformed = Path()
        for segment in path:
            points = []
            for v in segment.bpoints():
                real, imag = moving_least_square_with_rigid_transformation(
                    p, q, np.array([v.real, v.imag]), max(x_range, y_range))
                point_xformed = complex(real, imag)
                points.append(point_xformed)
            if len(segment.bpoints()) == 2:
                line = Line(points[0], points[1])
                path_deformed.append(line)
            else:
                cubic_bezier = CubicBezier(points[0], points[1], points[2],
                                           points[3])
                path_deformed.append(cubic_bezier)

        path_list.append(path_deformed)

    return path_list
Esempio n. 6
0
def pattern_to_svg(pattern, filename):
    if isinstance(filename, str) or isinstance(filename, unicode):
        output_file = open(filename, "wb")
    else:
        output_file = filename
    paths = []
    colors = []
    scale_factor = 0.1  # scale from cm to mm from pes
    for block in pattern.blocks:
        block_paths = []
        last_stitch = None
        for stitch in block.stitches:
            if "JUMP" in stitch.tags:
                last_stitch = stitch
                continue
            if last_stitch is None:
                last_stitch = stitch
                continue
            block_paths.append(
                Line(start=last_stitch.complex * scale_factor,
                     end=stitch.complex * scale_factor))
            last_stitch = stitch
        if len(block_paths) > 0:
            colors.append(block.tuple_color)
            paths.append(Path(*block_paths))
    dims = overall_bbox(paths)
    mindim = max(dims[1] - dims[0], dims[3] - dims[2])
    print("in pattern to svg, overallbbox", overall_bbox(paths))
    if len(paths) == 0:
        print("warning: pattern did not generate stitches")
        return
    wsvg(paths, colors, filename=output_file, mindim=mindim)
Esempio n. 7
0
    def save_points_as_svg_handler(points, size, image_number):
        # filename like file:///home/gdshen/Pictures/00000.jpg
        filename = os.path.join(project_path, svg_dir, image_number + '.svg')
        paths = []
        for i in range(size):
            start_point_x = points.property(i).property('startPoint').property(
                'X').toInt()
            start_point_y = points.property(i).property('startPoint').property(
                'Y').toInt()
            control_point_x = points.property(i).property(
                'controlPoint').property('X').toInt()
            control_point_y = points.property(i).property(
                'controlPoint').property('Y').toInt()
            target_point_x = points.property(i).property(
                'targetPoint').property('X').toInt()
            target_point_y = points.property(i).property(
                'targetPoint').property('Y').toInt()
            print(start_point_x, start_point_y, control_point_x,
                  control_point_y, target_point_x, target_point_y)
            paths.append(
                Path(
                    QuadraticBezier(complex(start_point_x, start_point_y),
                                    complex(control_point_x, control_point_y),
                                    complex(target_point_x, target_point_y))))

        wsvg(paths=paths, filename=filename)
Esempio n. 8
0
    def initialize(self):
        current_grid = defaultdict(dict)
        # simplify paths to lines
        poly_paths = []
        for path in self.paths:
            if path.length() > MINIMUM_STITCH_LENGTH:
                num_segments = ceil(path.length() / MINIMUM_STITCH_LENGTH)
                for seg_i in range(int(num_segments)):
                    poly_paths.append(Line(start=path.point(seg_i/num_segments), end=path.point((seg_i+1)/num_segments)))
            else:
                poly_paths.append(Line(start=path.start, end=path.end))
        bbox = overall_bbox(self.paths)
        curr_x = int(bbox[0]/MINIMUM_STITCH_LENGTH)*MINIMUM_STITCH_LENGTH
        total_tests = int(bbox[1]-bbox[0])*int(bbox[3]-bbox[2])/(MINIMUM_STITCH_LENGTH*MINIMUM_STITCH_LENGTH)
        while curr_x < bbox[1]:
            curr_y = int(bbox[2]/MINIMUM_STITCH_LENGTH)*MINIMUM_STITCH_LENGTH

            while curr_y < bbox[3]:
                test_line = Line(start=curr_x + curr_y * 1j,
                                 end=curr_x + MINIMUM_STITCH_LENGTH + (
                                                               curr_y + MINIMUM_STITCH_LENGTH) * 1j)
                start = time()
                is_contained = path1_is_contained_in_path2(test_line, Path(*poly_paths))
                end = time()
                if is_contained:
                    current_grid[curr_x][curr_y] = False
                curr_y += MINIMUM_STITCH_LENGTH
            curr_x += MINIMUM_STITCH_LENGTH
        self.current_grid = current_grid
Esempio n. 9
0
    def transform_side(sides, targets, angle_offset=0):
        def angle(point1, point2):
            diff = point1 - point2
            if diff.real == 0:
                return 90.0
            return atan(diff.imag / diff.real) * 180.0 / pi

        # change this so that it has two targets
        transformed_side = Path(*sides)
        source_angle = angle(transformed_side.end, transformed_side.start) - \
                       angle(targets[0], targets[1])
        transformed_side = transformed_side.rotated(-source_angle +
                                                    angle_offset)
        source = transformed_side.end if angle_offset == 0 else transformed_side.start
        diff = targets[1] - source
        transformed_side = transformed_side.translated(diff)
        draw_marker(targets[0], rgb(0, 200, 200))
        draw_marker(targets[1], rgb(0, 255, 255))
        transformed_diff = abs(transformed_side.start - transformed_side.end)
        targets_diff = abs(targets[0] - targets[1])
        if transformed_diff < targets_diff:
            transformed_side.insert(
                0, Line(start=targets[0], end=transformed_side.start))
        elif transformed_diff > targets_diff:
            # pop elements off until the transformed diff is smaller
            while transformed_diff > targets_diff:
                transformed_side.pop(0)
                transformed_diff = abs(transformed_side.start -
                                       transformed_side.end)
            print("path", transformed_side)
            print("path is longer", transformed_diff - targets_diff)
        return transformed_side
Esempio n. 10
0
    def cross_stitch_to_pattern(self, _image):
        # this doesn't work well for images with more than 2-3 colors
        max_dimension = max(_image.size)
        pixel_ratio = int(max_dimension * MINIMUM_STITCH_LENGTH / (4 * 25.4))
        if pixel_ratio != 0:
            _image = _image.resize(
                (_image.size[0] / pixel_ratio, _image.size[1] / pixel_ratio))
        pixels = posturize(_image)

        paths = []
        attrs = []

        for color in pixels:
            for pixel in pixels[color]:
                rgb = "#%02x%02x%02x" % (pixel[2][0], pixel[2][1], pixel[2][2])
                x = pixel[0]
                y = pixel[1]
                attrs.append({"fill": "none", "stroke": rgb})
                paths.append(
                    Path(
                        Line(start=x + 1j * y,
                             end=x + 0.5 * MINIMUM_STITCH_LENGTH + 1j *
                             (y + MINIMUM_STITCH_LENGTH))))
        debug_paths = [[path, attrs[i]["fill"], attrs[i]["stroke"]]
                       for i, path in enumerate(paths)]
        write_debug("png", debug_paths)
        self.all_paths = paths
        self.attributes = attrs
        self.scale = 1.0
        self.generate_pattern()
Esempio n. 11
0
    def generate(self, u, v, w):
        seg1 = self.getSegment(self.c, self.k, 0, u)
        seg2 = self.getSegment(self.c, self.k, 1, u)
        seg3 = self.getSegment(self.c, self.k, 2, u)
        seg4 = self.getSegment(self.c, self.k, 3, u)

        ck = Path(seg1, seg2, seg3, seg4)

        ll0 = Path(
            CubicBezier(self.lerp(self.l['start'], self.l0['start'], v),
                        self.lerp(self.l['c1'], self.l0['c1'], v),
                        self.lerp(self.l['c2'], self.l0['c2'], v),
                        self.lerp(self.l['end'], self.l0['end'], v)))

        self.paths = [ck, ll0]
        self.width = w
Esempio n. 12
0
def extract_text_font(root, metadata_file):
    glyphcodes = get_text_names_to_codes(metadata_file)
    # (2) Output bounding box svg
    for glyph in glyphs:
        if glyph.attrib["glyph-name"] not in glyphcodes:
            continue
        # set glyph id
        g_element = ET.SubElement(root, "g")
        name = glyph.attrib["glyph-name"]
        glyph_code = glyphcodes[name]
        #glyph_code = name.split("uni")[-1]
        g_element.set("c", glyph_code)
        g_element.set("n", name)

        # set bounding box values if present
        if "d" in glyph.attrib:
            path = Path(glyph.attrib["d"])
            xmin, xmax, ymin, ymax = path.bbox()
            g_element.set("x", str(round(xmin, 2)))
            g_element.set("y", str(round(ymin, 2)))
            g_element.set("w", str(round(xmax - xmin, 2)))
            g_element.set("h", str(round(ymax - ymin, 2)))
        else:
            g_element.set("x", str(0.0))
            g_element.set("y", str(0.0))
            g_element.set("w", str(0.0))
            g_element.set("h", str(0.0))

        # set set horiz-av-x
        horiz_adv_x = glyph.attrib[
            "horiz-adv-x"] if "horiz-adv-x" in glyph.attrib else ""
        if horiz_adv_x:
            g_element.set("h-a-x", horiz_adv_x)

    return root
Esempio n. 13
0
def path_difference_shapely(path1, path2):
    try:
        poly1 = path_to_poly(path1)
    except (IndexError, ValueError) as e:
        return path1
    if not poly1.is_valid or not path2.closed:
        # output the shape to a debug file
        # write_debug("invalid1", [[shape_to_path(poly1), "black", "none"]])
        return path1

    poly2 = path_to_poly(path2)
    if not poly2.is_valid:
        # output the shape to a debug file
        # write_debug("invalid2", [[shape_to_path(poly2), "black", "none"]])
        return path1
    diff_poly = poly1.difference(poly2)
    if isinstance(diff_poly, Polygon):
        new_path = shape_to_path(diff_poly)
    elif isinstance(diff_poly, GeometryCollection) or isinstance(
            diff_poly, MultiPolygon):
        new_path = []
        for shape in diff_poly:
            # line objects have a length but no area
            new_path += shape_to_path(shape)
    else:
        print("not sure what to do with type:", type(diff_poly))
    # make a new path from these points
    return Path(*new_path)
Esempio n. 14
0
    def snap(self, tree, threshold):
        def process(points):
            for i, p in enumerate(points):
                best, _, dist = tree.nearest_neighbor([p.real, p.imag])

                if dist < threshold:
                    points[i] = complex(best[0], best[1])
            return points

        path = parse_path(self['d'])
        newPath = Path()
        for seg in path:
            points = process([seg.start, seg.end])

            if isinstance(seg, Line):
                newSeg = Line(*points)
                newPath.append(newSeg)

            elif isinstance(seg, CubicBezier):
                newSeg = CubicBezier(points[0], seg.control1, seg.control2,
                                     points[1])
                newPath.append(newSeg)

        self['d'] = newPath.d()
        return self
Esempio n. 15
0
def transform_path(transform, path):
    if isinstance(path, str):
        return transform_path_string(transform, path)
    # if not a string, it's probably a Path object
    segments = path._segments
    for segment in segments:
        if isinstance(segment, CubicBezier):
            segment.start = transform_point(segment.start,
                                            matrix=transform,
                                            format="complex")
            segment.end = transform_point(segment.end,
                                          matrix=transform,
                                          format="complex")
            segment.control1 = transform_point(segment.control1,
                                               matrix=transform,
                                               format="complex")
            segment.control2 = transform_point(segment.control2,
                                               matrix=transform,
                                               format="complex")
        elif isinstance(segment, Line):
            segment.start = transform_point(segment.start,
                                            matrix=transform,
                                            format="complex")

            segment.end = transform_point(segment.end,
                                          matrix=transform,
                                          format="complex")
        else:
            raise ValueError("not sure how to handle {}".format(type(segment)))
    return Path(*segments)
Esempio n. 16
0
def flip_path(upside_down_path):
    path = []
    _, _, min_y, max_y = upside_down_path.bbox()
    offset = max_y + min_y
    for segment in upside_down_path._segments:
        if type(segment) is Line:
            path.append(
                Line(complex(segment.start.real, -segment.start.imag + offset),
                     complex(segment.end.real, -segment.end.imag + offset)))
        elif type(segment) is Arc:
            path.append(
                Arc(complex(segment.start.real,
                            -segment.start.imag + offset), segment.radius,
                    abs(180 - segment.rotation), segment.large_arc,
                    not segment.sweep,
                    complex(segment.end.real, -segment.end.imag + offset)))
        elif type(segment) is QuadraticBezier:
            path.append(
                QuadraticBezier(
                    complex(segment.start.real, -segment.start.imag + offset),
                    complex(segment.control.real,
                            -segment.control.imag + offset),
                    complex(segment.end.real, -segment.end.imag + offset)))
        else:
            raise ValueError(f"Unknown type: {type(segment)}")

    return Path(*path)
Esempio n. 17
0
    def d(self, useSandT=False, use_closed_attrib=False, rel=False):
        """Returns a path d-string for the path object.
        For an explanation of useSandT and use_closed_attrib, see the
        compatibility notes in the README."""

        segments = [s._segment for s in self._segments]
        path = Path(*segments)
        return path.d(useSandT, use_closed_attrib, rel)
Esempio n. 18
0
def test_generate_straight_stroke():
    dig = Digitizer()
    paths = [Path(*[Line(start=0, end=100), Line(start=100, end=100 + 100j),
                    Line(start=100 + 100j, end=100j), Line(start=100j, end=0)])]
    dig.stroke_color = (0, 0, 0)
    dig.scale = 1.0
    dig.generate_straight_stroke(paths)
    assert len(dig.stitches) > len(paths)
Esempio n. 19
0
def generateInBetweens(poseA, poseB, steps):
    inv = Inventory()

    # make pairs
    pairs = []
    for key in ORDER:
        if key in poseA.inv and key in poseB.inv:
            partA = poseA.inv[key]
            partB = poseB.inv[key]

            if len(partA) != 1 or len(partB) != 1:
                print('Too many parts {0} - A: {1} B: {2}'.format(
                    key, partA.keys(), partB.keys()))
                continue

            pairs.append((key, partA.values()[0], partB.values()[0]))

    # If there are 3 steps, there are 4 gaps between start and finish
    # |------1------2------3------|
    gaps = steps + 1

    # process pairs
    for key, a, b in pairs:
        pathA = parse_path(a['d'])
        pathB = parse_path(b['d'])

        if len(pathA) != len(pathB):
            print('Unmatched segments {0} - A: {1} B: {2}'.format(
                key, pathA, pathB))
            continue

        for step in range(1, gaps):
            newPath = Path()
            for i in range(len(pathA)):
                segA = pathA[i]
                segB = pathB[i]

                if isinstance(segA, Line):
                    points = _deltaPoints([segA.start, segA.end],
                                          [segB.start, segB.end], step, gaps)
                    newPath.append(Line(*points))

                elif isinstance(segA, CubicBezier):
                    points = _deltaPoints(
                        [segA.start, segA.control1, segA.control2, segA.end],
                        [segB.start, segB.control1, segB.control2, segB.end],
                        step, gaps)
                    newPath.append(CubicBezier(*points))

            newPart = Part(newPath.d())
            newPart['x'] = int(_delta(a['x'], b['x'], step, gaps))
            newPart['y'] = int(_delta(a['y'], b['y'], step, gaps))
            newPart['z'] = int(_delta(a['z'], b['z'], step, gaps))

            inv.addPart(key, newPart)
            print(key, step, newPart)

    return inv
Esempio n. 20
0
def test_fill_scan():
    dig = Digitizer()
    dig.fill_color = (0, 0, 0)
    paths = Path(*[Line(start=0, end=100), Line(start=100, end=100+100j),
                   Line(start=100+100j, end=100j), Line(start=100j, end=0)])
    dig.scale = 1.0
    dig.fill = True
    dig.fill_scan(paths)
    assert len(dig.stitches) > 0
Esempio n. 21
0
def test_scan_lines():
    paths = Path(*[
        Line(start=0, end=100),
        Line(start=100, end=100 + 100j),
        Line(start=100 + 100j, end=100j),
        Line(start=100j, end=0)
    ])
    lines = scan_lines(paths)
    assert len(lines) > 0
 def _remove_zero_length_lines(cls, paths):
     new_paths = []
     for path in paths:
         pp = list(filter(lambda x: x.start != x.end, path))
         newpath = Path()
         for p in pp:
             newpath.append(p)
         new_paths.append(newpath)
     return new_paths
Esempio n. 23
0
def glyphToPaths(g, yMul=-1):
  paths = []
  contours = []
  yOffs = -font.info.unitsPerEm

  # decompose components
  if len(g.components):
    font.newGlyph('__svgsync')
    ng = font['__svgsync']
    ng.width = g.width
    ng.appendGlyph(g)
    ng.decompose()
    g = ng

  for c in g:
    curve = False
    points = c.points
    path = Path()
    currentPos = 0j
    controlPoints = []

    for x in range(len(points)):
      p = points[x]
      # print 'p#' + str(x) + '.type = ' + repr(p.type)

      if p.type == 'move':
        currentPos = vec2(p.x, (p.y + yOffs) * yMul)
      elif p.type == 'offcurve':
        controlPoints.append(p)
      elif p.type == 'curve':
        pos = vec2(p.x, (p.y + yOffs) * yMul)
        if len(controlPoints) == 2:
          cp1, cp2 = controlPoints
          path.append(CubicBezier(
            currentPos,
            vec2(cp1.x, (cp1.y + yOffs) * yMul),
            vec2(cp2.x, (cp2.y + yOffs) * yMul),
            pos))
        else:
          if len(controlPoints) != 1:
            raise Exception('unexpected number of control points for curve')
          cp = controlPoints[0]
          path.append(QuadraticBezier(currentPos, vec2(cp.x, (cp.y + yOffs) * yMul), pos))
        currentPos = pos
        controlPoints = []
      elif p.type == 'line':
        pos = vec2(p.x, (p.y + yOffs) * yMul)
        path.append(Line(currentPos, pos))
        currentPos = pos

    paths.append(path)

  if font.has_key('__svgsync'):
    font.removeGlyph('__svgsync')

  return paths
Esempio n. 24
0
def test_generate_pattern(fill):
    dig = Digitizer()
    dig.all_paths = [Path(*[Line(start=0, end=100), Line(start=100, end=100+100j),
                            Line(start=100+100j, end=100j), Line(start=100j, end=0)])]
    dig.attributes = [{"fill": "black"}]
    dig.scale = 1.0
    dig.fill = fill
    dig.generate_pattern()
    assert len(dig.pattern.blocks) > 0
    assert len(dig.pattern.blocks[0].stitches) > 0
Esempio n. 25
0
def get_path(points):
    acc = []
    start = complex(*points[0])
    points = points[1:] + points[:1]
    for p in points:
        end = complex(*p)
        line = Line(start, end)
        acc.append(line)
        start = end
    return Path(*acc)
Esempio n. 26
0
def extract_smufl_font(root, metadata_file):
    glyphnames = get_supported_glyph_codes()
    metadata = get_json_content(metadata_file)
    glyph_anchors = metadata[
        "glyphsWithAnchors"] if "glyphsWithAnchors" in metadata else ""
    # extract alternate glyphs and append them if any
    alternate_glyphs = get_alternate_glyphs(glyphnames, metadata)
    if bool(alternate_glyphs):
        glyphnames.update(alternate_glyphs)

    # (1) Create xml file for each glyph
    write_xml_glyphs(glyphnames)

    # (2) Output bounding box svg
    for glyph in glyphs:
        # set glyph id
        glyph_code = glyph.attrib["glyph-name"][-4:]
        if glyph_code not in glyphnames:
            continue
        g_element = ET.SubElement(root, "g")
        g_element.set("c", glyph_code)

        # set bounding box values if present
        if "d" in glyph.attrib:
            path = Path(glyph.attrib["d"])
            xmin, xmax, ymin, ymax = path.bbox()
            g_element.set("x", str(round(xmin, 2)))
            g_element.set("y", str(round(ymin, 2)))
            g_element.set("w", str(round(xmax - xmin, 2)))
            g_element.set("h", str(round(ymax - ymin, 2)))
        else:
            g_element.set("x", str(0.0))
            g_element.set("y", str(0.0))
            g_element.set("w", str(0.0))
            g_element.set("h", str(0.0))

        # set set horiz-av-x
        if "horiz-adv-x" in glyph.attrib:
            g_element.set("h-a-x", glyph.get("horiz-adv-x"))
            if not float(g_element.get("w")):
                g_element.set("w", glyph.get("horiz-adv-x"))

        # add glyph anchors if present for current glyph
        current_glyphname = glyphnames[
            glyph_code] if glyph_code in glyphnames else ""
        if current_glyphname:
            g_element.set("n", current_glyphname)
            if current_glyphname in glyph_anchors:
                for key, value in glyph_anchors[current_glyphname].items():
                    a_element = ET.SubElement(g_element, "a")
                    a_element.set("n", key)
                    a_element.set("x", str(round(value[0], 2)))
                    a_element.set("y", str(round(value[1], 2)))

    return root
Esempio n. 27
0
def trace_image(filecontents):
    output = StringIO()
    output.write(filecontents)
    _image = Image.open(output)
    pixels = posturize(_image)
    output_paths = []
    attributes = []
    for color in pixels:
        data = zeros(_image.size, uint32)
        for pixel in pixels[color]:
            data[pixel[0], pixel[1]] = 1
        # Create a bitmap from the array
        bmp = potrace.Bitmap(data)
        # Trace the bitmap to a path
        path = bmp.trace()
        # Iterate over path curves
        for curve in path:
            svg_paths = []
            start_point = curve.start_point
            true_start = curve.start_point
            for segment in curve:
                if true_start is None:
                    true_start = segment.start_point
                if start_point is None:
                    start_point = segment.start_point
                if isinstance(segment, BezierSegment):
                    svg_paths.append(
                        CubicBezier(
                            start=start_point[1] + 1j * start_point[0],
                            control1=segment.c1[1] + segment.c1[0] * 1j,
                            control2=segment.c2[1] + segment.c2[0] * 1j,
                            end=segment.end_point[1] +
                            1j * segment.end_point[0]))
                elif isinstance(segment, CornerSegment):
                    svg_paths.append(
                        Line(start=start_point[1] + 1j * start_point[0],
                             end=segment.c[1] + segment.c[0] * 1j))
                    svg_paths.append(
                        Line(start=segment.c[1] + segment.c[0] * 1j,
                             end=segment.end_point[1] +
                             1j * segment.end_point[0]))
                else:
                    print("not sure what to do with: ", segment)
                start_point = segment.end_point
                # is the path closed?
                if true_start == start_point:
                    output_paths.append(Path(*svg_paths))
                    color = pixel[2]
                    rgb = "#%02x%02x%02x" % (color[0], color[1], color[2])
                    fill = rgb
                    attributes.append({"fill": fill, "stroke": rgb})
                    true_start = None
                    start_point = None
                    svg_paths = []
    return output_paths, attributes
Esempio n. 28
0
def svgbox( pixelid, crosshatch, value, numlines ):
	lines     		 = int( (255-value)/(256/numlines) )
	vertical_lines   = 0
	horizontal_lines = lines
	if (crosshatch):
		horizontal_lines = ceil( lines / 2)
		vertical_lines   = lines - horizontal_lines
	paths         = []
	move          = []
	origin        = [pixelid[0]*((config.boxsize[0]/config.meters_per_step)/config.svg_pixel_size ), pixelid[1]*((config.boxsize[1]/config.meters_per_step)/config.svg_pixel_size ) ]
	current_loc   = origin.copy()
	for y in range(0,horizontal_lines):
		if (y == 0):
			move = [0,(((config.boxsize[1]/config.meters_per_step)/config.svg_pixel_size )/horizontal_lines)/2]
			current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ]
		else:
			move = [0,(((config.boxsize[1]/config.meters_per_step)/config.svg_pixel_size )/horizontal_lines)]
			current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ]
		if (y % 2 == 0):
			move = [(config.boxsize[0]/config.meters_per_step)/config.svg_pixel_size,0]
		else:
			move = [(-config.boxsize[0]/config.meters_per_step)/config.svg_pixel_size,0]
		paths.append( Path( Line( complex(current_loc[0], current_loc[1]), complex(current_loc[0] + move[0], current_loc[1] + move[1] ) ) ) )
		current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ]
	current_loc = origin.copy()
	if (crosshatch):
		for y in range(0,vertical_lines):
			if (y == 0):
				move = [(((config.boxsize[0]/config.meters_per_step)/config.svg_pixel_size) /vertical_lines)/2,0]
				current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ]
			else:
				move = [((config.boxsize[0]/config.meters_per_step) /config.svg_pixel_size )/vertical_lines,0]
				current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ]
			if (y % 2 == 0):
				move = [0,((config.boxsize[1]/config.meters_per_step) /config.svg_pixel_size )]
			else:
				move = [0,((-config.boxsize[1]/config.meters_per_step) /config.svg_pixel_size )]
			paths.append( Path( Line( complex(current_loc[0], current_loc[1]), complex(current_loc[0] + move[0], current_loc[1] + move[1] ) ) ) )
			current_loc = [ current_loc[0] + move[0], current_loc[1] + move[1] ]
		current_loc = origin.copy()			
	return paths
Esempio n. 29
0
 def __init__(self, *segments, **kw):
     byA_FrozenClass.__init__(self)
     self._segments = Path()
     for p in segments:
         assert isinstance(p, byA_Line) or isinstance(p, byA_CubicBezier)
         if isinstance(p, byA_Line):
             self.insert(-1, p)
         if isinstance(p, byA_CubicBezier):
             self.insert(-1, p)
     if 'closed' in kw:
         self._segments.closed = kw['closed']  # DEPRECATED
     self._freeze("byA_Path")
Esempio n. 30
0
def test_stack_paths2():
    blo = Path(*[
        Line(start=0, end=100),
        Line(start=100, end=100 + 100j),
        Line(start=100 + 100j, end=100j),
        Line(start=100j, end=0)
    ])
    all_paths = [blo, blo.translated(110)]
    attributes = [{"fill": "black"}, {"fill": "black"}]

    all_paths_new, attributes_new = stack_paths(all_paths, attributes)
    assert all_paths == all_paths_new
    assert attributes_new == attributes