def ref_ticker(canvas, feature, cLen, Y0, nudge, offset): """Draw contig separators.""" # get contig name name = feature.qualifiers.get('id')[0] # take start and end points location = feature.location Zs = location.nofuzzy_start Ze = location.nofuzzy_end # calculate loop offset coordinates loop_offZs = offset_coord(Zs, cLen, offset) loop_offZe = offset_coord(Ze, cLen, offset) # calculate nudge offset coordinates offZs = nudge_coord(loop_offZs, nudge) offZe = nudge_coord(loop_offZe, nudge) xs, xe = offZs*u, offZe*u xmid = (xe+xs)/2 # set Y axis coordinates y0 = Y0+dop*3 # draw canvas.setLineWidth(2) ttl = canvas.beginPath() ttl.moveTo(xs,y0+w) ttl.lineTo(xs,y0+w+h*2) ttl.lineTo(xe,y0+w+h*2) ttl.lineTo(xe,y0+w) canvas.drawPath(ttl, stroke=1, fill=0) canvas.setFont(bFont, NfSize) canvas.drawCentredString(xmid, y0+h*5, name) canvas.setFont(rFont, NfSize) ttl.close()
def draw(self, pmlOp, pageNr, canvas, pe): canvas.setLineWidth(pe.mm2points(pmlOp.width)) path = canvas.beginPath() path.arc( pe.x(pmlOp.x - pmlOp.radius), pe.y(pmlOp.y - pmlOp.radius), pe.x(pmlOp.x + pmlOp.radius), pe.y(pmlOp.y + pmlOp.radius), startAng=pmlOp.startAngle, extent=90) canvas.drawPath(path)
def process(self): kwargs = dict(self.getAttributeValues(ignore=('points', ))) # Start the path and set the cursor to the start location. canvas = attr.getManager(self, interfaces.ICanvasManager).canvas self.path = canvas.beginPath() self.path.moveTo(kwargs.pop('x'), kwargs.pop('y')) # Process the text before the first sub-directive. if self.element.text is not None: self.processPoints(self.element.text) # Handle each sub-directive. for directive in self.element.getchildren(): if directive.tag in self.factories: self.factories[directive.tag](directive, self).process() # If there is more text after sub-directive, process it. if directive.tail is not None: self.processPoints(directive.tail) if kwargs.pop('close', False): self.path.close() if kwargs.pop('clip', False): canvas.clipPath(self.path, **kwargs) else: canvas.drawPath(self.path, **kwargs)
def draw_half_star (self, inner_length=1*inch, outer_length=2*inch, points=5, origin=None): canvas = self.canv canvas.setLineWidth(0) if not origin: canvas.translate(self.size*0.5,self.size*0.5) else: canvas.translate(*origin) canvas.setFillColor(self.fillcolor) canvas.setStrokeColor(self.strokecolor) p = canvas.beginPath() inner = False # Start on top is_origin = True #print 'Drawing star with radius',outer_length,'(moving origin ',origin,')' for theta in range(0,360,360/(points*2)): if 0 < theta < 180: continue if inner: r = inner_length else: r = outer_length x = (math.sin(math.radians(theta)) * r) y = (math.cos(math.radians(theta)) * r) #print 'POINT:',x,y if is_origin: p.moveTo(x,y) is_origin = False else: p.lineTo(x,y) inner = not inner p.close() canvas.drawPath(p,fill=1)
def spacer_ticker(canvas, feature, cLen, Y0, nudge, offset, side): """Draw separator indicators.""" # take start and end points location = feature.location Zs = location.nofuzzy_start Ze = location.nofuzzy_end # calculate loop offset coordinates loop_offZs = offset_coord(Zs, cLen, offset) loop_offZe = offset_coord(Ze, cLen, offset) # calculate nudge offset coordinates offZs = nudge_coord(loop_offZs, nudge) offZe = nudge_coord(loop_offZe, nudge) xs, xe = offZs*u, offZe*u # set Y axis coordinates y0 = Y0-dop*3.5 if side == 'low': yT1 = y0-h*4 else: yT1 = y0+h*4 # draw canvas.setLineWidth(2) ttl = canvas.beginPath() ttl.moveTo(xs,y0) ttl.lineTo(xs,yT1) ttl.lineTo(xe,yT1) ttl.lineTo(xe,y0) canvas.drawPath(ttl, stroke=1, fill=0) ttl.close()
def orf_eus(canvas, featL, coords, color_hex, shape): """Draw CDS and write count.""" xs, xe, xn, y0, yt, yb, ynt, ynb = coords canvas.setLineWidth(1) # initialize path pORF = canvas.beginPath() if shape == 'square': pORF.moveTo(xs,ynt) pORF.lineTo(xe,ynt) pORF.lineTo(xe,ynb) pORF.lineTo(xs,ynb) pORF.lineTo(xs,ynt) # draw triangle-shaped ORFS elif featL <= minL: pORF.moveTo(xs,yt) pORF.lineTo(xe,y0) pORF.lineTo(xs,yb) pORF.lineTo(xs,yt) # draw arrow-shaped ORFS else: pORF.moveTo(xs,ynt) pORF.lineTo(xn,ynt) pORF.lineTo(xn,yt) pORF.lineTo(xe,y0) pORF.lineTo(xn,yb) pORF.lineTo(xn,ynb) pORF.lineTo(xs,ynb) pORF.lineTo(xs,ynt) # evaluate function category and set fill color canvas.setFillColor(color_hex) # finalize object path canvas.drawPath(pORF, stroke=1, fill=1) pORF.close() canvas.setFillColor(black)
def simple_background(canvas, document): header_text = document.title sub_header_text = document.subject canvas.saveState() margin = 0.2 * inch if header_text: canvas.setFont('Helvetica-Bold', 16) canvas.drawString(margin, A4[1] - 0.15 * inch - margin, header_text) if sub_header_text: canvas.setFont('Helvetica-Bold', 32) canvas.drawString(margin, A4[1] - 0.15 * inch - margin - 0.45 * inch, sub_header_text) w = 1.5 * inch h = w / 257.0 * 86.0 canvas.drawImage(os.path.join(resource_dir, "logo_pl.JPG"), A4[0] - w - margin, A4[1] - h - margin, width=w, height=h) p = canvas.beginPath() p.moveTo(0, A4[1] - h - 2 * margin) p.lineTo(A4[0], A4[1] - h - 2 * margin) canvas.drawPath(p) canvas.restoreState()
def confidential(self, canvas): canvas.saveState() canvas.translate(18.5 * cm, 27.4 * cm) canvas.setLineWidth(3) canvas.setFillColorRGB(1, 0, 0) canvas.setStrokeGray(0.5) p = canvas.beginPath() p.moveTo(10, 0) p.lineTo(20, 10) p.lineTo(30, 0) p.lineTo(40, 10) p.lineTo(30, 20) p.lineTo(40, 30) p.lineTo(30, 40) p.lineTo(20, 30) p.lineTo(10, 40) p.lineTo(0, 30) p.lineTo(10, 20) p.lineTo(0, 10) canvas.drawPath(p, fill=1, stroke=0) canvas.restoreState()
def contig_ticker(canvas, feature, cLen, Y0, offset, offset_mode): """Draw contig separators.""" # get contig name name = feature.qualifiers.get('id')[0] # take start and end points location = feature.location Zs = location.nofuzzy_start Ze = location.nofuzzy_end # calculate offset coordinates if offset_mode == 'loop': offZs = offset_coord(Zs, cLen, offset) offZe = offset_coord(Ze, cLen, offset) elif offset_mode == 'nudge': offZs = nudge_coord(Zs, offset) offZe = nudge_coord(Ze, offset) else: offZs = Zs offZe = Ze xs, xe = offZs*u, offZe*u # set Y axis coordinates y0 = Y0-dop*3.5 # draw canvas.setLineWidth(2) ttl = canvas.beginPath() ttl.moveTo(xs,y0) ttl.lineTo(xs,y0-h*4) ttl.lineTo(xs+dop,y0-h*4) canvas.drawPath(ttl, stroke=1, fill=0) canvas.setFont(bFont, NfSize) canvas.drawString(xs+dop*2, y0-h*4.5, name) canvas.setFont(rFont, SfSize) canvas.drawString(xs+dop*2,y0-h*8,"".join(["[",str(Zs),"-",str(Ze),"]"])) canvas.setFont(rFont, NfSize) ttl.close()
def funcy(canvas, document): global header_text global sub_header_text canvas.saveState() margin = 0.2 * inch canvas.setFont('Helvetica-Bold', 16) canvas.drawString(margin, A4[1] - 0.2 * inch - margin, header_text) canvas.setFont('Helvetica-Bold', 32) canvas.drawString(margin, A4[1] - 0.2 * inch - margin - 0.40 * inch, sub_header_text) w = 1.5 * inch h = w / 257.0 * 86.0 canvas.drawImage(os.path.join(resource_dir, "logo_pl.JPG"), A4[0] - w - margin, A4[1] - h - margin, width=w, height=h) p = canvas.beginPath() p.moveTo(0, A4[1] - h - 2 * margin) p.lineTo(A4[0], A4[1] - h - 2 * margin) canvas.drawPath(p) canvas.restoreState()
def confidential(self, canvas): canvas.saveState() canvas.translate(18.5*cm, 27.4*cm) canvas.setLineWidth(3) canvas.setFillColorRGB(1, 0, 0) canvas.setStrokeGray(0.5) p = canvas.beginPath() p.moveTo(10, 0) p.lineTo(20, 10) p.lineTo(30, 0) p.lineTo(40, 10) p.lineTo(30, 20) p.lineTo(40, 30) p.lineTo(30, 40) p.lineTo(20, 30) p.lineTo(10, 40) p.lineTo(0, 30) p.lineTo(10, 20) p.lineTo(0, 10) canvas.drawPath(p, fill=1, stroke=0) canvas.restoreState()
def process(self): kwargs = dict(self.getAttributeValues(ignore=('points',))) # Start the path and set the cursor to the start location. canvas = attr.getManager(self, interfaces.ICanvasManager).canvas self.path = canvas.beginPath() self.path.moveTo(kwargs.pop('x'), kwargs.pop('y')) # Process the text before the first sub-directive. if self.element.text is not None: self.processPoints(self.element.text) # Handle each sub-directive. for directive in self.element.getchildren(): if directive.tag in self.factories: self.factories[directive.tag](directive, self).process() # If there is more text after sub-directive, process it. if directive.tail is not None: self.processPoints(directive.tail) if kwargs.pop('close', False): self.path.close() if kwargs.pop('clip', False): canvas.clipPath(self.path, **kwargs) else: canvas.drawPath(self.path, **kwargs)
def draw_star(self, inner_length=1 * inch, outer_length=2 * inch, points=5, origin=None): canvas = self.canv canvas.setLineWidth(0) if not origin: canvas.translate(self.size * 0.5, self.size * 0.5) else: canvas.translate(*origin) canvas.setFillColor(self.fillcolor) canvas.setStrokeColor(self.strokecolor) p = canvas.beginPath() inner = False # Start on top is_origin = True #print 'Drawing star with radius',outer_length,'(moving origin ',origin,')' for theta in range(0, 360, 360 / (points * 2)): if inner: r = inner_length else: r = outer_length x = (math.sin(math.radians(theta)) * r) y = (math.cos(math.radians(theta)) * r) #print 'POINT:',x,y if is_origin: p.moveTo(x, y) is_origin = False else: p.lineTo(x, y) inner = not inner p.close() canvas.drawPath(p, fill=1)
def drawShape(self, canvas, controls, color): """Utlity to draw a closed shape through a list of control points; extends the previous proc""" canvas.setFillColor(color) p = canvas.beginPath() self.curveThrough(p, controls) p.close() canvas.drawPath(p, stroke=1, fill=1)
def canvasBackground(canvas,colour): canvas.setFillColor(colour) path = canvas.beginPath() path.moveTo(0*cm,0*cm) path.lineTo(0*cm,30*cm) path.lineTo(25*cm,30*cm) path.lineTo(25*cm,0*cm) canvas.drawPath(path,True,True)
def detailsBackground(canvas,colour): canvas.setFillColor(colour) path = canvas.beginPath() path.moveTo(0.7*cm,16.5*cm) path.lineTo(0.7*cm,24*cm) path.lineTo(20*cm,24*cm) path.lineTo(20*cm,16.5*cm) path.lineTo(0.7*cm,16.5*cm) canvas.drawPath(path,True,True)
def draw_circle (self, x, y, r): # Test... canvas = self.canv canvas.setLineWidth(0) canvas.setStrokeColor(colors.grey) canvas.setFillColor(colors.grey) p = canvas.beginPath() p.circle(x,y,r) p.close() canvas.drawPath(p,fill=1)
def draw_circle(self, x, y, r): # Test... canvas = self.canv canvas.setLineWidth(0) canvas.setStrokeColor(colors.grey) canvas.setFillColor(colors.grey) p = canvas.beginPath() p.circle(x, y, r) p.close() canvas.drawPath(p, fill=1)
def baseliner(cLen, canvas, Y_map, nudge): # loop offset has no effect """Draw sequence baseline.""" canvas.setLineWidth(3) y0 = Y_map Zs = 0 # all sequences are initially aligned on the left Ze = cLen # calculate nudge offsets offZs = nudge_coord(Zs, nudge) offZe = nudge_coord(Ze, nudge) # set zeroes x0 = offZs*u x1 = offZe*u pBL = canvas.beginPath() pBL.moveTo(x0,y0) pBL.lineTo(x1,y0) canvas.drawPath(pBL, stroke=1, fill=0) pBL.close()
def seq_scale(canvas, scX, scY, incrT, incrN, dip, dop) : """Draws the sequence scale bar.""" canvas.setLineWidth(1.2) canvas.setFillColor(black) incrCNT = 0 # initialize count of increments psc = canvas.beginPath() psc.moveTo(scX, scY+dip-dop) # start at beginning (duh!) psc.lineTo(scX+incrT*incrN, scY+dip-dop) # draw the scale baseline # draw ticks until the max number of increments is reached while incrCNT <= incrN : psc.moveTo(scX+incrT*incrCNT, scY+dip-dop) psc.lineTo(scX+incrT*incrCNT, scY+dip) incrCNT += 1 canvas.drawPath(psc, stroke=1, fill=0) psc.close() # write out scale extremities values (needs hand-fix if not using kbs) canvas.setFont(rFont,NfSize) canvas.drawRightString(scX, scY+dip+dop, '0') canvas.drawString(scX+incrT*incrN, scY+dip+dop, str(incrN)+' kb')
def contig_ticker(canvas, feature, cLen, Y0, nudge, offset, side): """Draw contig separators.""" # get contig name try: name = feature.qualifiers.get('locus_tag')[0] except TypeError: name = 'unnamed feature' # take start and end points location = feature.location Zs = location.nofuzzy_start Ze = location.nofuzzy_end # calculate loop offset coordinates loop_offZs = offset_coord(Zs, cLen, offset) loop_offZe = offset_coord(Ze, cLen, offset) # calculate nudge offset coordinates offZs = nudge_coord(loop_offZs, nudge) offZe = nudge_coord(loop_offZe, nudge) xs, xe = offZs*u, offZe*u # set Y axis coordinates if side == 'low': y0 = Y0-dop*3.5 yT1 = y0-h*4 yT2 = y0-h*4.5 yT3 = y0-h*8 else: y0 = Y0+dop*3.5 yT1 = y0+h*4 yT2 = y0+h*4.5 yT3 = y0+h*8 # draw canvas.setLineWidth(2) ttl = canvas.beginPath() ttl.moveTo(xs,y0) ttl.lineTo(xs,yT1) ttl.lineTo(xs+dop,yT1) canvas.drawPath(ttl, stroke=1, fill=0) canvas.setFont(bFont, NfSize) canvas.drawString(xs+dop*2, yT2, name) canvas.setFont(rFont, SfSize) canvas.drawString(xs+dop*2,yT3,"".join(["[",str(Zs),"-",str(Ze),"]"])) canvas.setFont(rFont, NfSize) ttl.close()
def baseliner(cLen, canvas, Y_map, offset, offset_mode): """Draw sequence baseline.""" canvas.setLineWidth(3) y0 = Y_map Zs = 0 # all sequences are initially aligned on the left Ze = cLen # calculate offsets if offset_mode == 'nudge': offZs = nudge_coord(Zs, offset) offZe = nudge_coord(Ze, offset) else: offZs = Ze offZe = Zs x0 = offZs*u x1 = offZe*u pBL = canvas.beginPath() pBL.moveTo(x0,y0) pBL.lineTo(x1,y0) canvas.drawPath(pBL, stroke=1, fill=0) pBL.close()
def baseliner(cLen, canvas, Y_map, offset, offset_mode): """Draw sequence baseline.""" canvas.setLineWidth(3) y0 = Y_map Zs = 0 # all sequences are initially aligned on the left Ze = cLen # calculate offsets if offset_mode == 'nudge': offZs = nudge_coord(Zs, offset) offZe = nudge_coord(Ze, offset) else: offZs = Ze offZe = Zs x0 = offZs * u x1 = offZe * u pBL = canvas.beginPath() pBL.moveTo(x0, y0) pBL.lineTo(x1, y0) canvas.drawPath(pBL, stroke=1, fill=0) pBL.close()
def draw(self): canvas = self.canv canvas.setLineWidth(0.1 * cm) canvas.setFillColor(self.fillcolor) canvas.setStrokeColor(self.strokecolor) canvas.translate((1 - self.scale) * self.size / 2, (1 - self.scale) * self.size / 2) canvas.scale(self.scale, self.scale) canvas.setFillColor(self.fillcolor) canvas.setLineJoin(2) ident = self.ident shapes = [[(0, 0), (1, 0), (0.5, 1)], [(0, 0), (1, 0), (0, 1), (1, 1)], [(0, 0), (1, 0), (1, 1), (0, 1)], [(0, 0.5), (0.5, 1), (1, 0.5), (0.5, 0)], [(0, 1), (1, 1), (0.5, 0)]] if self.ident % 2 == 1: canvas.setDash(3, 2) p = canvas.beginPath() ident = ident // 2 if self.ident % 2 == 0: p.moveTo(0.5 * self.size, 0) p.lineTo(0.5 * self.size, 1 * self.size) ident = ident // 2 sndx = (ident) % (len(shapes) + 1) if sndx < len(shapes): d = shapes[sndx] p.moveTo(d[0][0] * self.size, d[0][1] * self.size) for ndx in range(len(d) - 1): p.lineTo(d[ndx + 1][0] * self.size, d[ndx + 1][1] * self.size) else: p.ellipse(0, 0, 1 * self.size, 1 * self.size) p.close() canvas.drawPath(p)
def star(canvas, title="Title Here", aka="Comment here.", xcenter=None, ycenter=None, nvertices=5): from math import pi from reportlab.lib.units import inch radius=inch/3.0 if xcenter is None: xcenter=2.75*inch if ycenter is None: ycenter=1.5*inch canvas.drawCentredString(xcenter, ycenter+1.3*radius, title) canvas.drawCentredString(xcenter, ycenter-1.4*radius, aka) p = canvas.beginPath() p.moveTo(xcenter,ycenter+radius) from math import pi, cos, sin angle = (2*pi)*2/5.0 startangle = pi/2.0 for vertex in range(nvertices-1): nextangle = angle*(vertex+1)+startangle x = xcenter + radius*cos(nextangle) y = ycenter + radius*sin(nextangle) p.lineTo(x,y) if nvertices==5: p.close() canvas.drawPath(p)
def draw(self, pmlOp, pageNr, canvas, pe): p = pmlOp.points pc = len(p) if pc < 2: print "LineOp contains only %d points" % pc return canvas.setLineWidth(pe.mm2points(pmlOp.width)) path = canvas.beginPath() path.moveTo(*pe.xy(p[0])) for point in p[1:]: path.lineTo(*pe.xy(point)) if pmlOp.isClosed: path.close() canvas.drawPath(path)
def beforeDrawPage(self, canvas, doc): self.senderFrame._reset() self.senderFrame.addFromList(self.sendertext[:], canvas) self.senderFooterFrame._reset() self.senderFooterFrame.addFromList(self.sendertext[:], canvas) self.detailsFooterFrame._reset() self.detailsFooterFrame.addFromList(self.detailstext, canvas) self.bankFooterFrame._reset() self.bankFooterFrame.addFromList(self.banktext, canvas) with save_state(canvas): p = canvas.beginPath() p.moveTo(15 * mm, 35 * mm) p.lineTo(self.width - 15 * mm, 35 * mm) canvas.drawPath(p) to = canvas.beginText() to.setTextOrigin(118 * mm, self.height - 15 * mm) to.setFont('Helvetica-Bold', 24) to.textOut(self.kind_text) to.moveCursor(50 * mm, 0) to.setFont('Helvetica', 10) to.textOut(_(u'page %d') % doc.page) to.setTextOrigin(118 * mm, self.height - 21 * mm) to.textOut(self.date_text) to.moveCursor(50 * mm, 0) to.textLine(formatters.date(self.date)) to.moveCursor(-50 * mm, 0) to.textOut(self.ocr_text) to.moveCursor(50 * mm, 0) to.textLine(self.ocr) to.moveCursor(-50 * mm, 0) if self.expiryDate: to.textOut(_(u'Due date')) to.moveCursor(50 * mm, 0) to.textLine(formatters.date(self.expiryDate)) to.moveCursor(-50 * mm, 0) canvas.drawText(to)
def contig_ticker(canvas, feature, cLen, Y0, offset, offset_mode): """Draw contig separators.""" # get contig name name = feature.qualifiers.get('id')[0] # take start and end points location = feature.location Zs = location.nofuzzy_start Ze = location.nofuzzy_end # calculate offset coordinates if offset_mode == 'loop': offZs = offset_coord(Zs, cLen, offset) offZe = offset_coord(Ze, cLen, offset) elif offset_mode == 'nudge': offZs = nudge_coord(Zs, offset) offZe = nudge_coord(Ze, offset) else: offZs = Zs offZe = Ze xs, xe = offZs * u, offZe * u # set Y axis coordinates y0 = Y0 - dop * 3.5 # draw canvas.setLineWidth(2) ttl = canvas.beginPath() ttl.moveTo(xs, y0) ttl.lineTo(xs, y0 - h * 4) ttl.lineTo(xs + dop, y0 - h * 4) canvas.drawPath(ttl, stroke=1, fill=0) canvas.setFont(bFont, NfSize) canvas.drawString(xs + dop * 2, y0 - h * 4.5, name) canvas.setFont(rFont, SfSize) canvas.drawString(xs + dop * 2, y0 - h * 8, "".join(["[", str(Zs), "-", str(Ze), "]"])) canvas.setFont(rFont, NfSize) ttl.close()
def draw(self, pmlOp, pageNr, canvas, pe): if pmlOp.lw != -1: canvas.setLineWidth(pe.mm2points(pmlOp.lw)) path = canvas.beginPath() path.rect(pe.x(pmlOp.x), pe.y(pmlOp.y) - pe.mm2points(pmlOp.height), pe.mm2points(pmlOp.width), pe.mm2points(pmlOp.height)) if pmlOp.fillType == pml.STROKE: canvas.drawPath(path) elif pmlOp.fillType == pml.FILL: canvas.drawPath(path, stroke=0, fill=1) elif pmlOp.fillType == pml.STROKE_FILL: canvas.drawPath(path, stroke=1, fill=1) else: print "Invalid fill type for RectOp"
def render_element(root, element, canvas, styles, text_state=None): canvas.saveState() current_style = {} if len(styles): current_style.update(styles[-1]) for declaration in element.get("style", "").split(";"): if declaration == "": continue key, value = declaration.split(":") if key == "dominant-baseline" and value == "inherit": continue current_style[key] = value styles.append(current_style) if "stroke-width" in current_style: canvas.setLineWidth(float(current_style["stroke-width"])) if "stroke-dasharray" in current_style: canvas.setDash([float(length) for length in current_style["stroke-dasharray"].split(",")]) if current_style.get("visibility") != "hidden": if "transform" in element.attrib: for transformation in element.get("transform").split(")")[::1]: if transformation: type, arguments = transformation.split("(") arguments = arguments.split(",") if type.strip() == "translate": if len(arguments) == 2: canvas.translate(float(arguments[0]), float(arguments[1])) elif type.strip() == "rotate": if len(arguments) == 1: canvas.rotate(float(arguments[0])) if len(arguments) == 3: canvas.translate(float(arguments[1]), float(arguments[2])) canvas.rotate(float(arguments[0])) canvas.translate(-float(arguments[1]), -float(arguments[2])) if element.tag == "svg": if "background-color" in current_style: set_fill_color(canvas, toyplot.color.css(current_style["background-color"])) canvas.rect( 0, 0, float(element.get("width")[:-2]), float(element.get("height")[:-2]), stroke=0, fill=1 ) for child in element: render_element(root, child, canvas, styles) elif element.tag == "g": if element.get("clip-path", None) is not None: clip_id = element.get("clip-path")[5:-1] clip_path = root.find(".//*[@id='%s']" % clip_id) for child in clip_path: if child.tag == "rect": x = float(child.get("x")) y = float(child.get("y")) width = float(child.get("width")) height = float(child.get("height")) path = canvas.beginPath() path.moveTo(x, y) path.lineTo(x + width, y) path.lineTo(x + width, y + height) path.lineTo(x, y + height) path.close() canvas.clipPath(path, stroke=0, fill=1) else: toyplot.log.error("Unhandled clip tag: %s" % child.tag) # pragma: no cover for child in element: render_element(root, child, canvas, styles) elif element.tag == "clipPath": pass elif element.tag == "line": stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) canvas.line( float(element.get("x1")), float(element.get("y1")), float(element.get("x2")), float(element.get("y2")), ) elif element.tag == "path": stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) path = canvas.beginPath() commands = element.get("d").split() while len(commands): command = commands.pop(0) if command == "L": path.lineTo(float(commands.pop(0)), float(commands.pop(0))) elif command == "M": path.moveTo(float(commands.pop(0)), float(commands.pop(0))) canvas.drawPath(path) elif element.tag == "polygon": fill, fill_gradient = get_fill(root, current_style) if fill_gradient is not None: raise NotImplementedError("Gradient <polygon> not implemented.") # pragma: no cover if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) points = [point.split(",") for point in element.get("points").split()] path = canvas.beginPath() for point in points[:1]: path.moveTo(float(point[0]), float(point[1])) for point in points[1:]: path.lineTo(float(point[0]), float(point[1])) path.close() canvas.drawPath(path, stroke=stroke is not None, fill=fill is not None) elif element.tag == "rect": fill, fill_gradient = get_fill(root, current_style) if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) x = float(element.get("x")) y = float(element.get("y")) width = float(element.get("width")) height = float(element.get("height")) path = canvas.beginPath() path.moveTo(x, y) path.lineTo(x + width, y) path.lineTo(x + width, y + height) path.lineTo(x, y + height) path.close() if fill_gradient is not None: pdf_colors = [] pdf_offsets = [] for stop in fill_gradient: offset = float(stop.get("offset")) color = toyplot.color.css(stop.get("stop-color")) opacity = float(stop.get("stop-opacity")) pdf_colors.append(reportlab.lib.colors.Color(color["r"], color["g"], color["b"], color["a"])) pdf_offsets.append(offset) canvas.saveState() canvas.clipPath(path, stroke=0, fill=1) canvas.setFillAlpha(1) canvas.linearGradient( float(fill_gradient.get("x1")), float(fill_gradient.get("y1")), float(fill_gradient.get("x2")), float(fill_gradient.get("y2")), pdf_colors, pdf_offsets, ) canvas.restoreState() canvas.drawPath(path, stroke=stroke is not None, fill=fill is not None) elif element.tag == "circle": fill, fill_gradient = get_fill(root, current_style) if fill_gradient is not None: raise NotImplementedError("Gradient <circle> not implemented.") # pragma: no cover if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) cx = float(element.get("cx")) cy = float(element.get("cy")) r = float(element.get("r")) canvas.circle(cx, cy, r, stroke=stroke is not None, fill=fill is not None) elif element.tag == "text": text_state = {"x": 0, "y": 0, "chunks": [[]]} for child in element: render_element(root, child, canvas, styles, text_state) for chunk in text_state["chunks"]: width = sum([span[7] for span in chunk]) dx = 0 text_anchor = current_style.get("text-anchor", "start") if text_anchor == "middle": dx = -width * 0.5 elif text_anchor == "end": dx = -width for x, y, fill, stroke, font_family, font_size, text, width in chunk: canvas.saveState() canvas.setFont(font_family, font_size) if fill is not None: set_fill_color(canvas, fill) if stroke is not None: set_stroke_color(canvas, stroke) canvas.translate(x + dx, y) canvas.scale(1, -1) canvas.drawString(0, 0, text) canvas.restoreState() elif element.tag == "tspan": # if "font-weight" in current_style: # font_description.set_weight( # pango.WEIGHT_BOLD if current_style["font-weight"] == "bold" else pango.WEIGHT_NORMAL) font_family = get_font_family(current_style) font_size = toyplot.units.convert(current_style["font-size"].strip(), "px") string_width = reportlab.pdfbase.pdfmetrics.stringWidth(element.text, font_family, font_size) ascent, descent = reportlab.pdfbase.pdfmetrics.getAscentDescent(font_family, font_size) if "x" in element.attrib: text_state["x"] = float(element.get("x")) text_state["chunks"].append([]) if "dy" in element.attrib: text_state["y"] += float(element.get("dy")) x = text_state["x"] y = text_state["y"] alignment_baseline = current_style.get("alignment-baseline", "middle") if alignment_baseline == "hanging": y += ascent elif alignment_baseline == "central": y += ascent * 0.5 elif alignment_baseline == "middle": y += (ascent + descent) * 0.5 elif alignment_baseline == "alphabetic": pass else: raise ValueError("Unsupported alignment-baseline: %s" % alignment_baseline) # pragma: no cover baseline_shift = current_style.get("baseline-shift", "0").strip() baseline_shift = toyplot.units.convert(baseline_shift, "px", "px", ascent - descent) y -= baseline_shift fill, fill_gradient = get_fill(root, current_style) stroke = get_stroke(current_style) text_state["chunks"][-1].append( (x, y, fill, stroke, font_family, font_size, element.text, string_width) ) text_state["x"] += string_width elif element.tag in ["defs", "title"]: pass else: raise Exception("unhandled tag: %s" % element.tag) # pragma: no cover styles.pop() canvas.restoreState()
def drawFirstPage(canvas, doc): canvas.saveState() # Title text tobj = canvas.beginText() tobj.setTextOrigin(doc.leftMargin, doc.pagesize[1] - doc.topMargin - 24) tobj.setFont('Helvetica-Bold', 32) tobj.setLeading(22) firstr = '/'.join(doc.firs) tobj.textLine('NavPlot') tobj.setFont('Helvetica', 16) tobj.textLine('%s Navigation warnings for: %s' % (firstr, doc.dateStr)) canvas.drawText(tobj) # Small print canvas.setFont('Helvetica', 10) canvas.drawString(doc.leftMargin, doc.bottomMargin, "IMPORTANT: Do not rely on this map - check NOTAM's from an official "\ "source. Data "+UTF8_COPYRIGHT_SIGN+' '+doc.copyright_holder) # Clipping rectangle for the map path = canvas.beginPath() path.rect(doc.leftMargin, doc.bottomMargin + doc.bottomOffset, doc.mapwidth, doc.mapheight) canvas.clipPath(path) # Drawing style for the map canvas.setLineWidth(0.5) canvas.setFillColor(gray) # Draw the other map stuff. Coordinate file must be in mapinfo format. # Coast line from http://rimmer.ngdc.noaa.gov/mgg/coast/getcoast.html moveFlag = True path = canvas.beginPath() map_data = doc.map_data for lin in map_data.splitlines(): if lin[0] != '#': lon, lat = map(float, lin.split('\t')) x, y = doc.latlon2xy(lat, lon) if moveFlag: path.moveTo(x, y) moveFlag = False else: path.lineTo(x, y) else: moveFlag = True canvas.setStrokeColor(darkgray) canvas.drawPath(path) # Draw some gliding sites canvas.setStrokeColor(gray) delta = 2.5 * mm for gs in GLIDING_SITES: x, y = doc.latlon2xy(*GLIDING_SITES[gs]) canvas.lines( ((x, y + delta, x, y - delta), (x - delta, y, x + delta, y))) canvas.drawString(x + mm, y + mm, gs) # Draw NOTAM areas canvas.setStrokeColor(blue) canvas.setFillColor(black) canvas.setLineWidth(0.5) for n, notam in enumerate(doc.notams): x, y = doc.latlon2xy(notam[0], notam[1]) radius = notam[2] / 60.0 * doc.scale canvas.circle(x, y, radius) if radius / mm < 3: x1 = x + radius / 1.41 + mm / 2 y1 = y + radius / 1.41 + mm / 2 canvas.line(x, y, x1, y1) canvas.drawString(x1, y1, str(n + 1)) else: canvas.drawCentredString(x, y - 3, str(n + 1)) canvas.restoreState()
def drawFirstPage(canvas, doc): canvas.saveState() # Title text tobj = canvas.beginText() tobj.setTextOrigin(doc.leftMargin, doc.pagesize[1]-doc.topMargin-24) tobj.setFont('Helvetica-Bold', 32) tobj.setLeading(22) firstr = '/'.join(doc.firs) tobj.textLine('NavPlot') tobj.setFont('Helvetica', 16) tobj.textLine('%s Navigation warnings for: %s' % (firstr, doc.dateStr)) canvas.drawText(tobj) # Small print canvas.setFont('Helvetica', 10) canvas.drawString(doc.leftMargin, doc.bottomMargin, "IMPORTANT: Do not rely on this map - check NOTAM's from an official "\ "source. Data "+UTF8_COPYRIGHT_SIGN+' '+doc.copyright_holder) # Clipping rectangle for the map path = canvas.beginPath() path.rect(doc.leftMargin, doc.bottomMargin+doc.bottomOffset, doc.mapwidth, doc.mapheight) canvas.clipPath(path) # Drawing style for the map canvas.setLineWidth(0.5) canvas.setFillColor(gray) # Draw the other map stuff. Coordinate file must be in mapinfo format. # Coast line from http://rimmer.ngdc.noaa.gov/mgg/coast/getcoast.html moveFlag = True path = canvas.beginPath() map_data = doc.map_data for lin in map_data.splitlines(): if lin[0] != '#': lon, lat = map(float, lin.split('\t')) x, y = doc.latlon2xy(lat, lon) if moveFlag: path.moveTo(x, y) moveFlag = False else: path.lineTo(x, y) else: moveFlag = True canvas.setStrokeColor(darkgray) canvas.drawPath(path) # Draw some gliding sites canvas.setStrokeColor(gray) delta = 2.5*mm for gs in GLIDING_SITES: x, y = doc.latlon2xy(*GLIDING_SITES[gs]) canvas.lines(((x, y+delta, x, y-delta), (x-delta, y, x+delta, y))) canvas.drawString(x+mm, y+mm, gs) # Draw NOTAM areas canvas.setStrokeColor(blue) canvas.setFillColor(black) canvas.setLineWidth(0.5) for n, notam in enumerate(doc.notams): x, y = doc.latlon2xy(notam[0], notam[1]) radius = notam[2]/60.0*doc.scale canvas.circle(x, y, radius) if radius/mm < 3: x1 = x + radius/1.41 + mm/2 y1 = y + radius/1.41 + mm/2 canvas.line(x, y, x1, y1) canvas.drawString(x1, y1, str(n+1)) else: canvas.drawCentredString(x, y-3, str(n+1)) canvas.restoreState()
def line(canvas): l = canvas.beginPath() l.moveTo(10 * inch, 0) l.lineTo(0, 5 * inch) canvas.drawPath(l, stroke=1, fill=1)
def drawFirstPage(canvas, doc): canvas.saveState() # Title text tobj = canvas.beginText() tobj.setTextOrigin(doc.leftMargin, doc.pagesize[1] - doc.topMargin - 24) tobj.setFont('Helvetica-Bold', 32) tobj.setLeading(22) tobj.textLine('NavPlot') tobj.setFont('Helvetica', 16) tobj.textLine('Navigation warnings for: %s' % doc.dateStr) canvas.drawText(tobj) # Small print canvas.setFont('Helvetica', 10) canvas.drawString(doc.leftMargin, doc.bottomMargin, "THIS IS AN UNOFFICAL BRIEFING. Use at your own risk.") #canvas.drawRightString(doc.pagesize[0] - doc.rightMargin, doc.bottomMargin, # "Data \N{COPYRIGHT SIGN} NATS Ltd.") # Clipping rectangle for the map path = canvas.beginPath() path.rect(doc.leftMargin, doc.bottomMargin + doc.bottomOffset, doc.mapwidth, doc.mapheight) canvas.clipPath(path) # Drawing style for the map canvas.setLineWidth(0.5) canvas.setFillColor(gray) # Draw the other map stuff. Coordinate file must be in mapinfo format. # Coast line from http://rimmer.ngdc.noaa.gov/mgg/coast/getcoast.html moveFlag = True path = canvas.beginPath() map_data = doc.map_data for lin in map_data.splitlines(): try: lon, lat = map(float, lin.split()) except: moveFlag = True continue x, y = doc.latlon2xy(lat, lon) if moveFlag: path.moveTo(x, y) moveFlag = False else: path.lineTo(x, y) canvas.setStrokeColor(darkgray) canvas.drawPath(path) # Draw some gliding sites canvas.setStrokeColor(gray) delta = 2.5 * mm for gs in GLIDING_SITES: x, y = doc.latlon2xy(*GLIDING_SITES[gs]) canvas.lines( ((x, y + delta, x, y - delta), (x - delta, y, x + delta, y))) canvas.drawString(x + mm, y + mm, gs) # Draw NOTAM areas canvas.setStrokeColor(blue) canvas.setFillColor(black) canvas.setLineWidth(0.5) for n, notam in enumerate(doc.notams): x, y = doc.latlon2xy(notam[0], notam[1]) radius = notam[2] / 60.0 * doc.scale canvas.circle(x, y, radius) if radius / mm < 3: x1 = x + radius / 1.41 + mm / 2 y1 = y + radius / 1.41 + mm / 2 canvas.line(x, y, x1, y1) canvas.drawString(x1, y1, str(n + 1)) else: canvas.drawCentredString(x, y - 3, str(n + 1)) canvas.restoreState()
def render_element(root, element, canvas, styles, text_state=None): canvas.saveState() current_style = {} if len(styles): current_style.update(styles[-1]) for declaration in element.get("style", "").split(";"): if declaration == "": continue key, value = declaration.split(":") if key == "dominant-baseline" and value == "inherit": continue current_style[key] = value styles.append(current_style) if "stroke-width" in current_style: canvas.setLineWidth(float(current_style["stroke-width"])) if "stroke-dasharray" in current_style: canvas.setDash([ float(length) for length in current_style["stroke-dasharray"].split(",") ]) if current_style.get("visibility") != "hidden": if "transform" in element.attrib: for transformation in element.get("transform").split(")")[::1]: if transformation: type, arguments = transformation.split("(") arguments = arguments.split(",") if type.strip() == "translate": if len(arguments) == 2: canvas.translate(float(arguments[0]), float(arguments[1])) elif type.strip() == "rotate": if len(arguments) == 1: canvas.rotate(float(arguments[0])) if len(arguments) == 3: canvas.translate(float(arguments[1]), float(arguments[2])) canvas.rotate(float(arguments[0])) canvas.translate(-float(arguments[1]), -float(arguments[2])) if element.tag == "svg": if "background-color" in current_style: set_fill_color( canvas, toyplot.color.css(current_style["background-color"])) canvas.rect( 0, 0, float(element.get("width")[:-2]), float(element.get("height")[:-2]), stroke=0, fill=1, ) for child in element: render_element(root, child, canvas, styles) elif element.tag == "g": if element.get("clip-path", None) is not None: clip_id = element.get("clip-path")[5:-1] clip_path = root.find(".//*[@id='%s']" % clip_id) for child in clip_path: if child.tag == "rect": x = float(child.get("x")) y = float(child.get("y")) width = float(child.get("width")) height = float(child.get("height")) path = canvas.beginPath() path.moveTo(x, y) path.lineTo(x + width, y) path.lineTo(x + width, y + height) path.lineTo(x, y + height) path.close() canvas.clipPath(path, stroke=0, fill=1) else: toyplot.log.error("Unhandled clip tag: %s" % child.tag) # pragma: no cover for child in element: render_element(root, child, canvas, styles) elif element.tag == "clipPath": pass elif element.tag == "line": stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) canvas.line( float(element.get("x1")), float(element.get("y1")), float(element.get("x2")), float(element.get("y2")), ) elif element.tag == "path": stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) path = canvas.beginPath() commands = element.get("d").split() while len(commands): command = commands.pop(0) if command == "L": path.lineTo(float(commands.pop(0)), float(commands.pop(0))) elif command == "M": path.moveTo(float(commands.pop(0)), float(commands.pop(0))) canvas.drawPath(path) elif element.tag == "polygon": fill, fill_gradient = get_fill(root, current_style) if fill_gradient is not None: raise NotImplementedError( "Gradient <polygon> not implemented." ) # pragma: no cover if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) points = [ point.split(",") for point in element.get("points").split() ] path = canvas.beginPath() for point in points[:1]: path.moveTo(float(point[0]), float(point[1])) for point in points[1:]: path.lineTo(float(point[0]), float(point[1])) path.close() canvas.drawPath(path, stroke=stroke is not None, fill=fill is not None) elif element.tag == "rect": fill, fill_gradient = get_fill(root, current_style) if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) x = float(element.get("x")) y = float(element.get("y")) width = float(element.get("width")) height = float(element.get("height")) path = canvas.beginPath() path.moveTo(x, y) path.lineTo(x + width, y) path.lineTo(x + width, y + height) path.lineTo(x, y + height) path.close() if fill_gradient is not None: pdf_colors = [] pdf_offsets = [] for stop in fill_gradient: offset = float(stop.get("offset")) color = toyplot.color.css(stop.get("stop-color")) opacity = float(stop.get("stop-opacity")) pdf_colors.append( reportlab.lib.colors.Color(color["r"], color["g"], color["b"], color["a"])) pdf_offsets.append(offset) canvas.saveState() canvas.clipPath(path, stroke=0, fill=1) canvas.setFillAlpha(1) canvas.linearGradient( float(fill_gradient.get("x1")), float(fill_gradient.get("y1")), float(fill_gradient.get("x2")), float(fill_gradient.get("y2")), pdf_colors, pdf_offsets, ) canvas.restoreState() canvas.drawPath(path, stroke=stroke is not None, fill=fill is not None) elif element.tag == "circle": fill, fill_gradient = get_fill(root, current_style) if fill_gradient is not None: raise NotImplementedError( "Gradient <circle> not implemented." ) # pragma: no cover if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) cx = float(element.get("cx")) cy = float(element.get("cy")) r = float(element.get("r")) canvas.circle(cx, cy, r, stroke=stroke is not None, fill=fill is not None) elif element.tag == "text": text_state = {"x": 0, "y": 0, "chunks": [[]]} for child in element: render_element(root, child, canvas, styles, text_state) for chunk in text_state["chunks"]: width = sum([span[7] for span in chunk]) dx = 0 text_anchor = current_style.get("text-anchor", "start") if text_anchor == "middle": dx = -width * 0.5 elif text_anchor == "end": dx = -width for x, y, fill, stroke, font_family, font_size, text, width in chunk: canvas.saveState() canvas.setFont(font_family, font_size) if fill is not None: set_fill_color(canvas, fill) if stroke is not None: set_stroke_color(canvas, stroke) canvas.translate(x + dx, y) canvas.scale(1, -1) canvas.drawString(0, 0, text) canvas.restoreState() elif element.tag == "tspan": # if "font-weight" in current_style: # font_description.set_weight( # pango.WEIGHT_BOLD if current_style["font-weight"] == "bold" else pango.WEIGHT_NORMAL) font_family = get_font_family(current_style) font_size = toyplot.units.convert( current_style["font-size"].strip(), "px") string_width = reportlab.pdfbase.pdfmetrics.stringWidth( element.text, font_family, font_size) ascent, descent = reportlab.pdfbase.pdfmetrics.getAscentDescent( font_family, font_size) if "x" in element.attrib: text_state["x"] = float(element.get("x")) text_state["chunks"].append([]) if "dy" in element.attrib: text_state["y"] += float(element.get("dy")) x = text_state["x"] y = text_state["y"] alignment_baseline = current_style.get("alignment-baseline", "middle") if alignment_baseline == "hanging": y += ascent elif alignment_baseline == "central": y += ascent * 0.5 elif alignment_baseline == "middle": y += (ascent + descent) * 0.5 elif alignment_baseline == "alphabetic": pass else: raise ValueError("Unsupported alignment-baseline: %s" % alignment_baseline) # pragma: no cover baseline_shift = current_style.get("baseline-shift", "0").strip() baseline_shift = toyplot.units.convert(baseline_shift, "px", "px", ascent - descent) y -= baseline_shift fill, fill_gradient = get_fill(root, current_style) stroke = get_stroke(current_style) text_state["chunks"][-1].append( (x, y, fill, stroke, font_family, font_size, element.text, string_width)) text_state["x"] += string_width elif element.tag in ["defs", "title"]: pass else: raise Exception("unhandled tag: %s" % element.tag) # pragma: no cover styles.pop() canvas.restoreState()
def render_element(root, element, canvas, styles): canvas.saveState() current_style = {} if len(styles): current_style.update(styles[-1]) for declaration in element.get("style", "").split(";"): if declaration == "": continue key, value = declaration.split(":") current_style[key] = value styles.append(current_style) if "stroke-width" in current_style: canvas.setLineWidth(float(current_style["stroke-width"])) if "stroke-dasharray" in current_style: canvas.setDash([ float(length) for length in current_style["stroke-dasharray"].split(",") ]) if current_style.get("visibility") != "hidden": if "transform" in element.attrib: for transformation in element.get("transform").split(")")[::1]: if transformation: transform, arguments = transformation.split("(") arguments = arguments.split(",") if transform.strip() == "translate": if len(arguments) == 2: canvas.translate(float(arguments[0]), float(arguments[1])) elif transform.strip() == "rotate": if len(arguments) == 1: canvas.rotate(float(arguments[0])) if len(arguments) == 3: canvas.translate(float(arguments[1]), float(arguments[2])) canvas.rotate(float(arguments[0])) canvas.translate(-float(arguments[1]), -float(arguments[2])) if element.tag == "svg": if "background-color" in current_style: set_fill_color( canvas, toyplot.color.css(current_style["background-color"])) canvas.rect( 0, 0, float(element.get("width")[:-2]), float(element.get("height")[:-2]), stroke=0, fill=1, ) for child in element: render_element(root, child, canvas, styles) elif element.tag == "g": if element.get("clip-path", None) is not None: clip_id = element.get("clip-path")[5:-1] clip_path = root.find(".//*[@id='%s']" % clip_id) for child in clip_path: if child.tag == "rect": x = float(child.get("x")) y = float(child.get("y")) width = float(child.get("width")) height = float(child.get("height")) path = canvas.beginPath() path.moveTo(x, y) path.lineTo(x + width, y) path.lineTo(x + width, y + height) path.lineTo(x, y + height) path.close() canvas.clipPath(path, stroke=0, fill=1) else: toyplot.log.error("Unhandled clip tag: %s", child.tag) # pragma: no cover for child in element: render_element(root, child, canvas, styles) elif element.tag == "clipPath": pass elif element.tag == "line": stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) canvas.setLineCap(get_line_cap(current_style)) canvas.line( float(element.get("x1", 0)), float(element.get("y1", 0)), float(element.get("x2", 0)), float(element.get("y2", 0)), ) elif element.tag == "path": stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) canvas.setLineCap(get_line_cap(current_style)) path = canvas.beginPath() commands = element.get("d").split() while len(commands): command = commands.pop(0) if command == "L": path.lineTo(float(commands.pop(0)), float(commands.pop(0))) elif command == "M": path.moveTo(float(commands.pop(0)), float(commands.pop(0))) canvas.drawPath(path) elif element.tag == "polygon": fill, fill_gradient = get_fill(root, current_style) if fill_gradient is not None: raise NotImplementedError( "Gradient <polygon> not implemented." ) # pragma: no cover if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) points = [ point.split(",") for point in element.get("points").split() ] path = canvas.beginPath() for point in points[:1]: path.moveTo(float(point[0]), float(point[1])) for point in points[1:]: path.lineTo(float(point[0]), float(point[1])) path.close() canvas.drawPath(path, stroke=stroke is not None, fill=fill is not None) elif element.tag == "rect": fill, fill_gradient = get_fill(root, current_style) if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) x = float(element.get("x", 0)) y = float(element.get("y", 0)) width = float(element.get("width")) height = float(element.get("height")) path = canvas.beginPath() path.moveTo(x, y) path.lineTo(x + width, y) path.lineTo(x + width, y + height) path.lineTo(x, y + height) path.close() if fill_gradient is not None: pdf_colors = [] pdf_offsets = [] for stop in fill_gradient: offset = float(stop.get("offset")) color = toyplot.color.css(stop.get("stop-color")) opacity = float(stop.get("stop-opacity")) pdf_colors.append( reportlab.lib.colors.Color(color["r"], color["g"], color["b"], color["a"] * opacity)) pdf_offsets.append(offset) canvas.saveState() canvas.clipPath(path, stroke=0, fill=1) canvas.setFillAlpha(1) canvas.linearGradient( float(fill_gradient.get("x1")), float(fill_gradient.get("y1")), float(fill_gradient.get("x2")), float(fill_gradient.get("y2")), pdf_colors, pdf_offsets, ) canvas.restoreState() canvas.drawPath(path, stroke=stroke is not None, fill=fill is not None) elif element.tag == "circle": fill, fill_gradient = get_fill(root, current_style) if fill_gradient is not None: raise NotImplementedError( "Gradient <circle> not implemented." ) # pragma: no cover if fill is not None: set_fill_color(canvas, fill) stroke = get_stroke(current_style) if stroke is not None: set_stroke_color(canvas, stroke) cx = float(element.get("cx", 0)) cy = float(element.get("cy", 0)) r = float(element.get("r")) canvas.circle(cx, cy, r, stroke=stroke is not None, fill=fill is not None) elif element.tag == "text": x = float(element.get("x", 0)) y = float(element.get("y", 0)) fill, fill_gradient = get_fill(element, current_style) stroke = get_stroke(current_style) font_family = get_font_family(current_style) font_size = toyplot.units.convert(current_style["font-size"], target="px") text = element.text canvas.saveState() canvas.setFont(font_family, font_size) if fill is not None: set_fill_color(canvas, fill) if stroke is not None: set_stroke_color(canvas, stroke) canvas.translate(x, y) canvas.scale(1, -1) canvas.drawString(0, 0, text) canvas.restoreState() elif element.tag == "image": # pylint: disable=redefined-variable-type import PIL.Image image = element.get("xlink:href") if not image.startswith("data:image/png;base64,"): raise ValueError( "Unsupported image type.") # pragma: no cover image = base64.standard_b64decode(image[22:]) image = io.BytesIO(image) image = PIL.Image.open(image) image = reportlab.lib.utils.ImageReader(image) x = float(element.get("x", 0)) y = float(element.get("y", 0)) width = float(element.get("width")) height = float(element.get("height")) canvas.saveState() path = canvas.beginPath() set_fill_color(canvas, toyplot.color.rgb(1, 1, 1)) canvas.rect(x, y, width, height, stroke=0, fill=1) canvas.translate(x, y + height) canvas.scale(1, -1) canvas.drawImage(image=image, x=0, y=0, width=width, height=height, mask=None) canvas.restoreState() elif element.tag in ["defs", "title"]: pass else: raise Exception("unhandled tag: %s" % element.tag) # pragma: no cover styles.pop() canvas.restoreState()
def generate_list(list_id, names, pre_cross_dict={}, title="Coffee list", canvas=None): """ Generate a PDF for a coffee list Parameters: list_id: A (preferably unique) ID for this list. Will be embedded as a QR code into the URL names: A list of names for this list pre_cross_dict: A dictionary mapping names to a number of crosses to pre-draw onto the list title: A heading for the list. Could e.g. include a date. canvas: If set, draw to this canvas. Returns: A StringIO instance with the PDF file, or None if canvas is given. """ assert len(names) <= COFFEE_COUNT_PER_PAGE # Prepare QR code qr_code = tempfile.NamedTemporaryFile(suffix=".png") qr_data = "%s?id=%d" % (COFFEE_HOMEPAGE, list_id) qrcode.make(qr_data, border=0).save(qr_code.name) # Start page, prepare units had_canvas = canvas is not None if not had_canvas: outfile = StringIO.StringIO() canvas = reportlab.pdfgen.canvas.Canvas(outfile, pagesize=COFFEE_SHEET_PAGE_FORMAT) width, height = COFFEE_SHEET_PAGE_FORMAT cm_unit = reportlab.lib.units.cm qr_size = 2 * cm_unit canvas.translate(1.5 * cm_unit, 1.5 * cm_unit) width -= 3 * cm_unit height -= 3 * cm_unit # Draw orientation markers path = canvas.beginPath() path.moveTo(cm_unit, height) path.lineTo(0, height) path.lineTo(0, height - cm_unit) canvas.setLineWidth(5) canvas.setLineJoin(0) canvas.drawPath(path) path = canvas.beginPath() path.moveTo(width, height - cm_unit) path.lineTo(width, height) path.lineTo(width - cm_unit, height) canvas.drawPath(path) path = canvas.beginPath() path.moveTo(width, cm_unit) path.lineTo(width, 0) path.lineTo(width - cm_unit, 0) canvas.drawPath(path) path = canvas.beginPath() path.moveTo(0, cm_unit) path.lineTo(0, 0) path.lineTo(cm_unit, 0) canvas.drawPath(path) canvas.setLineWidth(1) # Draw title canvas.setFont("Helvetica", 16) canvas.drawString(.5 * cm_unit, height - 1 * cm_unit, title) # Draw the QR code and ID canvas.drawImage(qr_code.name, .5 * cm_unit, .5 * cm_unit, qr_size, qr_size) canvas.setFont("Helvetica", 8) canvas.drawString(.5 * cm_unit, .2 * cm_unit, "#%d" % list_id) # Draw bottom text canvas.setFont("Helvetica", 9) ypos = -.2 COFFEE_SHEET_BOTTOM_TEXT = getattr(config, "COFFEE_SHEET_BOTTOM_TEXT", "") for text in COFFEE_SHEET_BOTTOM_TEXT.split("\n"): text = text.strip() canvas.drawString(qr_size + 1. * cm_unit, qr_size - ypos * cm_unit, text) ypos += .5 # Draw grid grid_y = height - 2*cm_unit canvas.line(0, grid_y, width, grid_y) for name in names: new_y = grid_y - COFFEE_LINE_HEIGHT * cm_unit canvas.line(0, grid_y, 0, new_y) canvas.line(width, grid_y, width, new_y) box_start = COFFEE_NAME_FIELD_WIDTH * cm_unit box_width = (width - box_start) / COFFEE_BOXES_PER_LINE pre_draw_crosses = pre_cross_dict.get(name, 0) for i in range(int((width - box_start) / box_width)): canvas.line(box_start, grid_y, box_start, new_y) if pre_draw_crosses > 0: pre_draw_crosses -= 1 cross_margin = 2 canvas.line(box_start + cross_margin, grid_y - cross_margin, box_start + box_width - cross_margin, new_y + cross_margin) canvas.line(box_start + cross_margin, new_y + cross_margin, box_start + box_width - cross_margin, grid_y - cross_margin) box_start += box_width canvas.drawString(.2 * cm_unit, grid_y - (COFFEE_LINE_HEIGHT - .1) * cm_unit, name) grid_y = new_y canvas.line(0, grid_y, width, grid_y) canvas.showPage() if not had_canvas: canvas.save() return outfile
def draw_line(canvas, x, y, x_to, y_to): p = canvas.beginPath() p.moveTo(x, y) p.lineTo(x_to, y_to) p.close() canvas.drawPath(p)
qr_path = os.path.expanduser(qr_code_file) logo_path = os.path.expanduser('logo.png') im = Image.open(qr_code_file) qr_width, qr_height = im.size canvas = canvas.Canvas("candy-wallet.pdf", pagesize=landscape(letter)) canvas.setFillColor((HexColor("#ab20fd"))) path = canvas.beginPath() path.moveTo(-5 * cm, -5 * cm) path.lineTo(-5 * cm, 35 * cm) path.lineTo(35 * cm, 35 * cm) path.lineTo(35 * cm, -5 * cm) canvas.drawPath(path, True, True) canvas.setLineWidth(.9) canvas.setFont('Helvetica', 10) canvas.setFillColorRGB(32, 5, 137) canvas.drawString(35, 550, 'Address:') canvas.drawString(35, 540, address) canvas.drawString(35, 530, 'Private Key:') canvas.drawString(35, 520, private_key) canvas.drawString(35, 510, 'Public Key:') canvas.drawString(35, 500, public_key) scaler = .75