def generateSVG(pattern, size): f = io.BytesIO() surface = cairo.SVGSurface(f, mm_to_pt(size[0]), mm_to_pt(size[1])) ctx = cairo.Context(surface) ctx.set_source(pattern) ctx.paint() surface.finish() f.seek(0) return f
def draw_alignment_marks(self, ctx): ctx.save() ctx.scale(util.mm_to_pt(1), util.mm_to_pt(1)) ctx.set_source_rgb(0,0,0) ctx.new_path() ctx.move_to(0, self.overlap) ctx.line_to(self.overlap, self.overlap) ctx.line_to(self.overlap, 0) ctx.move_to(self.paper_size[0], self.overlap) ctx.move_to(self.paper_size[0]-self.overlap, self.overlap) ctx.move_to(self.paper_size[0]-self.overlap, 0) ctx.set_line_width(0.5) ctx.stroke() ctx.restore()
def generatePDF(pattern, size, tiling=False, paper_size="A4", margin=10): f = io.BytesIO() if not tiling: surface = cairo.PDFSurface(f, mm_to_pt(size[0]), mm_to_pt(size[1])) ctx = cairo.Context(surface) ctx.set_source(pattern) ctx.paint() surface.finish() else: tiler = CairoTiler(pattern, size, PAPER_SIZES[paper_size], (margin, margin, margin, margin)) tiler.tile(f) f.seek(0) return f
def tile(self, output): surface = cairo.PDFSurface(output, util.mm_to_pt(self.paper_size[0]), util.mm_to_pt(self.paper_size[1])) ctx = cairo.Context(surface) n = math.ceil(self.size[0] / (self.paper_size[0]-self.overlap-self.margins[0]-self.margins[2])) m = math.ceil(self.size[1] / (self.paper_size[1]-self.overlap-self.margins[1]-self.margins[3])) for i in range(0, n): for j in range(0, m): ctx.reset_clip() ctx.identity_matrix() xoff = i * ((self.paper_size[0] - self.margins[0] - self.margins[2])- self.overlap) yoff = j * ((self.paper_size[1] - self.margins[1] - self.margins[3])- self.overlap) mat = cairo.Matrix() mat.translate(util.mm_to_pt(xoff-self.margins[2]), util.mm_to_pt(yoff-self.margins[1])) #ctx.translate(util.mm_to_pt(-xoff), util.mm_to_pt(-yoff))s ctx.rectangle(util.mm_to_pt(self.margins[2]), util.mm_to_pt(self.margins[1]), util.mm_to_pt((self.paper_size[0] - self.margins[0] - self.margins[2])), util.mm_to_pt((self.paper_size[1] - self.margins[1] - self.margins[3]))) ctx.clip() self.pattern.set_matrix(mat) ctx.set_source(self.pattern) ctx.paint() ctx.reset_clip() ul = (self.margins[2], self.margins[1]) ur = (self.paper_size[0] - self.margins[0], ul[1]) ll = (ul[0], self.paper_size[1] - self.margins[2]) lr = (ur[0], ll[1]) if j > 0: #Upper horizontal alignment marks self.draw_alignment_mark(ctx, (self.margins[2], self.margins[1])) self.draw_alignment_mark(ctx, (self.paper_size[0] - self.margins[0], self.margins[1]), flipx=True) if j < (m-1): #Lower horizontal alignment marks self.draw_alignment_mark(ctx, ll, flipy=True) self.draw_alignment_mark(ctx, lr, flipx=True, flipy=True) if i > 0: #Left vertical alignment marks self.draw_alignment_mark(ctx, ul, rotation=math.pi/2, flipx=True) self.draw_alignment_mark(ctx, ll, rotation=math.pi/2, flipy=True, flipx=True) if i < (n-1): #Right vertical alignment marks self.draw_alignment_mark(ctx, ur, rotation=math.pi/2) self.draw_alignment_mark(ctx, lr, rotation=math.pi/2, flipy=True) #ctx.translate(util.mm_to_pt(xoff), util.mm_to_pt(yoff)) ctx.show_page()
def draw_alignment_mark(self, ctx, pos, rotation=0, flipx=False, flipy=False): ctx.save() ctx.scale(util.mm_to_pt(1), util.mm_to_pt(1)) ctx.translate(*pos) if flipy: ctx.scale(1, -1) if flipx: ctx.scale(-1, 1) ctx.rotate(rotation) ctx.set_source_rgb(0,0,0) ctx.move_to(-5,0) ctx.line_to(0, 0) ctx.line_to(0, self.overlap) ctx.line_to(-5, self.overlap) ctx.move_to(0, self.overlap/2) ctx.line_to(-2, self.overlap/2) ctx.set_line_width(0.3) ctx.stroke() ctx.restore()
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()
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))