def draw_guide(canvas, x, y, guide, working_dir, character_info): if guide == Guide.CHARACTER: prefill_character(working_dir, canvas, x + SQUARE_PADDING, \ y - SQUARE_PADDING, \ character_info.character + '0.png') return canvas.setDash(1, 2) canvas.setStrokeColor(CMYKColor(0, 0, 0, 0.2)) if guide == Guide.STAR or guide == Guide.CROSS_STAR: x1 = x y1 = y x2 = x1 + SQUARE_SIZE y2 = y - SQUARE_SIZE canvas.line(x1, y1, x2, y2) canvas.line(x2, y1, x1, y2) if guide == Guide.CROSS or guide == Guide.CROSS_STAR: x1 = x y1 = y - SQUARE_SIZE / 2 x2 = x1 + SQUARE_SIZE y2 = y1 canvas.line(x1, y1, x2, y2) x1 = x + SQUARE_SIZE / 2 y1 = y x2 = x1 y2 = y1 - SQUARE_SIZE canvas.line(x1, y1, x2, y2) canvas.setDash() canvas.setStrokeColor(CMYKColor(0, 0, 0, 1))
def render(self, canvas): if self.dashed: canvas.setDash(1, 2) else: canvas.setDash([], 0) canvas.line(self.coords[0], self.coords[1], self.coords[2], self.coords[3])
def draw_guide(canvas, x, y, guide): canvas.setDash(1, 2) canvas.setStrokeColor(CMYKColor(0, 0, 0, 0.2)) if guide == Guide.STAR: x1 = x y1 = y x2 = x1 + SQUARE_SIZE y2 = y - SQUARE_SIZE canvas.line(x1, y1, x2, y2) canvas.line(x2, y1, x1, y2) elif guide == Guide.CROSS: x1 = x y1 = y - SQUARE_SIZE / 2 x2 = x1 + SQUARE_SIZE y2 = y1 canvas.line(x1, y1, x2, y2) x1 = x + SQUARE_SIZE / 2 y1 = y x2 = x1 y2 = y1 - SQUARE_SIZE canvas.line(x1, y1, x2, y2) canvas.setDash() canvas.setStrokeColor(CMYKColor(0, 0, 0, 1))
def set_dash_style(canvas, spec): try: args = dash_style[spec] except: args = map(int, spec.split("-")) canvas.setDash(args[0], args[1])
def process(self): kw = dict(self.getAttributeValues()) canvas = attr.getManager(self, interfaces.ICanvasManager).canvas if 'width' in kw: canvas.setLineWidth(kw['width']) if 'join' in kw: canvas.setLineJoin(kw['join']) if 'cap' in kw: canvas.setLineCap(kw['cap']) if 'miterLimit' in kw: canvas.setMiterLimit(kw['miterLimit']) if 'dash' in kw: canvas.setDash(kw['dash'])
def printBandOutline(self, canvas, text): """ Draw a dotted rectangle around the entire band, and type a small faded caption at the origin of the band. """ canvas.saveState() canvas.setLineWidth(0.1) canvas.setStrokeColorRGB(0.8, 0.5, 0.7) canvas.setDash(1, 2) canvas.rect(self.x, self.y, self.width, self.height) canvas.setFont("Helvetica", 8) canvas.setFillColor((0.6, 0.8, 0.7)) canvas.drawString(self.x, self.y, text) canvas.restoreState()
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 drawPage(canvas, data, reverse=False): pageWidth, pageHeight = A4 #canvas.drawString(100,pageHeight - 100,"Hello World") canvas.setFillColor(black) # rect (x,y, width,height, fill, stroke) print('Page width %s data length %s' % (pageWidth / cm, len(data))) print('Page height %s ' % (pageHeight / cm)) leftX = 0.0 rightX = 10.5 Y = 1.45 name = [] guideWidth = 0.1 for i in range(math.ceil(len(data) / 2)): # left if len(data) >= i * 2 + 2 or not reverse: if reverse: name = data[i * 2 + 1] else: name = data[i * 2] drawCard(canvas, leftX, Y, name) # right if len(data) >= i * 2 + 2 or reverse: if reverse: name = data[i * 2] else: name = data[i * 2 + 1] drawCard(canvas, rightX, Y, name) # draw cutting line canvas.setLineWidth(0.3) canvas.setDash(1, 2) canvas.line((0) * cm, Y * cm, (guideWidth) * cm, Y * cm) canvas.line((10.5 - guideWidth) * cm, Y * cm, (10.5 + guideWidth) * cm, Y * cm) canvas.line(((pageWidth / cm) - guideWidth) * cm, Y * cm, pageWidth, Y * cm) Y += 6.7 # Card height canvas.setLineWidth(0.3) canvas.setDash(1, 2) canvas.line((0) * cm, Y * cm, (guideWidth) * cm, Y * cm) canvas.line((10.5 - guideWidth) * cm, Y * cm, (10.5 + guideWidth) * cm, Y * cm) canvas.line(((pageWidth / cm) - guideWidth) * cm, Y * cm, pageWidth, Y * cm) canvas.setLineWidth(1) canvas.setDash(1) # draw vertical lines canvas.line((0) * cm, 0, (0) * cm, 1 * cm) canvas.line((0) * cm, pageHeight - (1 * cm), (0) * cm, pageHeight) canvas.line((10.5) * cm, 0, (10.5) * cm, 1 * cm) canvas.line((10.5) * cm, pageHeight - (1 * cm), (10.5) * cm, pageHeight) canvas.line((21) * cm, 0, (21) * cm, 1 * cm) canvas.line((21) * cm, pageHeight - (1 * cm), (21) * cm, pageHeight)
def draw_cells(canvas, printzone): def component_addition(collec_a, collec_b): return [a + b for a, b in zip(collec_a, collec_b)] canvas.saveState() canvas.setLineWidth(LINE_WIDTH) canvas.setDash(4, 4) for row in range(1, LABEL_VCOUNT): canvas.line( *(component_addition(printzone.bottomleft, (0., row * LABEL_VPERIOD)) + component_addition(printzone.bottomright, (0., row * LABEL_VPERIOD)))) if LABEL_VMARGIN: canvas.line(*( component_addition(printzone.bottomleft, (0., row * LABEL_VPERIOD - LABEL_VMARGIN)) + component_addition(printzone.bottomright, (0., row * LABEL_VPERIOD - LABEL_VMARGIN)))) for col in range(1, LABEL_HCOUNT): canvas.line(*( component_addition(printzone.topleft, (col * LABEL_HPERIOD, 0.)) + component_addition(printzone.bottomleft, (col * LABEL_HPERIOD, 0.)) )) if LABEL_HMARGIN: canvas.line(*( component_addition(printzone.topleft, (col * LABEL_HPERIOD - LABEL_HMARGIN, 0.)) + component_addition(printzone.bottomleft, (col * LABEL_HPERIOD - LABEL_HMARGIN, 0.)))) canvas.restoreState()
def create_badges(data): # canvas.translate(0, section_height) for batch in make_batches(data, 2): # fold & cut helpers canvas.setDash(6, 3) canvas.line(width / 2.0, 0, width / 2.0, height) # vertical line canvas.setDash(1, 0) canvas.line(0, height / 2.0, width, height / 2.0) # horizontal canvas.setDash(1, 0) draw_margins() canvas.translate(0, height / 2.0 + margin) for pos, (ticket_index, attendee) in enumerate(batch, 1): write_qr_code(attendee, ticket_index) canvas.translate(width / 2.0 + margin, 0) write_badge(attendee) canvas.translate(-width / 2.0 - margin, -height / 2.0 - margin) canvas.showPage( ) # finish the page, next statements should go next page canvas.save()
def draw_margins(): # margins canvas.setDash(1, 4) # main canvas.setDash(1, 0) # canvas.line(page_margin_left, 0, page_margin_left, height) # canvas.line(width - page_margin_right, 0, width - page_margin_right, height) # canvas.line(0, page_margin_bottom, width, page_margin_bottom) # canvas.line(0, height - page_margin_top, width, height - page_margin_top) # page border canvas.line(0, 0, width, 0) canvas.line(0, 0, 0, height) canvas.line(0, height, width, height) canvas.line(width, 0, width, height) # halves canvas.line(0, height / 2.0, width, height / 2.0) canvas.line(width / 2.0, 0, width / 2.0, height) canvas.setDash(1, 4) canvas.line(width / 2.0 - margin, 0, width / 2.0 - margin, height) canvas.line(width / 2.0 + margin, 0, width / 2.0 + margin, height) canvas.line(0, height / 2.0 + margin, width, height / 2.0 + margin) canvas.line(0, height / 2.0 - margin, width, height / 2.0 - margin)
def draw(self, pmlOp, pageNr, canvas, pe): canvas.setDash(pmlOp.dashArray, pmlOp.phase)
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 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 drawCard(canvas, cardX, cardY, data=[]): cardWidth, cardHeight = (10.5, 6.7) eventIndent = (0.4) eventWidth, eventHeight = (cardWidth - (eventIndent * 2), 1) canvas.setFillColor(HexColor(0x000000)) canvas.setStrokeColor(HexColor(0x000000)) canvas.setDash(1) # logo x = cardX + eventIndent y = cardHeight + cardY - eventIndent - 1 canvas.drawImage('images/IIIF-logo-500w.png', x=x * cm, y=(y * cm), width=1 * cm, height=1 * cm, preserveAspectRatio=True) # Card rect canvas.setLineWidth(0.5) #canvas.rect(cardX * cm,cardY*cm,cardWidth * cm,cardHeight * cm,fill=False, stroke=True) # event rect canvas.setLineWidth(1) canvas.rect((cardX + eventIndent) * cm, (cardY + eventIndent) * cm, eventWidth * cm, eventHeight * cm, fill=True, stroke=True) if data: #canvas.setFont("Open Sans", 3*cm) # 5.5cm # Pronoum print('Pronoum') safeFont(canvas, 'Times-Bold', 16, (cardWidth - 4 - 0.8), data[1], cm) canvas.drawCentredString((cardX + (cardWidth / 2)) * cm, (cardY + 5.3) * cm, data[1]) # name print('Name') safeFont(canvas, 'Times-Bold', 36, cardWidth, data[0], cm) canvas.drawCentredString((cardX + (cardWidth / 2)) * cm, (cardY + 3.8) * cm, data[0]) # company safeFont(canvas, 'Times-Bold', 20, cardWidth, data[2], cm) canvas.drawCentredString((cardX + (cardWidth / 2)) * cm, (cardY + 2.8) * cm, data[2]) # event canvas.setFillColor(HexColor("#FFFFFF")) safeFont(canvas, 'Times-Bold', 16, cardWidth - 0.8, data[4], cm) canvas.drawCentredString( (cardX + (cardWidth / 2)) * cm, (cardY + eventIndent + (eventHeight / 2) - 0.2) * cm, data[4]) if data[3] == 'Volunteer': canvas.setFillColor(HexColor("#50f442")) canvas.setStrokeColor(HexColor("#50f442")) canvas.setLineWidth(1) canvas.rect((cardX + eventIndent) * cm, (cardY + eventIndent + eventHeight + 0.04) * cm, (eventWidth) * cm, 0.7 * cm, fill=True, stroke=True) #canvas.setFillColor(HexColor("#FFFFFF")) canvas.setFillColor(HexColor(0x000000)) safeFont(canvas, 'Times-Bold', 16, cardWidth - 0.8, "Volunteer", cm) canvas.drawCentredString((cardX + (cardWidth / 2)) * cm, (cardY + eventIndent + eventHeight + (eventHeight / 2) - 0.3) * cm, "Volunteer") canvas.setFillColor(HexColor(0x000000)) canvas.setStrokeColor(HexColor(0x000000))
def make_a_table(canvas, ncol, nrow, entries, str_index): width, height = A4 cell_size = 16 * mm table_data = [] for i in range(nrow): row = [] for j in range(ncol): if 1 < j < ncol - 1: row.append('') else: try: row.append(entries[i]) except: row.append('') table_data.append(row) kanji_tbl_style = [] kanji_tbl_style.append(('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black)) kanji_tbl_style.append(('BOX', (0, 0), (-1, -1), 0.25, colors.black)) for i in range(ncol): kanji_tbl_style.append(('ALIGN', (i, 0), (i, -1), 'CENTER')) kanji_tbl_style.append(('VALIGN', (i, 0), (i, -1), 'BOTTOM')) kanji_tbl_style.append(('FONT', (i, 0), (i, -1), 'Stroke', 36)) if i == ncol - 1: kanji_tbl_style.append(('TEXTCOLOR', (i, 0), (i, -1), NAVY)) elif i < 2: kanji_tbl_style.append(('TEXTCOLOR', (i, 0), (i, -1), GRAY)) kanji_tbl = Table(table_data, colWidths=cell_size, rowHeights=cell_size) kanji_tbl.setStyle(TableStyle(kanji_tbl_style)) kanji_tbl.wrapOn(canvas, width, height) table_x, table_y = 12 * mm, 21 * mm kanji_tbl.drawOn(canvas, table_x, table_y) kanji_info = [] info_tbl_style = [] info_style = ParagraphStyle( name='Info', fontName='Hiragino', fontSize=7, ) for i in range(nrow): try: text = Paragraph(kanji_lookup[entries[i]], info_style) kanji_info.append([text]) except: kanji_info.append(['']) info_tbl_style.append(('VALIGN', (0, 0), (-1, -1), 'TOP')) info_tbl = Table(kanji_info, colWidths=50 * mm, rowHeights=cell_size) info_tbl.setStyle(TableStyle(info_tbl_style)) info_tbl.wrapOn(canvas, width, height) info_tbl.drawOn(canvas, table_x + cell_size * ncol, table_y) for i in range(nrow): coord_trans = (table_x + cell_size * ncol + 50 * mm, table_y + cell_size * i) if i % 2 == 1: char_x = table_x + cell_size * ncol + 5 * mm else: char_x = table_x + cell_size * ncol + 22 * mm coord_char = (char_x, table_y + cell_size * i + 2 * mm) try: kanji = entries[nrow - i - 1] canvas.setFillColor(BLACK) canvas.setFont('Times-Italic', 8) canvas.drawRightString(*coord_trans, trans_lookup[kanji]) if kanji in font_lookup['bone']: canvas.setFillColor(GREEN30) canvas.setFont('Bone', 55) elif kanji in font_lookup['tenbun']: canvas.setFillColor(RED30) canvas.setFont('Tenbun', 55) else: continue canvas.drawString(*coord_char, kanji) except: pass sep_x = table_x + cell_size * ncol + 0.5 * mm canvas.setLineWidth(0.1 * mm) canvas.line(sep_x, table_y, sep_x, table_y + cell_size * nrow) canvas.setFillColor(LIGHTGRAY) rect_x, rect_y = table_x, height - 16 * mm canvas.roundRect(rect_x, rect_y, 70 * mm, 10 * mm, 1 * mm, fill=1, stroke=0) canvas.setFont('Hiragino', 12) canvas.setFillColor(BLACK) canvas.drawString(rect_x + 2 * mm, rect_y + 3 * mm, "Joytan Kanji Practice | 漢字練習帳") # Name with underline canvas.setLineWidth(0.1 * mm) canvas.setFillColor(BLACK) canvas.setFont('Hiragino', 10) name_x, name_y = width - 90 * mm, height - 14 * mm canvas.drawString(name_x, name_y, "名前:") canvas.line(name_x, name_y - 2 * mm, name_x + 70 * mm, name_y - 2 * mm) # Left footer canvas.setFont('Helvetica-Bold', 10) coord_msg = (table_x, table_y - 5 * mm) canvas.drawString( *coord_msg, "Support our project: https://kokimame.github.io/joytan/") coord_index = (table_x, table_y - 12 * mm) canvas.drawString(*coord_index, "%s | © Joytan" % str_index) # Right footer coord_l1 = (width - 20 * mm, table_y - 5 * mm) coord_l2 = (width - 20 * mm, table_y - 10 * mm) coord_l3 = (width - 20 * mm, table_y - 13 * mm) canvas.setFont('Hiragino', 9) canvas.drawRightString(*coord_l1, "【部首】/画数/学年 オンヨミ くんよみ") canvas.setFont('Hiragino', 8) canvas.drawRightString( *coord_l2, "【radical】/#stroke/grade Onyomi(Katakana) Kunyomi (Hiragana)") canvas.setFont('Times-Italic', 7) canvas.drawRightString(*coord_l3, "* Rough kanji-wise translation") # Additional lines canvas.setDash([0.1 * mm, 1.2 * mm]) canvas.setLineCap(1) # Dotted vertical lines for i in range(ncol): x = table_x + cell_size / 2 + cell_size * i canvas.line(x, table_y, x, table_y + nrow * cell_size) # Dotted horizontal lines for i in range(nrow): trans_y = table_y + cell_size / 2 + cell_size * i canvas.line(table_x, trans_y, table_x + ncol * cell_size, trans_y) # Separation between the Info panel for i in range(nrow + 1): x = table_x + cell_size * ncol trans_y = table_y + cell_size * i canvas.line(x, trans_y, x + 50 * mm, trans_y) canvas.showPage()
def gerafolha(intmarg, extmarg, infmarg, supmarg): global numos canvas.setLineWidth(0.6 * mm) canvas.line(intmarg * mm, infmarg * mm, intmarg * mm, (297 - supmarg) * mm) # Desenhor da borda interna canvas.line(intmarg * mm, infmarg * mm, (210 - extmarg) * mm, infmarg * mm) # Desenhor da borda inferior canvas.line((210 - extmarg) * mm, infmarg * mm, (210 - extmarg) * mm, 287 * mm) # Desenhor da borda externa canvas.line((210 - extmarg) * mm, (297 - supmarg) * mm, intmarg * mm, (297 - supmarg) * mm) # Desenhor da borda superior canvas.line((210 - extmarg) * mm, 280 * mm, intmarg * mm, 280 * mm) # Linha inferir do cabeçalho for linha in range(1, 34): # Linhas para escrita altura = 280 - (8 * linha) canvas.setLineWidth(0.254 * mm) canvas.line(intmarg * mm, altura * mm, (210 - extmarg) * mm, altura * mm) if numos % 100 == 0: canvas.setFont('Garamond-Negrito', 18) else: canvas.setFont('Garamond-Italico', 18) canvas.drawCentredString((intmarg + 12.5) * mm, (altura + 2) * mm, str(numos)) numos += 1 canvas.setFont('Times-Regular', 18) canvas.drawCentredString((intmarg + 157.5) * mm, (altura + 2) * mm, "/ /") canvas.setLineWidth(0.254 * mm) canvas.setDash(1, 1) canvas.line((intmarg + 25) * mm, 16 * mm, (intmarg + 25) * mm, 287 * mm) # Borda direita Num. O.S. canvas.line((intmarg + 70) * mm, 16 * mm, (intmarg + 70) * mm, 287 * mm) # Borda direita Cliente canvas.line((intmarg + 115) * mm, 16 * mm, (intmarg + 110) * mm, 287 * mm) # Borda direita Motor canvas.line((intmarg + 145) * mm, 16 * mm, (intmarg + 145) * mm, 287 * mm) # Borda direita Montador canvas.line((intmarg + 170) * mm, 16 * mm, (intmarg + 170) * mm, 287 * mm) # Borda direita Data canvas.setDash(1, 0) canvas.setFont('Times-Regular', 18) canvas.drawCentredString((intmarg + 12.5) * mm, 281.5 * mm, "OS") canvas.drawCentredString((intmarg + 47.5) * mm, 281.5 * mm, "Cliente") canvas.drawCentredString((intmarg + 90) * mm, 281.5 * mm, "Motor") canvas.drawCentredString((intmarg + 127.5) * mm, 281.5 * mm, "Montador") canvas.drawCentredString((intmarg + 157.5) * mm, 281.5 * mm, "Data") canvas.drawCentredString((intmarg + 177.5) * mm, 281.5 * mm, "Ass.") canvas.setFont('Times-Regular', 12) canvas.drawCentredString((intmarg + 85) * mm, 10 * mm, "Página _____") # ----------- IMPRESSÃO DO CARIMBO DE TEMPO E NOME DE USUÁRIO ----------- canvas.setFont('Consola', 8) canvas.saveState() canvas.rotate(90) if intmarg > extmarg: canvas.drawString( infmarg * mm, -(intmarg - 5) * mm, str("{} - {}".format(time.time(), getpass.getuser()))) else: canvas.drawString( infmarg * mm, -(210 - extmarg + 5) * mm, str("{} - {}".format(time.time(), getpass.getuser()))) canvas.restoreState() canvas.showPage() # Adiciona uma nova página
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()