Example #1
0
 def __init__(self, measure_unit):
     super(ExtendedFlowable, self).__init__()
     self.unit = measure_unit
     self.cursor = Cursor()
     self._elements = []
Example #2
0
class ExtendedFlowable(Flowable, object):

    def __init__(self, measure_unit):
        super(ExtendedFlowable, self).__init__()
        self.unit = measure_unit
        self.cursor = Cursor()
        self._elements = []

    def draw(self):
        """Draw the elements"""
        for element in self._elements:
            position = element['position']
            if self._elements.index(element) > 0:
                last_position = self._elements[
                    self._elements.index(element) - 1]['position']
                self.cursor.move(x=position.x - last_position.x,
                                 y=position.y - last_position.y)
            else:
                self.cursor.move_to(x=position.x, y=position.y)
            element['method'](*element['args'], **element['kwargs'])

    def drawOn(self, canvas, *args, **kwargs):
        Flowable.drawOn(self, canvas, *args, **kwargs)

    @add_element
    def draw_string(self, *args, **kwargs):
        return self._draw_string(*args, **kwargs)

    def _draw_string(self, value=''):
        """
        Use the flowable drawString methods to add a string on the current
        cursor position
        """
        self.canv.drawString(
            self.cursor.x * self.unit,
            self.cursor.y * self.unit,
            value)

    @add_element
    def draw_paragraph(self, *args, **kwargs):
        return self._draw_paragraph(*args, **kwargs)

    def _draw_paragraph(self, text, style, **kwargs):
        """Draw a paragraph"""
        paragraph_style = style.paragraph_style
        p_width, p_height = self._get_paragraph_size(style, **kwargs)

        canvas = self.canv
        paragraph = Paragraph(text, paragraph_style)
        width, height = paragraph.wrapOn(
            self.canv, p_width, p_height)

        if kwargs.get('debug', False) is True:
            paragraph_style.borderWidth = 1
            paragraph_style.borderColor = ColorRGB(0, 0, 0, alpha=50).rgb

        y_pos = self.cursor.y - style.padding_top - style.space_before
        paragraph.drawOn(
            canvas,
            self.cursor.x * self.unit,
            y_pos * self.unit - height,
        )

        self.cursor.move(y=height / self.unit + style.padding_v)
        if height < p_height:
            self.cursor.move(y=(p_height - height) / self.unit)

    def _get_paragraph_size(self, style, **kwargs):
        """Return the paragraph width and height"""
        if 'width' not in kwargs.keys() or kwargs['width'] is None:
            paragraph_width = self._frame.width - (self.cursor.x * self.unit)
        else:
            paragraph_width = kwargs['width'] * self.unit

        if 'height' not in kwargs.keys() or kwargs['height'] is None:
            paragraph_height = 0
        else:
            paragraph_height = kwargs['height'] * self.unit

        return paragraph_width, paragraph_height

    @add_element
    def draw_rectangle(self, *args, **kwargs):
        return self._draw_rectangle(*args, **kwargs)

    def _draw_rectangle(
            self,
            width,
            height,
            bg_color=None,
            stroke_color=None,
            fill=0,
            stroke=0):
        """Draw a rectangle"""
        if stroke:
            self.canv.setStrokeColor(stroke_color.rgb)
        if fill:
            self.canv.setFillColor(bg_color.rgb)
        self.canv.rect(
            self.cursor.x * self.unit,
            self.cursor.y * self.unit - height * self.unit,
            width * self.unit + 0.3,
            height * self.unit + 0.3,
            fill=fill,
            stroke=stroke,
        )

    @add_element
    def draw_grid(self, *args, **kwargs):
        return self._draw_grid(*args, **kwargs)

    def _draw_grid(
            self,
            size,
            width,
            height,
            color=ColorRGB(r=150, g=150, b=150)):
        """Draw the grid"""
        self._draw_rectangle(width, height, stroke_color=color)
        for x in range(int(width) / size):
            self.cursor.move(x=size)
            self._draw_v_line(height, color=color)
        self.cursor.move_to(x=0)
        for y in range(int(height) / size):
            self.cursor.move(y=size)
            self._draw_h_line(width, color=color)

    @add_element
    def draw_h_line(self, *args, **kwargs):
        return self._draw_h_line(*args, **kwargs)

    def _draw_h_line(self, width, color=ColorRGB(r=150, g=150, b=150)):
        """Draw an horizontal line"""
        self.canv.setStrokeColor(color.rgb)
        self.canv.line(
            self.cursor.x * self.unit,
            self.cursor.y * self.unit,
            (self.cursor.x + width) * self.unit,
            self.cursor.y * self.unit)

    @add_element
    def draw_v_line(self, *args, **kwargs):
        return self._draw_h_line(*args, **kwargs)

    def _draw_v_line(self, height, color=ColorRGB(r=150, g=150, b=150)):
        """Draw a vertical line"""
        self.canv.setStrokeColor(color.rgb)
        self.canv.line(
            self.cursor.x * self.unit,
            self.cursor.y * self.unit,
            self.cursor.x * self.unit,
            (self.cursor.y - height) * self.unit)

    @add_element
    def draw_barcode(self, *args, **kwargs):
        return self._draw_barcode(*args, **kwargs)

    def _draw_barcode(self, value, barHeight, barWidth):
        """Draw a barcode"""
        barcode = Drawing()
        if barHeight is None:
            barcode.add(BarcodeCode128(
                value=value,
                barWidth=barWidth
            ))
        else:
            barcode.add(BarcodeCode128(
                value=value,
                barHeight=barHeight,
                barWidth=barWidth
            ))
        barcode.drawOn(
            self.canv,
            self.cursor.x * self.unit,
            self.cursor.y * self.unit,
        )

    @add_element
    def draw_image(self, *args, **kwargs):
        return self._draw_image(*args, **kwargs)

    def _draw_image(self, img_path, width=None, height=None, **kwargs):
        """Draw an image"""
        canvas = self.canv
        img = Image(img_path)
        _width, _height = img.wrapOn(canvas, 0, 0)
        _width = _width * 72. / 300
        _height = _height * 72. / 300
        if width is not None:
            _width = width
        if height is not None:
            _height = height
        canvas.drawImage(
            img_path,
            self.cursor.x * self.unit,
            self.cursor.y * self.unit - _height,
            _width,
            _height,
        )