Ejemplo n.º 1
0
def test_surface():
    # TypeError: The Surface type cannot be instantiated
    test.raises(TypeError, "s = cairo.Surface()")

    if cairo.HAS_IMAGE_SURFACE:
        f, w, h = cairo.FORMAT_ARGB32, 100, 100
        s = cairo.ImageSurface(f, w, h)
        assert s.get_format() == f
        assert s.get_width() == w
        assert s.get_height() == h

    if cairo.HAS_PDF_SURFACE:
        f, w, h = tfi.TemporaryFile(mode='w+b'), 100, 100
        s = cairo.PDFSurface(f, w, h)

    if cairo.HAS_PS_SURFACE:
        f, w, h = tfi.TemporaryFile(mode='w+b'), 100, 100
        s = cairo.PSSurface(f, w, h)

    if cairo.HAS_RECORDING_SURFACE:
        s = cairo.RecordingSurface(cairo.CONTENT_COLOR, None)
        s = cairo.RecordingSurface(cairo.CONTENT_COLOR, (1, 1, 10, 10))

    if cairo.HAS_SVG_SURFACE:
        f, w, h = tfi.TemporaryFile(mode='w+b'), 100, 100
        s = cairo.SVGSurface(f, w, h)
Ejemplo n.º 2
0
def test_recording_surface():
    with pytest.raises(TypeError):
        cairo.RecordingSurface(cairo.CONTENT_COLOR, object())

    with pytest.raises(TypeError):
        cairo.RecordingSurface()

    surface = cairo.RecordingSurface(cairo.CONTENT_COLOR, None)
    assert surface.ink_extents() == (0.0, 0.0, 0.0, 0.0)
Ejemplo n.º 3
0
def test_recording_surface_get_extents():
    surface = cairo.RecordingSurface(cairo.CONTENT_COLOR, None)
    assert surface.get_extents() is None

    surface = cairo.RecordingSurface(cairo.CONTENT_COLOR, (1, 2, 3, 4))
    assert surface.get_extents() == (1, 2, 3, 4)

    surface = cairo.RecordingSurface(cairo.CONTENT_COLOR, (1, 2, 3, 4))
    surface.finish()
    assert surface.get_extents() == (1, 2, 3, 4)
Ejemplo n.º 4
0
    def update_bounding_box(self, items: Collection[Item]) -> None:
        """Update the bounding boxes of the model items for this view, in model
        coordinates."""
        painter = self._bounding_box_painter
        qtree = self._qtree
        c2v = self._matrix
        for item in items:
            surface = cairo.RecordingSurface(cairo.Content.COLOR_ALPHA,
                                             None)  # type: ignore[arg-type]
            cr = cairo.Context(surface)
            painter.paint_item(item, cr)
            x, y, w, h = surface.ink_extents()

            vx, vy = c2v.transform_point(x, y)
            vw, vh = c2v.transform_distance(w, h)

            qtree.add(item=item, bounds=(vx, vy, vw, vh), data=(x, y, w, h))

        if self._matrix_changed and self._model:
            for item in self._model.get_all_items():
                if item not in items:
                    bounds = self._qtree.get_data(item)
                    x, y = c2v.transform_point(bounds[0], bounds[1])
                    w, h = c2v.transform_distance(bounds[2], bounds[3])
                    qtree.add(item=item, bounds=(x, y, w, h), data=bounds)
            self._matrix_changed = False
Ejemplo n.º 5
0
 def Resize(self):
     if self.recording:
         self.recording_surface = cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, None)
         self.recording_ctx = cairo.Context(self.recording_surface)
     else:
         self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.canvas.viewport.x, self.canvas.viewport.y)
         self.ctx = cairo.Context(self.surface)
Ejemplo n.º 6
0
    def draw(self, fobj: typing.BinaryIO, scale = 1, options = { }):
        import cairo

        options["scale"] = scale

        layers: typing.DefaultDict[int, cairo.RecordingSurface] = collections.defaultdict(
                lambda: cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, None))

        for sname in options.get("structures", self.keys()):
            structure = self[sname]
            layers = structure._draw(self, layers, options)

        # for some reason we cant paint these recording surfaces onto another recording surface to
        # determine the bounds of the whole picture, so we need to do this manually

        draw_surfs = [layers[i] for i in options.get("order", self.layers)]
        if len(draw_surfs) == 0: return

        dims = np.array([surf.ink_extents() for surf in draw_surfs])
        dims[:, 2:] += dims[:, :2]
        x0, y0 = np.min(dims[:, :2], axis = 0)
        x1, y1 = np.max(dims[:, 2:], axis = 0)
        w, h = x1 - x0, y1 - y0

        scale = 1
        with cairo.PDFSurface(fobj, scale * w, scale * h) as surf:
            ctx = cairo.Context(surf)
            ctx.translate(0, scale * h)
            ctx.scale(scale, -scale)

            for layer_surf in draw_surfs:
                ctx.set_source_surface(layer_surf, -x0, -y0)
                ctx.paint()
Ejemplo n.º 7
0
 def surface(self, flap_w: float,
             flap_halfh: float) -> cairo.RecordingSurface:
     # Create cairo Surface to write to
     rect = cairo.Rectangle(0, 0, int(mm_to_pt(flap_w)),
                            int(mm_to_pt(flap_halfh * 2)))
     sfc = cairo.RecordingSurface(cairo.Content.COLOR_ALPHA, rect)
     # Prepare
     ctx = cairo.Context(sfc)
     ctx.scale(mm_to_pt(1), mm_to_pt(1))
     ctx.select_font_face(self.font)
     font_h = int(flap_halfh * 1.5)
     ctx.set_font_size(int(font_h * self.scale))
     # Trial run to get the width of the drawn character
     ctx.move_to(0, int(flap_halfh + font_h / 2))
     ctx.show_text(self.char)
     x, y, width, height = sfc.ink_extents()
     # Clear surface
     ctx.save()
     ctx.set_operator(cairo.Operator.CLEAR)
     ctx.paint()
     ctx.restore()
     # Draw for real
     ctx.move_to(int((flap_w - pt_to_mm(width)) / 2 - pt_to_mm(x)),
                 int(flap_halfh + font_h / 2) + self.offset)
     ctx.show_text(self.char)
     return sfc
Ejemplo n.º 8
0
 def bounding_box(self, items: Collection[Item],
                  cr: CairoContext) -> Rectangle:
     """Get the unified bounding box of the rendered items."""
     surface = cairo.RecordingSurface(cairo.Content.COLOR_ALPHA,
                                      None)  # type: ignore[arg-type]
     cr = cairo.Context(surface)
     self.paint(items, cr)
     return Rectangle(*surface.ink_extents())
Ejemplo n.º 9
0
 def get_bound_cairo(self):
     # Not as tight as it could be.... ?
     import cairo
     surface = cairo.RecordingSurface(cairo.Content.COLOR_ALPHA, None)
     cxt = cairo.Context(surface)
     self.process_cairo(cxt)
     extents = surface.ink_extents()
     (ulx, uly, width, height) = extents
     llx, lly = ulx, -uly - height
     urx, ury = llx + width, lly + height
     return Bound(llx, lly, urx, ury)
Ejemplo n.º 10
0
def test_surface():
    # TypeError: The Surface type cannot be instantiated
    pytest.raises(TypeError, "s = cairo.Surface()")

    f, w, h = cairo.FORMAT_ARGB32, 100, 100
    s = cairo.ImageSurface(f, w, h)
    assert s.get_format() == f
    assert s.get_width() == w
    assert s.get_height() == h

    f, w, h = tfi.TemporaryFile(mode='w+b'), 100, 100
    s = cairo.PDFSurface(f, w, h)

    f, w, h = tfi.TemporaryFile(mode='w+b'), 100, 100
    s = cairo.PSSurface(f, w, h)

    s = cairo.RecordingSurface(cairo.CONTENT_COLOR, None)
    s = cairo.RecordingSurface(cairo.CONTENT_COLOR, (1, 1, 10, 10))

    f, w, h = tfi.TemporaryFile(mode='w+b'), 100, 100
    s = cairo.SVGSurface(f, w, h)
Ejemplo n.º 11
0
def _vertical_lines_pattern(color: Color):
    import cairo

    pat = cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, cairo.Rectangle(0, 0, 3, 100))
    ctx = cairo.Context(pat)
    ctx.set_line_width(.4)
    ctx.move_to(.5, 0)
    ctx.line_to(.5, 100)
    ctx.set_source_rgba(*color)
    ctx.stroke()

    return pat
Ejemplo n.º 12
0
def make_pattern(col):
    pattern_surface = \
        cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, (0, 0, 32, 4))
    ctx = cairo.Context(pattern_surface)
    ctx.set_line_width(4)
    ctx.set_source_rgb(col[0],col[1],col[2])
    ctx.move_to(0, 0)
    ctx.line_to(32, 0)
    ctx.stroke()
    pattern = cairo.SurfacePattern(pattern_surface)
    pattern.set_extend(cairo.EXTEND_REPEAT)
    return pattern
Ejemplo n.º 13
0
def text_extents_cairo(text):
    import cairo
    #surface = cairo.PDFSurface("/dev/null", 0, 0)
    # only in cairo 1.11.0:
    surface = cairo.RecordingSurface(cairo.Content.COLOR_ALPHA, None)
    cxt = cairo.Context(surface)
    #cxt.move_to(0., 0.)
    #cxt.show_text(text)
    #extents = surface.ink_extents()
    #(ulx, uly, width, height) = extents
    #print("get_bound", extents) # same as text_extents ...
    ex = cxt.text_extents(text)
    return ex
Ejemplo n.º 14
0
def make_pattern_circles(col):
    pattern_surface = \
        cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, (0, 0, 6, 6))
    ctx = cairo.Context(pattern_surface)
    #ctx.set_line_width(4)
    ctx.set_source_rgb(col[0], col[1], col[2])

    ctx.move_to(0, 0)
    ctx.arc(3, 3, 2.7, 0 * DEGREES, 360 * DEGREES)
    ctx.close_path()
    ctx.fill()
    pattern = cairo.SurfacePattern(pattern_surface)
    pattern.set_extend(cairo.EXTEND_REPEAT)
    return pattern
Ejemplo n.º 15
0
def north_west_lines_pattern(color: Color):
    import cairo

    pat = cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, cairo.Rectangle(0, 0, 3, 3))
    ctx = cairo.Context(pat)
    ctx.set_line_width(.4)
    ctx.move_to(-.2, 1.7)
    ctx.line_to(1.7, -.2)
    ctx.move_to(1.3, 3.2)
    ctx.line_to(3.2, 1.3)
    ctx.set_source_rgba(*color)
    ctx.stroke()

    return pat
Ejemplo n.º 16
0
def main(chute, args):
    pattern, size = chute.get_pattern()

    surface = cairo.RecordingSurface(
        cairo.CONTENT_COLOR_ALPHA,
        cairo.Rectangle(0, 0, util.mm_to_pt(size[0]), util.mm_to_pt(size[1])))
    ctx = cairo.Context(surface)
    ctx.push_group()
    ctx.set_source(pattern)
    ctx.paint()
    pattern2 = ctx.pop_group()

    if args.paper_size:
        if args.typ == "svg":
            print(
                "ERROR: svg does not support multiple pages. Don't specify a paper size if you want to export svg file"
            )
        if args.paper_size not in PAPER_SIZES.keys():
            print(args.paper_size)
            print("Known Paper Sizes:")
            print(PAPER_SIZES)
            return
        tiler = CairoTiler(pattern2,
                           size,
                           overlap=10,
                           paper_size=PAPER_SIZES[args.paper_size])
        tiler.tile(args.output)
    else:
        if args.typ == "svg":
            surface = cairo.SVGSurface(args.output, util.mm_to_pt(size[0]),
                                       util.mm_to_pt(size[1]))
        elif args.typ == "pdf":
            surface = cairo.PDFSurface(args.output, util.mm_to_pt(size[0]),
                                       util.mm_to_pt(size[1]))

        ctx = cairo.Context(surface)
        ctx.set_source(pattern2)
        ctx.paint()
Ejemplo n.º 17
0
def test_from_recording_surface():
    s = cairo.RecordingSurface(cairo.CONTENT_COLOR, None)
    ctx = cairo.Context(s)
    ctx.paint()
    f = io.BytesIO()
    dev = cairo.ScriptDevice(f)
    dev.from_recording_surface(s)
    dev.flush()
    assert b"paint" in f.getvalue()

    # already finished
    dev.finish()
    with pytest.raises(cairo.Error):
        dev.from_recording_surface(s)

    # only recording surfaces allowed
    image = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
    with pytest.raises(TypeError):
        dev.from_recording_surface(image)

    # No None allowed
    with pytest.raises(TypeError):
        dev.from_recording_surface(None)
Ejemplo n.º 18
0
    def Render(self, obj, width, height):
        
        # create drawing
        surface = cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, None)
        self.ctx = cairo.Context (surface)

        # draw all objects
        for node in obj.nodes:
            node.Render(self)

        s_x, s_y, s_width, s_height = surface.ink_extents()

        # create image with whole drawing content
        WIDTH, HEIGHT = 256, 256        
        img_surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, width, height)
        img_ctx = cairo.Context (img_surface)
        
        ratio = s_width
        decx = 0
        decy = math.fabs(s_width-s_height)/2
        if s_height>s_width:
            ratio = s_height
            decx = math.fabs(s_width-s_height)/2
            decy = 0
        if ratio>0:
            img_ctx.scale (WIDTH/ratio, HEIGHT/ratio) # Normalizing the canvas
        
        # draw background
        img_ctx.rectangle(0, 0, WIDTH*ratio, HEIGHT*ratio)
        img_ctx.set_source_rgb(self.background.r, self.background.g, self.background.b)
        img_ctx.fill() 

        img_ctx.set_source_surface(surface, -s_x+decx, -s_y+decy)
        img_ctx.paint()

        return img_surface
Ejemplo n.º 19
0
from typing import List
Ejemplo n.º 20
0
def test_recording_surface():
    surface = cairo.RecordingSurface(cairo.CONTENT_COLOR,
                                     cairo.Rectangle(1, 1, 10, 10))

    assert isinstance(surface.get_extents(), cairo.Rectangle)
Ejemplo n.º 21
0
 def __new__(cls, *args, **kwargs):
     import cairo
     return cairo.RecordingSurface(*args, **kwargs)
Ejemplo n.º 22
0
def main():
    parser = argparse.ArgumentParser(
        description='Add ToUnicode tables to PDF files.')
    parser.add_argument('--outdir',
                        default='tmp/sfd',
                        type=str,
                        help='Output .sfd files to this directory')
    parser.add_argument('pdfs',
                        type=str,
                        nargs='+',
                        help='PDF files to process')
    args = parser.parse_args()

    fontnum = 0
    for pdf in args.pdfs:
        print("Adding ToUnicode tables to PDF file {}".format(pdf))
        with open(pdf, 'rb') as fobj:
            pdfdata = fobj.read()
        doc = PdfReader(fdata=pdfdata)
        doc.read_all()
        fonts = [
            o for o in doc.indirect_objects.values()
            if hasattr(o, 'Type') and o.Type == '/Font'
        ]
        fonts = {
            font.FontDescriptor.FontName[1:]: font
            for font in fonts if font.FontDescriptor is not None
        }
        embedded_fonts = fontforge.fontsInFile(pdf)
        for fontname in embedded_fonts:
            if fontname not in fonts:
                print(
                    "WARNING: font {} not found in pdf file".format(fontname))
                continue
            print("Adding ToUnicode table to font {}".format(fontname))
            font = fontforge.open('{}({})'.format(pdf, fontname))
            fonts[fontname].ToUnicode = PdfDict()
            fonts[fontname].ToUnicode.stream = generate_tounicode(
                font, fonts[fontname])
            # Need to save the modified font because fontforge won't read
            # ToUnicode when it converts to woff later.
            font.fontname = 'pretex{:06d}'.format(fontnum)
            font.save(
                os.path.join(
                    args.outdir,
                    '[{}]{}.sfd'.format(os.path.basename(pdf)[:-4], fontname)))
            fontnum += 1
        PdfWriter(pdf, trailer=doc).write()

        # Measure extents for displayed equations
        pdfpath = os.path.realpath(os.path.dirname(pdf))
        doc = poppler.document_new_from_file(
            'file://{}'.format(os.path.realpath(pdf)), None)
        boxsize = os.path.join(pdfpath, 'boxsize.txt')
        with open(boxsize) as fobj:
            lines = fobj.readlines()
        with open(boxsize, 'w') as fobj:
            pageno = 0
            for line in lines:
                if not (line.startswith('inline:')
                        or line.startswith('display:')):
                    fobj.write(line)
                    continue
                pageno += 1
                if not line.startswith('display:'):
                    fobj.write(line)
                    continue
                page = doc.get_page(pageno - 1)
                width, height = page.get_size()
                surf = cairo.RecordingSurface(
                    cairo.Content.COLOR_ALPHA,
                    cairo.Rectangle(0, 0, width, height))
                ctx = cairo.Context(surf)
                page.render_for_printing(ctx)
                x, y, w, h = surf.ink_extents()
                fobj.write(line.strip() + '{},{},{},{}\n'.format(x, y, w, h))
Ejemplo n.º 23
0
def cairo_surf(
    tree: libginger.Tree,
    colour: ty.Tuple[float, float, float, float] = (0.0, 0.0, 0.0, 1.0),
    line_width: float = 1.0,
    font_size: int = 20,
    token_node_distance: int = 20,
    node_part_margin: int = None,
    label_shift: int = 5,
    arrow_shift: int = 6,
    energy: float = 0.5,
) -> cairo.RecordingSurface:
    r"""
    Render a tree in a cairo recording surface.

    ## Parameters
      - `colour`  the colour of the drawing as an RGBA vector in $[0, 1]⁴$
      - `line_width`  the width of the lines, obviously
      - `font_size`  the font size used
      - `token_node_distance`  the horizontal spacing between two nodes
      - `node_part_margin`  the vertical spacing between node attributes
        (default: `$⌈\texttt{token\_node\_distance`/3}⌉$`)
      - `label_shift`  the space between arrow and their labels
      - `arrow_shift`  the horizontal padding between arrows of opposite directions
      - `energy`  the magnitude of the tangent at the origin of an arc etween two nodes is $E×d$
         where $E$ is the energy and $d$ the distance between those nodes. Increase this to make
         the arcs go higher.
    """

    if cairo is None:
        raise NotImplementedError

    if node_part_margin is None:
        node_part_margin = math.ceil(token_node_distance / 3)

    res = cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, None)
    context = cairo.Context(res)
    context.set_font_size(font_size)

    # For every token, we need to take account the width of the largest of the stacked attributes :
    # `form`, `lemma`, `upostag` This dict associate every node to its Rect
    node_rects = {}  # type: ty.Dict[libginger.Node, Rect]
    current_x = 0
    for n in tree.word_sequence:
        parts_extents = [
            context.text_extents(s if s is not None else "_")
            for s in (n.form, n.lemma, n.upostag)
        ]
        w = max(e[2] for e in parts_extents)
        h = sum(e[3] for e in parts_extents) + 3 * node_part_margin
        node_rects[n] = Rect(current_x, 0, w, h)
        current_x += w + token_node_distance

    # Normalise the height of the nodes to the largest
    part_height = math.ceil(max(h for _, _, _, h in node_rects.values()) / 3)
    nodes_height = 3 * part_height
    # And take into account in node rects
    node_rects = {
        n: Rect(x, y, w, nodes_height) for n, (x, y, w, h) in node_rects.items()
    }

    # Now draw
    context.set_source_rgba(*colour)
    context.set_line_width(line_width)

    # First draw the nodes
    context.move_to(0, 0)
    for node, (x, y, w, h) in ((n, node_rects[n]) for n in tree.word_sequence):
        parts = (
            s if s is not None else "_" for s in (node.form, node.lemma, node.upostag)
        )
        for i, p in enumerate(parts, start=1):
            margin = math.floor((w - context.text_extents(p)[2]) / 2)
            context.move_to(x + margin, y + i * part_height)
            context.show_text(p)
    context.stroke()

    # Find out the largest arc height
    # First, get the relations
    deps = [
        (node.head, node, node.deprel)
        for node in tree.word_sequence
        if node.head is not tree.root
    ]

    # Now draw the arcs
    arrowhead_size = font_size / 3
    for head, foot, tag in deps:
        # Arc
        head_rect, foot_rect = node_rects[head], node_rects[foot]
        start = Point(
            head_rect.x
            + head_rect.w / 2
            + (-arrow_shift if foot.identifier < head.identifier else arrow_shift),
            head_rect.y,
        )
        end = Point(foot_rect.x + foot_rect.w / 2, foot_rect.y - arrowhead_size)
        origin_speed = math.floor(abs(end.x - start.x) * energy)
        control1 = (start.x, start.y - origin_speed)
        control2 = (end.x, end.y - origin_speed)
        context.move_to(*start)
        context.curve_to(*control1, *control2, *end)
        arrow_extents = context.path_extents()
        context.stroke()
        arrowhead(context, arrowhead_size, end)
        tag_w = context.text_extents(tag)[2]
        context.move_to(
            (arrow_extents[0] + arrow_extents[2] - tag_w) / 2,
            arrow_extents[1] - label_shift,
        )
        context.show_text(tag)

    # Root arrow
    head_rect = node_rects[
        next(node for node in tree.word_sequence if node.head is tree.root)
    ]
    root_x = head_rect.x + head_rect.w / 2
    _, root_y, *_ = res.ink_extents()
    root_w = context.text_extents("root")[2] - label_shift
    context.move_to(root_x - root_w / 2, root_y)
    context.show_text("root")
    context.move_to(root_x, root_y)
    context.line_to(root_x, head_rect.y)
    context.stroke()
    arrowhead(context, arrowhead_size, Point(root_x, head_rect.y))
    return res
Ejemplo n.º 24
0
def create_surface(zoom=0):
    surface = cairo.RecordingSurface(
        cairo.Content.COLOR_ALPHA,
        cairo.Rectangle(0, 0, Renderer.BASE_WIDTH, Renderer.BASE_HEIGHT))
    return surface
Ejemplo n.º 25
0
def process(pcbfile, side=pcbnew.F_Cu, netlist=None, output=None):
    refs = None

    # load netlist
    if netlist is not None:
        net = kicad_netlist_reader.netlist(netlist)
        refs = [x.getRef() for x in net.getInterestingComponents()]

    # build BOM
    print("Loading %s" % pcbfile)
    pcb = pcbnew.LoadBoard(pcbfile)
    bom_table = generate_bom(pcb, filter_layer=side, filter_refs=refs)
    footprints = load_footprints(pcb, layer=side)
    board_xmin, board_ymin, board_width, board_height = get_bbox(pcb)
    margin = Point(5, 15)
    text_margin = Point(5, 2)

    # Render all components into a base surface for performance
    base = cairo.RecordingSurface(cairo.Content.COLOR_ALPHA, None)
    ctx = cairo.Context(base)

    # Render Footprints
    render_footprints(pcb, ctx, footprints, BASE_STYLE)

    # Show Board Edge for context
    ctx.set_source_rgb(0, 0, 0)
    ctx.set_line_width(0.25)
    ctx.rectangle(board_xmin, board_ymin, board_width, board_height)
    ctx.stroke()

    # for each part group, print page to PDF
    fname_out = output
    if output is None:
        sidename = "top" if side == pcbnew.F_Cu else "bottom"
        fname_out = os.path.splitext(
            pcbfile)[0] + "_place_" + sidename + ".pdf"

    with cairo.PDFSurface(fname_out, 72, 72) as pdf:
        for i, bom_row in enumerate(bom_table):
            print("Plotting page (%d/%d)" % (i + 1, len(bom_table)))
            pdf.set_size((board_width + 2 * margin.x) * POINTS_PER_MM,
                         (board_height + 2 * margin.y) * POINTS_PER_MM)
            ctx = pangocairo.CairoContext(cairo.Context(pdf))

            # Scale from points to mm
            ctx.scale(POINTS_PER_MM, POINTS_PER_MM)
            # Render Text
            render_text(
                ctx,
                text_margin.x,
                margin.y - text_margin.y,
                board_width + 2 * margin.x - 2 * text_margin.x,
                "%dx %s, %s" % (len(bom_row.refs), bom_row.value,
                                bom_row.footprint),
                align_bottom=True)
            render_text(
                ctx, text_margin.x, board_height + margin.y + text_margin.y,
                board_width + 2 * margin.x - 2 * text_margin.x, ", ".join(
                    bom_row.refs))

            # Offset within page for margins+header
            ctx.translate(margin.x, margin.y)
            # Set corner of board on kicad page to 0,0
            ctx.translate(-board_xmin, -board_ymin)
            ctx.set_source_surface(base, 0.0, 0.0)
            ctx.paint()
            render_footprints(
                pcb,
                ctx,
                footprints,
                HIGHLIGHT_STYLE,
                include_only=bom_row.refs)
            pdf.show_page()

    print("Output written to %s" % fname_out)
Ejemplo n.º 26
0
    def get_pattern(self):
        pattern_lines = self._get_pattern_path()
        line_right = spg.LineString(pattern_lines["right"])
        line_top = spg.LineString(pattern_lines["top"])
        line_left = spg.LineString(pattern_lines["left"])
        line_bottom = spg.LineString(pattern_lines["bottom"])

        coords = list()
        coords.extend(line_right.coords)
        coords.extend(line_top.coords)
        coords.extend(line_left.coords)
        coords.extend(line_bottom.coords)

        polygon = spg.Polygon(coords)
        ui, li = polygon.exterior.xy

        ui = np.array(ui)
        li = np.array(li)

        if self.joint_style == MitreType.none:
            if self.seam_allowance[0] > 0:
                polygon = self.add_seamallowance(polygon, line_right,
                                                 self.seam_allowance[0])
            if self.seam_allowance[1] > 0:
                polygon = self.add_seamallowance(polygon, line_top,
                                                 self.seam_allowance[1])
            if self.seam_allowance[2] > 0:
                polygon = self.add_seamallowance(polygon, line_left,
                                                 self.seam_allowance[2])
            if self.seam_allowance[3] > 0:
                polygon = self.add_seamallowance(polygon, line_bottom,
                                                 self.seam_allowance[3])
        elif len(set(self.seam_allowance)) == 1:
            if self.joint_style == MitreType.miter:
                jt = JOIN_STYLE.mitre
            elif self.joint_style == MitreType.bevel:
                jt = JOIN_STYLE.bevel
            elif self.joint_style == MitreType.round:
                jt = JOIN_STYLE.round
            polygon = polygon.buffer(self.seam_allowance[0],
                                     join_style=jt,
                                     mitre_limit=2)
        elif self.joint_style == MitreType.bevel:
            polygon = self.add_seamallowance_bevel(
                [line_right, line_top, line_left, line_bottom],
                self.seam_allowance)
        elif self.joint_style == MitreType.round:
            print(
                "ERROR: joint style \"round\" not supported for non uniform seam allowance. Please use bevel or none"
            )
        elif self.joint_style == MitreType.miter:
            print(
                "ERROR: joint style \"miter\" not supported for non uniform seam allowance. Please use bevel or none"
            )

        u, l = polygon.exterior.xy

        u = np.array(u)
        l = np.array(l)

        margins = (10, 10, 10, 10)
        l = l * -1
        li = li * -1

        pattern_extend = (np.min(u), np.min(l), np.max(u), np.max(l))
        pattern_width = pattern_extend[2] - pattern_extend[0]
        pattern_height = pattern_extend[3] - pattern_extend[1]

        document_width = pattern_width + margins[0] + margins[1]
        document_height = pattern_height + margins[2] + margins[3]

        surface = cairo.RecordingSurface(
            cairo.CONTENT_COLOR_ALPHA,
            cairo.Rectangle(0, 0, mm_to_pt(document_width),
                            mm_to_pt(document_height)))
        ctx = cairo.Context(surface)
        ctx.save()
        ctx.set_line_join(cairo.LINE_JOIN_ROUND)
        ctx.set_line_cap(cairo.LINE_CAP_ROUND)
        ctx.push_group()
        ctx.scale(mm_to_pt(1), mm_to_pt(1))
        ctx.save()

        if self.grid:
            draw_grid(ctx, (0, 0), 10, 1, document_height, document_width)

        #draw seam allowance
        ctx.translate(
            -pattern_extend[0] + (document_width / 2 - pattern_width / 2),
            -pattern_extend[1] + (document_height / 2 - pattern_height / 2))
        ctx.move_to(u[0], l[0])
        for x, y in zip(u, l):
            ctx.line_to(x, y)
        ctx.close_path()
        ctx.set_source_rgb(.0, .0, .0)
        ctx.set_line_width(0.3)
        ctx.stroke()

        #draw pattern
        ctx.move_to(ui[0], li[0])
        for x, y in zip(ui, li):
            ctx.line_to(x, y)
        ctx.close_path()
        ctx.set_source_rgb(1, .0, .0)
        ctx.set_line_width(0.3)
        ctx.stroke()
        ctx.restore()
        pattern = ctx.pop_group()
        return (pattern, (document_width, document_height))