Esempio n. 1
0
    def draw_y_axis(self, zero=True):
        # Draw y axis ticks
        self.y_array = [(self.y_range[0], self.origin.y)]
        try:
            y_delta = self.height / (float(self.y_range[1] - self.y_range[0]) / float(self.frequency[1]))
        except ZeroDivisionError:
            y_delta = self.height / 2.0
        x_delta = 3
        tick_y = self.origin.y
        j = self.y_range[0]
        k = 0
        self.draw_tick(self.origin.x, tick_y, self.origin.x - x_delta, tick_y)
        if zero:
            self.draw_y_label(j, k, self.origin.x - x_delta, tick_y)
        while j < self.y_range[1]:
            j += self.frequency[1]
            tick_y -= y_delta
            self.y_array.append((j, tick_y))
            self.draw_tick(self.origin.x, tick_y, self.origin.x - x_delta, tick_y)
            self.draw_y_label(j, k, self.origin.x - x_delta, tick_y)
            k += 1

        # Draw axis lines
        cursor1 = PDFCursor(self.origin.x, tick_y)
        if self.axis:
            yaxis = PDFLine(self.session, self.page, cursor1, self.origin, self.base_color, stroke="solid")
            yaxis._draw()
Esempio n. 2
0
    def draw_data(self):
        if self.legend is not None:
            self._draw_legend_title()

        i = 0
        for series in self.data:
            if self.legend is not None:
                self._draw_legend_line(i, series.keys()[0])
            series = series.values()[0]
            self._set_color(i)
            self.line = LinearRegressionLine()
            i += 1

            cursors = []
            for value in series:
                cursor = self.get_coord(value)
                cursors.append(cursor)
                self.line.add_data(value)
            self._draw_dots(cursors)

            if self.linear_regression:
                self.line.calculate_line()
                cursor1, cursor2 = self.line.get_cursors(cursors)
                trend = PDFLine(self.session, self.page, cursor1, cursor2)
                trend._draw()
                if self.linear_regression_equation:
                    text = self.line.get_equation()
                    text_width = self.session.parent.document.font._string_width(text)
                    text_height = self.session.parent.document.font.font_size * 1.2
                    x = cursor2.x + (-text_width)
                    y = self.line._get_y_at_x(x) + text_height
                    PDFText(self.session, self.page, text, cursor=PDFCursor(x, y))

        if self.legend is not None:
            self._draw_legend_box()
Esempio n. 3
0
 def draw_tick(self, x1, y1, x2, y2):
     x = PDFCursor(x1, y1)
     y = PDFCursor(x2, y2)
     if self.axis:
         tick = PDFLine(self.session, self.page, x, y, self.base_color,
                        "solid")
         tick._draw()
Esempio n. 4
0
    def draw_x_axis(self, zero=True):
        # Draw x axis ticks
        self.x_array = [(0, self.origin.x)]
        try:
            x_delta = self.width / (float(self.x_range[1] - self.x_range[0]) / float(self.frequency[0]))
        except ZeroDivisionError:
            x_delta = self.width / 2.0
        self.x_delta = x_delta
        y_delta = 3
        tick_x = self.origin.x
        i = self.x_range[0]
        k = 0
        self.draw_tick(tick_x, self.origin.y, tick_x, self.origin.y + y_delta)
        if zero:
            self.draw_x_label(i, k, tick_x, self.origin.y)
        while i < self.x_range[1]:
            i += self.frequency[0]
            tick_x += x_delta
            self.x_array.append((i, tick_x))
            self.draw_tick(tick_x, self.origin.y, tick_x, self.origin.y + y_delta)
            self.draw_x_label(i, k, tick_x, self.origin.y)
            k += 1

        cursor2 = PDFCursor(tick_x, self.origin.y)
        if self.axis:
            xaxis = PDFLine(self.session, self.page, self.origin, cursor2, self.base_color, stroke="solid")
            xaxis._draw()
Esempio n. 5
0
    def draw_y_axis(self, zero=True):
        # Draw y axis ticks
        self.y_array = [(self.y_range[0], self.origin.y)]
        try:
            y_delta = self.height / (float(self.y_range[1] - self.y_range[0]) /
                                     float(self.frequency[1]))
        except ZeroDivisionError:
            y_delta = self.height / 2.0
        x_delta = 3
        tick_y = self.origin.y
        j = self.y_range[0]
        k = 0
        self.draw_tick(self.origin.x, tick_y, self.origin.x - x_delta, tick_y)
        if zero:
            self.draw_y_label(j, k, self.origin.x - x_delta, tick_y)
        while j < self.y_range[1]:
            j += self.frequency[1]
            tick_y -= y_delta
            self.y_array.append((j, tick_y))
            self.draw_tick(self.origin.x, tick_y, self.origin.x - x_delta,
                           tick_y)
            self.draw_y_label(j, k, self.origin.x - x_delta, tick_y)
            k += 1

        # Draw axis lines
        cursor1 = PDFCursor(self.origin.x, tick_y)
        if self.axis:
            yaxis = PDFLine(self.session,
                            self.page,
                            cursor1,
                            self.origin,
                            self.base_color,
                            stroke="solid")
            yaxis._draw()
Esempio n. 6
0
    def draw_x_axis(self, zero=True):
        # Draw x axis ticks
        self.x_array = [(0, self.origin.x)]
        try:
            x_delta = self.width / (float(self.x_range[1] - self.x_range[0]) /
                                    float(self.frequency[0]))
        except ZeroDivisionError:
            x_delta = self.width / 2.0
        self.x_delta = x_delta
        y_delta = 3
        tick_x = self.origin.x
        i = self.x_range[0]
        k = 0
        self.draw_tick(tick_x, self.origin.y, tick_x, self.origin.y + y_delta)
        if zero:
            self.draw_x_label(i, k, tick_x, self.origin.y)
        while i < self.x_range[1]:
            i += self.frequency[0]
            tick_x += x_delta
            self.x_array.append((i, tick_x))
            self.draw_tick(tick_x, self.origin.y, tick_x,
                           self.origin.y + y_delta)
            self.draw_x_label(i, k, tick_x, self.origin.y)
            k += 1

        cursor2 = PDFCursor(tick_x, self.origin.y)
        if self.axis:
            xaxis = PDFLine(self.session,
                            self.page,
                            self.origin,
                            cursor2,
                            self.base_color,
                            stroke="solid")
            xaxis._draw()
Esempio n. 7
0
 def _draw_legend_line(self, index, series_name):
     line_height = self.session.parent.document.font.font_size
     end = PDFCursor(self.legend_data_start.x + 15, self.legend_data_start.y)
     line = PDFLine(self.session, self.page, self.legend_data_start, end, color=self.line_colors[index])
     line._draw()
     end.x_plus(10)
     end.y_plus(0.25 * line_height)
     text = PDFText(self.session, self.page, series_name, cursor=end)
     self.legend_data_start.y_plus(1.75 * line_height)
Esempio n. 8
0
 def _draw_legend_line(self, index, series_name):
     line_height = self.session.parent.document.font.font_size
     end = PDFCursor(self.legend_data_start.x + 15,
                     self.legend_data_start.y)
     line = PDFLine(self.session,
                    self.page,
                    self.legend_data_start,
                    end,
                    color=self.line_colors[index])
     line._draw()
     end.x_plus(10)
     end.y_plus(0.25 * line_height)
     text = PDFText(self.session, self.page, series_name, cursor=end)
     self.legend_data_start.y_plus(1.75 * line_height)
Esempio n. 9
0
 def _set_borders(self):
     self._get_points()
     self._get_border_formats()
     if self.style["bottom"] is not None:
         self.bottom_line = PDFLine(
             self.table.session,
             self.table.page,
             self.point_sw,
             self.point_se,
             self.format["bottom_color"],
             self.style["bottom"],
             self.size["bottom"],
         )
     if self.style["right"] is not None:
         self.right_line = PDFLine(
             self.table.session,
             self.table.page,
             self.point_se,
             self.point_ne,
             self.format["right_color"],
             self.style["right"],
             self.size["right"],
         )
     if self.style["left"] is not None:
         self.left_line = PDFLine(
             self.table.session,
             self.table.page,
             self.point_sw,
             self.point_nw,
             self.format["left_color"],
             self.style["left"],
             self.size["left"],
         )
     if self.style["top"] is not None:
         self.top_line = PDFLine(
             self.table.session,
             self.table.page,
             self.point_ne,
             self.point_nw,
             self.format["top_color"],
             self.style["top"],
             self.size["top"],
         )
Esempio n. 10
0
    def draw_data(self):
        if self.legend is not None:
            self._draw_legend_title()

        i = 0
        for series in self.data:
            if self.legend is not None:
                self._draw_legend_line(i, series.keys()[0])
            series = series.values()[0]
            self._set_color(i)
            self.line = LinearRegressionLine()
            i += 1

            cursors = []
            for value in series:
                cursor = self.get_coord(value)
                cursors.append(cursor)
                self.line.add_data(value)
            self._draw_dots(cursors)

            if self.linear_regression:
                self.line.calculate_line()
                cursor1, cursor2 = self.line.get_cursors(cursors)
                trend = PDFLine(self.session, self.page, cursor1, cursor2)
                trend._draw()
                if self.linear_regression_equation:
                    text = self.line.get_equation()
                    text_width = self.session.parent.document.font._string_width(
                        text)
                    text_height = self.session.parent.document.font.font_size * 1.2
                    x = cursor2.x + (-text_width)
                    y = self.line._get_y_at_x(x) + text_height
                    PDFText(self.session,
                            self.page,
                            text,
                            cursor=PDFCursor(x, y))

        if self.legend is not None:
            self._draw_legend_box()
Esempio n. 11
0
 def _set_borders(self):
     self._get_points()
     self._get_border_formats()
     if self.style['bottom'] is not None:
         self.bottom_line = PDFLine(self.table.session, self.table.page,
                                    self.point_sw, self.point_se,
                                    self.format['bottom_color'],
                                    self.style['bottom'],
                                    self.size['bottom'])
     if self.style['right'] is not None:
         self.right_line = PDFLine(self.table.session, self.table.page,
                                   self.point_se, self.point_ne,
                                   self.format['right_color'],
                                   self.style['right'], self.size['right'])
     if self.style['left'] is not None:
         self.left_line = PDFLine(self.table.session, self.table.page,
                                  self.point_sw, self.point_nw,
                                  self.format['left_color'],
                                  self.style['left'], self.size['left'])
     if self.style['top'] is not None:
         self.top_line = PDFLine(self.table.session, self.table.page,
                                 self.point_ne, self.point_nw,
                                 self.format['top_color'],
                                 self.style['top'], self.size['top'])
Esempio n. 12
0
 def draw_tick(self, x1, y1, x2, y2):
     x = PDFCursor(x1, y1)
     y = PDFCursor(x2, y2)
     if self.axis:
         tick = PDFLine(self.session, self.page, x, y, self.base_color, "solid")
         tick._draw()
Esempio n. 13
0
class PDFCell(object):
    def __init__(self, table, row_index, column_index, text_cursor,
                 border_cursor):
        self.table = table
        self.font = self.table.font
        self.row_index = row_index
        self.column_index = column_index

        self.text_cursor = text_cursor
        self.border_cursor = border_cursor

        self.height = 0
        self.width = 0
        self.max_width = 0

        self.line_space = 2
        self.text = ''

    def __repr__(self):
        return '(%s, %s)' % (self.row_index, self.column_index)

    # Text
    def _set_text(self, text):
        self.text = text
        if hasattr(self, 'format'):
            numf = self.format['num_format']
            if numf is not None:
                precision = numf[1]
                numf = numf[0]
                if precision <= 0:
                    self.text = str(int(self.text))
                else:
                    self.text = '%0.*f' % (precision, float(self.text))
                if 'euro' in numf:
                    self.text = self.text.replace('.', ',')
                    self.text = '%s%s' % (chr(128), self.text)
                if any(s in numf for s in ['comma', ',']):
                    self.text = str('{:,}'.format(int(self.text)))
                if any(s in numf for s in ['percent', '%']):
                    self.text = '%s %' % self.text
                if any(s in numf for s in ['$', 'money', 'dollar']):
                    self.text = '$%s' % self.text

    def _draw_text(self):
        if self.text == '' or self.text is None:
            self.text_cursor.x_plus(self.max_width)
        elif hasattr(self, 'text_list'):
            self.text_cursor.y_plus(-self.padding_bottom -
                                    ((len(self.text_list) - 1) *
                                     (self.line_size + self.line_space)) -
                                    self.diff_bottom)
            i = 0
            for item in self.text_list:
                self.text_cursor.x_plus(self.padding_left +
                                        self.width_diff_l[i])
                self.text_object = PDFText(self.table.session, self.table.page,
                                           item, self.font, self.text_color,
                                           self.text_cursor)
                self.text_cursor.x_plus(-self.font._string_width(item) -
                                        self.width_diff_l[i])
                self.text_cursor.y_plus(self.line_space + self.line_size)
                i += 1
            self.text_cursor.x_plus(
                self.font._string_width(self.text_list[-1]) +
                self.padding_right + self.width_diff_right +
                self.width_diff_l[-1])
            self.text_cursor.y_plus(self.padding_bottom + self.diff_bottom -
                                    self.line_space - self.line_size)
        else:
            self.text_cursor.y_plus(-(self.padding_bottom + self.diff_bottom))
            self.text_cursor.x_plus(self.padding_left + self.width_diff_left)
            self.text_object = PDFText(self.table.session, self.table.page,
                                       self.text, self.font, self.text_color,
                                       self.text_cursor)
            self.text_cursor.x_plus(self.padding_right + self.width_diff_right)
            self.text_cursor.y_plus(self.padding_bottom + self.diff_bottom)

    def _set_text_padding(self):
        if self.format['padding'] is not False:
            self.padding_top = self.padding_right = self.padding_left = self.padding_bottom = self.format[
                'padding']
        else:
            self.padding_top = self.format['padding_top']
            self.padding_right = self.format['padding_right']
            self.padding_left = self.format['padding_left']
            self.padding_bottom = self.format['padding_bottom']

        self.width = (self.text_width + self.padding_right + self.padding_left)

        self.height = (self.line_size + self.padding_top + self.padding_bottom)

    # Format
    def _set_format(self, format):
        self.format = format
        self.font = self.format['font']
        self.text_wrap = self.format['text_wrap']
        self.text_color = self.format['text_color']
        if self.text != '' and self.text is not None:
            self.text_width = self.font._string_width(self.text)
            self._set_text(self.text)
        else:
            self.text_width = 0
        if self.font is not None:
            self.line_size = self.font.line_size
        else:
            self.line_size = 0
        self._set_text_padding()

    # Borders
    def _get_points(self):
        self.point_nw = self.border_cursor.copy()
        self.point_sw = self.border_cursor.copy()
        self.point_se = self.border_cursor.copy()
        self.point_ne = self.border_cursor.copy()

        # cursor start is NW point
        self.point_sw.y_plus(self.max_height)
        self.point_ne.x_plus(self.max_width)
        self.point_se.x_plus(self.max_width)
        self.point_se.y_plus(self.max_height)

        self.border_cursor = self.point_ne

    def _get_border_formats(self):
        self.style = {}
        self.size = {}
        if self.format['border'][0] is not None:
            style, size = self.format['border']
            self.style['left'] = self.style['right'] = self.style[
                'top'] = self.style['bottom'] = style
            self.size['left'] = self.size['right'] = self.size[
                'top'] = self.size['bottom'] = size
        else:
            self.style['right'], self.size['right'] = self.format['right']
            self.style['left'], self.size['left'] = self.format['left']
            self.style['top'], self.size['top'] = self.format['top']
            self.style['bottom'], self.size['bottom'] = self.format['bottom']

    def _set_borders(self):
        self._get_points()
        self._get_border_formats()
        if self.style['bottom'] is not None:
            self.bottom_line = PDFLine(self.table.session, self.table.page,
                                       self.point_sw, self.point_se,
                                       self.format['bottom_color'],
                                       self.style['bottom'],
                                       self.size['bottom'])
        if self.style['right'] is not None:
            self.right_line = PDFLine(self.table.session, self.table.page,
                                      self.point_se, self.point_ne,
                                      self.format['right_color'],
                                      self.style['right'], self.size['right'])
        if self.style['left'] is not None:
            self.left_line = PDFLine(self.table.session, self.table.page,
                                     self.point_sw, self.point_nw,
                                     self.format['left_color'],
                                     self.style['left'], self.size['left'])
        if self.style['top'] is not None:
            self.top_line = PDFLine(self.table.session, self.table.page,
                                    self.point_ne, self.point_nw,
                                    self.format['top_color'],
                                    self.style['top'], self.size['top'])

    def _draw_borders(self):
        if self.style['bottom'] is not None:
            self.bottom_line._draw()
        if self.style['right'] is not None:
            self.right_line._draw()
        if self.style['left'] is not None:
            self.left_line._draw()
        if self.style['top'] is not None:
            self.top_line._draw()

    # Fill
    def _draw_fill(self):
        if self.format['fill_color'] is not None:
            if isinstance(self.format['fill_color'], PDFColor):
                rect = PDFRectangle(self.table.session,
                                    self.table.page,
                                    self.point_nw,
                                    self.point_se,
                                    fill_color=self.format['fill_color'],
                                    style='F')
                rect._draw()
            else:
                raise Exception("Color %s is not a PDFColor" %
                                self.format['fill_color'])

    # Finishing
    def _compile(self):
        if hasattr(self, 'format'):
            if self.text_wrap is not False:
                self.text_wrap = self.format['text_wrap']
        else:
            self.text = ''
            self.text_width = 1
            self.line_size = 1
            self.format = PDFCellFormat(None, None)
            self.text_wrap = False
            self._set_text_padding()

    def _finish(self):
        if self.text_wrap is True and self.width > self.max_width:
            self.text_list = self.text.split('\n')
            self.height = len(self.text_list) * (
                self.line_size + self.padding_bottom +
                self.padding_top) + self.diff_bottom + self.diff_top
            for item in self.text_list:
                w = self.font._string_width(item)
                self.width = 0
                if w > self.width:
                    self.width = w
            self.text_wrap = False
            self.table._compile()

    def _advance_initial(self):
        self.text_cursor.y_plus(self.max_height - self.padding_bottom)

    def _set_max_width(self, value):
        self.max_width = value
        self.width = self.font._string_width(
            self.text) + self.padding_right + self.padding_left
        self._set_side_diffs()

    def _set_side_diffs(self):
        if hasattr(self, 'text_list'):
            self.width_diff_l = []
            for item in self.text_list:
                textwidth = self.font._string_width(item)
                width_diff = self.max_width - self.padding_right - self.padding_left - textwidth
                if self.format['align'] == 'left':
                    self.width_diff_l.append(0)
                    self.width_diff_right = width_diff
                elif self.format['align'] == 'right':
                    self.width_diff_l.append(width_diff)
                    self.width_diff_right = 0
                else:
                    self.width_diff_l.append(int(width_diff / 2.0))
                    self.width_diff_right = width_diff - int(width_diff / 2.0)
        else:
            width_diff = self.max_width - self.width
            if self.format['align'] == 'left':
                self.width_diff_left = 0
                self.width_diff_right = width_diff
            elif self.format['align'] == 'right':
                self.width_diff_right = 0
                self.width_diff_left = width_diff
            else:
                self.width_diff_left = int(width_diff / 2.0)
                self.width_diff_right = width_diff - self.width_diff_left

    def _set_max_height(self, value):
        self.max_height = value
        self._set_vertical_diffs()

    def _set_vertical_diffs(self):
        if hasattr(self, 'text_list'):
            diff = self.max_height - (
                len(self.text_list) * (self.line_size + self.line_space)
            ) + self.line_space - self.padding_bottom - self.padding_top
        else:
            diff = self.max_height - self.height

        if self.format['valign'] == 'bottom':
            self.diff_bottom = 0
            self.diff_top = diff
        elif self.format['valign'] == 'top':
            self.diff_top = 0
            self.diff_bottom = diff
        else:
            self.diff_bottom = int(diff / 2.0)
            self.diff_top = diff - self.diff_bottom
Esempio n. 14
0
class PDFCell(object):
    def __init__(self, table, row_index, column_index, text_cursor, border_cursor):
        self.table = table
        self.font = self.table.font
        self.row_index = row_index
        self.column_index = column_index

        self.text_cursor = text_cursor
        self.border_cursor = border_cursor

        self.height = 0
        self.width = 0
        self.max_width = 0

        self.line_space = 2
        self.text = ""

    def __repr__(self):
        return "(%s, %s)" % (self.row_index, self.column_index)

    # Text
    def _set_text(self, text):
        self.text = text
        if hasattr(self, "format"):
            numf = self.format["num_format"]
            if numf is not None:
                precision = numf[1]
                numf = numf[0]
                if precision <= 0:
                    self.text = str(int(self.text))
                else:
                    self.text = "%0.*f" % (precision, float(self.text))
                if "euro" in numf:
                    self.text = self.text.replace(".", ",")
                    self.text = "%s%s" % (chr(128), self.text)
                if any(s in numf for s in ["comma", ","]):
                    self.text = str("{:,}".format(int(self.text)))
                if any(s in numf for s in ["percent", "%"]):
                    self.text = "%s %" % self.text
                if any(s in numf for s in ["$", "money", "dollar"]):
                    self.text = "$%s" % self.text

    def _draw_text(self):
        if self.text == "" or self.text is None:
            self.text_cursor.x_plus(self.max_width)
        elif hasattr(self, "text_list"):
            self.text_cursor.y_plus(
                -self.padding_bottom
                - ((len(self.text_list) - 1) * (self.line_size + self.line_space))
                - self.diff_bottom
            )
            i = 0
            for item in self.text_list:
                self.text_cursor.x_plus(self.padding_left + self.width_diff_l[i])
                self.text_object = PDFText(
                    self.table.session, self.table.page, item, self.font, self.text_color, self.text_cursor
                )
                self.text_cursor.x_plus(-self.font._string_width(item) - self.width_diff_l[i])
                self.text_cursor.y_plus(self.line_space + self.line_size)
                i += 1
            self.text_cursor.x_plus(
                self.font._string_width(self.text_list[-1])
                + self.padding_right
                + self.width_diff_right
                + self.width_diff_l[-1]
            )
            self.text_cursor.y_plus(self.padding_bottom + self.diff_bottom - self.line_space - self.line_size)
        else:
            self.text_cursor.y_plus(-(self.padding_bottom + self.diff_bottom))
            self.text_cursor.x_plus(self.padding_left + self.width_diff_left)
            self.text_object = PDFText(
                self.table.session, self.table.page, self.text, self.font, self.text_color, self.text_cursor
            )
            self.text_cursor.x_plus(self.padding_right + self.width_diff_right)
            self.text_cursor.y_plus(self.padding_bottom + self.diff_bottom)

    def _set_text_padding(self):
        if self.format["padding"] is not False:
            self.padding_top = self.padding_right = self.padding_left = self.padding_bottom = self.format["padding"]
        else:
            self.padding_top = self.format["padding_top"]
            self.padding_right = self.format["padding_right"]
            self.padding_left = self.format["padding_left"]
            self.padding_bottom = self.format["padding_bottom"]

        self.width = self.text_width + self.padding_right + self.padding_left

        self.height = self.line_size + self.padding_top + self.padding_bottom

    # Format
    def _set_format(self, format):
        self.format = format
        self.font = self.format["font"]
        self.text_wrap = self.format["text_wrap"]
        self.text_color = self.format["text_color"]
        if self.text != "" and self.text is not None:
            self.text_width = self.font._string_width(self.text)
            self._set_text(self.text)
        else:
            self.text_width = 0
        if self.font is not None:
            self.line_size = self.font.line_size
        else:
            self.line_size = 0
        self._set_text_padding()

    # Borders
    def _get_points(self):
        self.point_nw = self.border_cursor.copy()
        self.point_sw = self.border_cursor.copy()
        self.point_se = self.border_cursor.copy()
        self.point_ne = self.border_cursor.copy()

        # cursor start is NW point
        self.point_sw.y_plus(self.max_height)
        self.point_ne.x_plus(self.max_width)
        self.point_se.x_plus(self.max_width)
        self.point_se.y_plus(self.max_height)

        self.border_cursor = self.point_ne

    def _get_border_formats(self):
        self.style = {}
        self.size = {}
        if self.format["border"][0] is not None:
            style, size = self.format["border"]
            self.style["left"] = self.style["right"] = self.style["top"] = self.style["bottom"] = style
            self.size["left"] = self.size["right"] = self.size["top"] = self.size["bottom"] = size
        else:
            self.style["right"], self.size["right"] = self.format["right"]
            self.style["left"], self.size["left"] = self.format["left"]
            self.style["top"], self.size["top"] = self.format["top"]
            self.style["bottom"], self.size["bottom"] = self.format["bottom"]

    def _set_borders(self):
        self._get_points()
        self._get_border_formats()
        if self.style["bottom"] is not None:
            self.bottom_line = PDFLine(
                self.table.session,
                self.table.page,
                self.point_sw,
                self.point_se,
                self.format["bottom_color"],
                self.style["bottom"],
                self.size["bottom"],
            )
        if self.style["right"] is not None:
            self.right_line = PDFLine(
                self.table.session,
                self.table.page,
                self.point_se,
                self.point_ne,
                self.format["right_color"],
                self.style["right"],
                self.size["right"],
            )
        if self.style["left"] is not None:
            self.left_line = PDFLine(
                self.table.session,
                self.table.page,
                self.point_sw,
                self.point_nw,
                self.format["left_color"],
                self.style["left"],
                self.size["left"],
            )
        if self.style["top"] is not None:
            self.top_line = PDFLine(
                self.table.session,
                self.table.page,
                self.point_ne,
                self.point_nw,
                self.format["top_color"],
                self.style["top"],
                self.size["top"],
            )

    def _draw_borders(self):
        if self.style["bottom"] is not None:
            self.bottom_line._draw()
        if self.style["right"] is not None:
            self.right_line._draw()
        if self.style["left"] is not None:
            self.left_line._draw()
        if self.style["top"] is not None:
            self.top_line._draw()

    # Fill
    def _draw_fill(self):
        if self.format["fill_color"] is not None:
            if isinstance(self.format["fill_color"], PDFColor):
                rect = PDFRectangle(
                    self.table.session,
                    self.table.page,
                    self.point_nw,
                    self.point_se,
                    fill_color=self.format["fill_color"],
                    style="F",
                )
                rect._draw()
            else:
                raise Exception("Color %s is not a PDFColor" % self.format["fill_color"])

    # Finishing
    def _compile(self):
        if hasattr(self, "format"):
            if self.text_wrap is not False:
                self.text_wrap = self.format["text_wrap"]
        else:
            self.text = ""
            self.text_width = 1
            self.line_size = 1
            self.format = PDFCellFormat(None, None)
            self.text_wrap = False
            self._set_text_padding()

    def _finish(self):
        if self.text_wrap is True and self.width > self.max_width:
            self.text_list = self.text.split("\n")
            self.height = (
                len(self.text_list) * (self.line_size + self.padding_bottom + self.padding_top)
                + self.diff_bottom
                + self.diff_top
            )
            for item in self.text_list:
                w = self.font._string_width(item)
                self.width = 0
                if w > self.width:
                    self.width = w
            self.text_wrap = False
            self.table._compile()

    def _advance_initial(self):
        self.text_cursor.y_plus(self.max_height - self.padding_bottom)

    def _set_max_width(self, value):
        self.max_width = value
        self.width = self.font._string_width(self.text) + self.padding_right + self.padding_left
        self._set_side_diffs()

    def _set_side_diffs(self):
        if hasattr(self, "text_list"):
            self.width_diff_l = []
            for item in self.text_list:
                textwidth = self.font._string_width(item)
                width_diff = self.max_width - self.padding_right - self.padding_left - textwidth
                if self.format["align"] == "left":
                    self.width_diff_l.append(0)
                    self.width_diff_right = width_diff
                elif self.format["align"] == "right":
                    self.width_diff_l.append(width_diff)
                    self.width_diff_right = 0
                else:
                    self.width_diff_l.append(int(width_diff / 2.0))
                    self.width_diff_right = width_diff - int(width_diff / 2.0)
        else:
            width_diff = self.max_width - self.width
            if self.format["align"] == "left":
                self.width_diff_left = 0
                self.width_diff_right = width_diff
            elif self.format["align"] == "right":
                self.width_diff_right = 0
                self.width_diff_left = width_diff
            else:
                self.width_diff_left = int(width_diff / 2.0)
                self.width_diff_right = width_diff - self.width_diff_left

    def _set_max_height(self, value):
        self.max_height = value
        self._set_vertical_diffs()

    def _set_vertical_diffs(self):
        if hasattr(self, "text_list"):
            diff = (
                self.max_height
                - (len(self.text_list) * (self.line_size + self.line_space))
                + self.line_space
                - self.padding_bottom
                - self.padding_top
            )
        else:
            diff = self.max_height - self.height

        if self.format["valign"] == "bottom":
            self.diff_bottom = 0
            self.diff_top = diff
        elif self.format["valign"] == "top":
            self.diff_top = 0
            self.diff_bottom = diff
        else:
            self.diff_bottom = int(diff / 2.0)
            self.diff_top = diff - self.diff_bottom