def beforeDrawPage(self, canvas): """Draws the background before anything else""" canvas.saveState() rl_obj = makerl(canvas, self.page_template) canvas.scale(self.page_xscale, self.page_yscale) canvas.doForm(rl_obj) canvas.restoreState()
def gen_label(sku, canvas, title): # barcode128 = code39.Extended39(value = sku, barWidth = barWidth, barHeight = barHeight) barcode128 = code128.Code128(value = sku, barWidth = barWidth, barHeight = barHeight) canvas.scale(0.3, 1.0) barcode128.drawOn(canvas, bar_x, bar_y) canvas.setFont(font, fontsize) canvas.drawString(bar_value_x, bar_value_y, sku) canvas.showPage()
def drawOn(self, canvas): canvas.saveState() canvas.setFont('Helvetica-Bold', 24) canvas.drawString(600, 100, 'A Custom Shape') canvas.translate(self.x, self.y) canvas.scale(self.scale, self.scale) self.drawBounds(canvas) self.drawCentre(canvas) self.drawTopLeft(canvas) self.drawBottomLeft(canvas) self.drawBottomRight(canvas) self.drawTopRight(canvas) canvas.restoreState()
def drawOn(self, canvas): canvas.saveState() canvas.setFont('Helvetica-Bold',24) canvas.drawString(600, 100, 'A Custom Shape') canvas.translate(self.x, self.y) canvas.scale(self.scale, self.scale) self.drawBounds(canvas) self.drawCentre(canvas) self.drawTopLeft(canvas) self.drawBottomLeft(canvas) self.drawBottomRight(canvas) self.drawTopRight(canvas) canvas.restoreState()
def scaletranslate(canvas): from reportlab.lib.units import inch canvas.setFont("Courier-BoldOblique", 12) # save the state canvas.saveState() # scale then translate canvas.scale(0.3, 0.5) canvas.translate(2.4*inch, 1.5*inch) canvas.drawString(0, 2.7*inch, "Scale then translate") coords(canvas) # forget the scale and translate... canvas.restoreState() # translate then scale canvas.translate(2.4*inch, 1.5*inch) canvas.scale(0.3, 0.5) canvas.drawString(0, 2.7*inch, "Translate then scale") coords(canvas)
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 gen_label(fnsku, title, sku, canvas, modl): barcode128 = code128.Code128(value = fnsku, barWidth = modl.barWidth, barHeight = modl.barHeight) barcode128.drawOn(canvas, modl.bar_x, modl.bar_y) canvas.setFont(modl.font, modl.fontsize) canvas.drawString(modl.bar_value_x, modl.bar_value_y, fnsku) canvas.setFont(modl.font, modl.fontsize - 1) if len(title) > modl.title_len: title = title[0:modl.title_left_len] + "..." + title[modl.title_left_len - modl.title_len:] canvas.scale(0.6, 1.0) canvas.drawString(modl.title_x, modl.title_y, title)#title canvas.setFont(modl.fontB, modl.fontsize) canvas.scale(1.0, 1.0) canvas.drawString(modl.condition_type_x, modl.condition_type_y, modl.condition_type) if modl.print_sku: canvas.setFont(modl.font, modl.fontsize) canvas.drawString(modl.sku_x, modl.sku_y, sku) canvas.showPage()
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 genkitlabel(canvas,xa,ya,xw,yh,contentlist,test=0,paper_size_no=0): """ """ v('[------genkitlabel()') x = xa y = ya m = .05*inch h = yh # calc height h -= m*2 # height - margin w = xw # calc width w -= m*2 # width - margin v('genkitlabel() ------') v('genkitlabel() xa,ya,xw,yh: %f %f %f %f' % (xa,ya,xw,yh)) v('genkitlabel() m h w : %f %f %f' % ( m, h, w)) xo = yo = m # origin canvas.setLineWidth(.01*inch) canvas.setStrokeColorRGB(.75,.75,.75) global xwidth if (not (xwidth/inch <= 3.50)): cutmark(canvas,x,y,1,1) cutmark(canvas,x+xw,y+yh,-1,-1) cutmark(canvas,x,y+yh,1,-1) cutmark(canvas,x+xw,y,-1,1) didlogo = False yloc = y + h image_size = 1.2*inch logo_yloc = yloc-image_size+.2*inch yrel = 0 for line in contentlist: if (line == '..' or line == '.'): flip = False break v('genkitlabel(): line:%s' %(line)) token = line.split() if len(token) <= 0: continue dowhat = token[0].upper() #--- global flip if (dowhat == 'FLIP'): flip = True elif (dowhat == 'LOGO'): v('LOGO') if (len(token) == 1): # no arg print logo if (paper_size_no == 3): image_size = 1*inch canvas.drawImage('logo512x512.png', x+m-.75*inch,logo_yloc, image_size, image_size, preserveAspectRatio=True) else: canvas.drawImage('logo512x512.png', x+m+.1*inch+2.4*inch,logo_yloc, image_size, image_size, preserveAspectRatio=True) else: # print arg arg = token[1] if (len(arg) == 1): # character. make it big if flip: # They said 'LOGO X', so we draw big fat X where the logo should be canvas.saveState() canvas.translate(x+m+.3*inch,logo_yloc+1*inch) canvas.scale(-1,-1) canvas.setFont('Helvetica-Bold',70) canvas.drawString(0,0,token[1]) canvas.restoreState() else: # They said 'LOGO X', so we draw big fat X where the logo should be canvas.setFont('Helvetica-Bold',70) canvas.drawString(x+m-.45*inch,logo_yloc+.2*inch,token[1]) else: # Multiple characters if flip: # They said 'LOGO X', so we draw big fat X where the logo should be canvas.saveState() canvas.translate(x+m+.3*inch,logo_yloc+1*inch) canvas.scale(-1,-1) canvas.setFont('Helvetica-Bold',20) canvas.drawString(.5*inch,.55*inch,arg[0]) canvas.drawString(.5*inch,.30*inch,arg[1]) canvas.drawString(.5*inch,.05*inch,arg[2]) canvas.restoreState() else: # They said 'LOGO X', so we draw big fat X where the logo should be canvas.setFont('Helvetica-Bold',20) canvas.drawString(x+m-.45*inch,logo_yloc+.80*inch,arg[0]) canvas.drawString(x+m-.45*inch,logo_yloc+.55*inch,arg[1]) canvas.drawString(x+m-.45*inch,logo_yloc+.30*inch,arg[2]) #--- elif (dowhat == 'BARCODE'): yloc = render_barcode(canvas, x,yloc, token[1], ' '.join(token[2:])) v('genkitlabel(): yloc now: %f' % (yloc)) #--- elif (dowhat == 'KEYVAL'): v('KEYVAL Width : ') yloc = render_key_and_value(canvas, x+m+.350*inch, yloc, token[1], ' '.join(token[2:])) #yinc = .150*inch ## ## v('genkitlabel() --- line:' + line) return line
def render_key_and_value(canvas,x,y,lhs,rhs,wraplen=40): """ render a keyword:value pair. Keyword will be in bold """ global xwidth global yheight yinc = .125*inch fontsize = 10 v('render_key_and_value(): xwidth:%f yheight:%f ' % (xwidth,yheight)) # little labels get special treatment if (xwidth/inch <= 3.50): v('render_key_and_value(): fixing wraplen for small labels') wraplen = 25 fontsize = 9 if flip: yinc = -.105*inch else: yinc = .105*inch lhs += ': ' width = stringWidth(lhs,'Helvetica-Bold',fontsize) width *= 1.2 if (width < .75*inch): width = .75*inch # draw keyword canvas.setFont('Helvetica-Bold',fontsize) if flip: canvas.saveState() canvas.translate(x+2.45*inch,y+.25*inch) canvas.scale(-1,-1) canvas.drawString(0, 0, lhs.upper()) canvas.restoreState() else: canvas.drawString(x, y, lhs.upper()) # draw value canvas.setFont('Helvetica',fontsize) yrel = 0 lines = 0 v('render_key_and_value(): y+yrel: %f' %(y+ yrel)) text_line_list = textwrap.wrap(rhs,wraplen) for line in text_line_list: if flip: canvas.saveState() canvas.translate(x+width+1.00*inch, y+yrel+.25*inch) canvas.scale(-1,-1) canvas.drawString(0,0, line) canvas.restoreState() else: canvas.drawString(x+width, y+yrel, line) yrel -= yinc lines += 1 if ((yheight/inch <= 1.25) and (lines == 3)): break yrel -= yinc/2 return y+yrel
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 mirror(canvas): from reportlab.lib.units import inch canvas.translate(5.5*inch, 0) canvas.scale(-1.0, 1.0) coords(canvas)
def scale(canvas): canvas.scale(0.75, 0.5) coords(canvas)
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 genkitlabel(canvas, xa, ya, xw, yh, contentlist, test=0, paper_size_no=0): """ """ v('[------genkitlabel()') x = xa y = ya m = .05 * inch h = yh # calc height h -= m * 2 # height - margin w = xw # calc width w -= m * 2 # width - margin v('genkitlabel() ------') v('genkitlabel() xa,ya,xw,yh: %f %f %f %f' % (xa, ya, xw, yh)) v('genkitlabel() m h w : %f %f %f' % (m, h, w)) xo = yo = m # origin canvas.setLineWidth(.01 * inch) canvas.setStrokeColorRGB(.75, .75, .75) global xwidth if (not (xwidth / inch <= 3.50)): cutmark(canvas, x, y, 1, 1) cutmark(canvas, x + xw, y + yh, -1, -1) cutmark(canvas, x, y + yh, 1, -1) cutmark(canvas, x + xw, y, -1, 1) didlogo = False yloc = y + h image_size = 1.2 * inch logo_yloc = yloc - image_size + .2 * inch yrel = 0 for line in contentlist: if (line == '..' or line == '.'): flip = False break v('genkitlabel(): line:%s' % (line)) token = line.split() if len(token) <= 0: continue dowhat = token[0].upper() #--- global flip if (dowhat == 'FLIP'): flip = True elif (dowhat == 'LOGO'): v('LOGO') if (len(token) == 1): # no arg print logo if (paper_size_no == 3): image_size = 1 * inch canvas.drawImage('logo512x512.png', x + m - .75 * inch, logo_yloc, image_size, image_size, preserveAspectRatio=True) else: canvas.drawImage('logo512x512.png', x + m + .1 * inch + 2.4 * inch, logo_yloc, image_size, image_size, preserveAspectRatio=True) else: # print arg arg = token[1] if (len(arg) == 1): # character. make it big if flip: # They said 'LOGO X', so we draw big fat X where the logo should be canvas.saveState() canvas.translate(x + m + .3 * inch, logo_yloc + 1 * inch) canvas.scale(-1, -1) canvas.setFont('Helvetica-Bold', 70) canvas.drawString(0, 0, token[1]) canvas.restoreState() else: # They said 'LOGO X', so we draw big fat X where the logo should be canvas.setFont('Helvetica-Bold', 70) canvas.drawString(x + m - .45 * inch, logo_yloc + .2 * inch, token[1]) else: # Multiple characters if flip: # They said 'LOGO X', so we draw big fat X where the logo should be canvas.saveState() canvas.translate(x + m + .3 * inch, logo_yloc + 1 * inch) canvas.scale(-1, -1) canvas.setFont('Helvetica-Bold', 20) canvas.drawString(.5 * inch, .55 * inch, arg[0]) canvas.drawString(.5 * inch, .30 * inch, arg[1]) canvas.drawString(.5 * inch, .05 * inch, arg[2]) canvas.restoreState() else: # They said 'LOGO X', so we draw big fat X where the logo should be canvas.setFont('Helvetica-Bold', 20) canvas.drawString(x + m - .45 * inch, logo_yloc + .80 * inch, arg[0]) canvas.drawString(x + m - .45 * inch, logo_yloc + .55 * inch, arg[1]) canvas.drawString(x + m - .45 * inch, logo_yloc + .30 * inch, arg[2]) #--- elif (dowhat == 'BARCODE'): yloc = render_barcode(canvas, x, yloc, token[1], ' '.join(token[2:])) v('genkitlabel(): yloc now: %f' % (yloc)) #--- elif (dowhat == 'KEYVAL'): v('KEYVAL Width : ') yloc = render_key_and_value(canvas, x + m + .350 * inch, yloc, token[1], ' '.join(token[2:])) #yinc = .150*inch ## ## v('genkitlabel() --- line:' + line) return line
def render_key_and_value(canvas, x, y, lhs, rhs, wraplen=40): """ render a keyword:value pair. Keyword will be in bold """ global xwidth global yheight yinc = .125 * inch fontsize = 10 v('render_key_and_value(): xwidth:%f yheight:%f ' % (xwidth, yheight)) # little labels get special treatment if (xwidth / inch <= 3.50): v('render_key_and_value(): fixing wraplen for small labels') wraplen = 25 fontsize = 9 if flip: yinc = -.105 * inch else: yinc = .105 * inch lhs += ': ' width = stringWidth(lhs, 'Helvetica-Bold', fontsize) width *= 1.2 if (width < .75 * inch): width = .75 * inch # draw keyword canvas.setFont('Helvetica-Bold', fontsize) if flip: canvas.saveState() canvas.translate(x + 2.45 * inch, y + .25 * inch) canvas.scale(-1, -1) canvas.drawString(0, 0, lhs.upper()) canvas.restoreState() else: canvas.drawString(x, y, lhs.upper()) # draw value canvas.setFont('Helvetica', fontsize) yrel = 0 lines = 0 v('render_key_and_value(): y+yrel: %f' % (y + yrel)) text_line_list = textwrap.wrap(rhs, wraplen) for line in text_line_list: if flip: canvas.saveState() canvas.translate(x + width + 1.00 * inch, y + yrel + .25 * inch) canvas.scale(-1, -1) canvas.drawString(0, 0, line) canvas.restoreState() else: canvas.drawString(x + width, y + yrel, line) yrel -= yinc lines += 1 if ((yheight / inch <= 1.25) and (lines == 3)): break yrel -= yinc / 2 return y + yrel