Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    def _draw_single_background(self, canvas, x, margins, width, height):
        canvas.saveState()

        clipping_mask = canvas.beginPath()
        clipping_mask.roundRect(
            x + margins[Border.LEFT], margins[Border.BOTTOM],
            width - margins[Border.RIGHT] - margins[Border.LEFT],
            height - margins[Border.TOP] - margins[Border.BOTTOM],
            self.BACKGROUND_CORNER_DIAMETER)
        canvas.clipPath(clipping_mask, stroke=0, fill=0)

        # get optimum background orientation
        background_orientation = best_orientation(self.background_image_path,
                                                  width, height)
        if background_orientation == Orientation.TURN90:
            canvas.rotate(90)
            canvas.translate(0, -self.WIDTH * 2)
            canvas.drawImage(self.background_image_path,
                             0,
                             0,
                             width=height,
                             height=width,
                             mask=None)
        else:
            canvas.drawImage(self.background_image_path,
                             x,
                             0,
                             width=width,
                             height=height,
                             mask=None)

        canvas.restoreState()
    def _draw_single_background(self,
                                canvas,
                                x,
                                margins,
                                width,
                                height,
                                orientation=Orientation.NORMAL):
        canvas.saveState()

        canvas.setFillColor("white")
        clipping_mask = canvas.beginPath()

        if orientation == Orientation.TURN90:
            clipping_mask.roundRect(
                x + margins[Border.BOTTOM],
                margins[Border.LEFT],
                width - margins[Border.TOP] - margins[Border.BOTTOM],
                height - margins[Border.RIGHT] - margins[Border.LEFT],
                self.BACKGROUND_CORNER_DIAMETER,
            )
        else:
            clipping_mask.roundRect(
                x + margins[Border.LEFT],
                margins[Border.BOTTOM],
                width - margins[Border.RIGHT] - margins[Border.LEFT],
                height - margins[Border.TOP] - margins[Border.BOTTOM],
                self.BACKGROUND_CORNER_DIAMETER,
            )
        canvas.clipPath(clipping_mask, stroke=0, fill=1)

        if self.background_image_path is not None:
            canvas.drawImage(self.background_image_path,
                             x,
                             0,
                             width=width,
                             height=height,
                             mask=None)

        canvas.restoreState()
 def pageCanvas(self, canvas, doc):
     """
     Forming of the page layout (backround color...)
     """
     canvas.saveState()
     canvas.setFont(self.FONTNAME, self.FONTSIZE)
     canvas.setFillColorRGB(
         self.BCKGRDCOLOR[0], self.BCKGRDCOLOR[1], self.BCKGRDCOLOR[2])
     canvas.rect(0, 0, self.WIDTH, self.HEIGHT, stroke=0, fill=1)
     canvas.restoreState()
     canvas.saveState()
     p = canvas.beginPath()
     p.rect(0, self.HEIGHT - 80, self.WIDTH, 80)
     canvas.clipPath(p, stroke=0)
     canvas.linearGradient(
         0, self.HEIGHT - 80, self.WIDTH, self.HEIGHT - 80,
         (black, blue), extend=False)
     canvas.restoreState()
     canvas.saveState()
     canvas.setFillColorRGB(1, 1, 1)
     canvas.setFont(self.FONTNAME, self.FONTSIZE)
     canvas.drawString(40, 714, "%s.%s:%s" % (self.PASSAGE[0], 
                     self.PASSAGE[1], self.PASSAGE[2]))
     canvas.restoreState()
Example #6
0
    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()
Example #7
0
    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()
Example #8
0
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()
Example #9
0
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()
Example #10
0
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()
Example #11
0
    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()