def render(self,
               horizontal_spacing: int = 1,
               vertical_spacing: int = 1,
               crossing_char: str = None,
               use_unicode_characters: bool = True) -> str:
        """Outputs text containing the diagram."""

        block_diagram = BlockDiagramDrawer()

        w = self.width()
        h = self.height()

        # Communicate padding into block diagram.
        for x in range(0, w - 1):
            block_diagram.set_col_min_width(
                x*2 + 1,
                # Horizontal separation looks narrow, so partials round up.
                int(np.ceil(self.horizontal_padding.get(x, horizontal_spacing)))
            )
            block_diagram.set_col_min_width(x*2, 1)
        for y in range(0, h - 1):
            block_diagram.set_row_min_height(
                y*2 + 1,
                # Vertical separation looks wide, so partials round down.
                int(np.floor(self.vertical_padding.get(y, vertical_spacing)))
            )
            block_diagram.set_row_min_height(y*2, 1)

        # Draw vertical lines.
        for x_b, y1_b, y2_b, emphasize in self.vertical_lines:
            x = int(x_b * 2)
            y1, y2 = int(min(y1_b, y2_b) * 2), int(max(y1_b, y2_b) * 2)
            charset = pick_charset(use_unicode_characters, emphasize)

            # Caps.
            block_diagram.mutable_block(x, y1).draw_curve(
                charset, bottom=True)
            block_diagram.mutable_block(x, y2).draw_curve(
                charset, top=True)

            # Span.
            for y in range(y1 + 1, y2):
                block_diagram.mutable_block(x, y).draw_curve(
                    charset, top=True, bottom=True)

        # Draw horizontal lines.
        for y_b, x1_b, x2_b, emphasize in self.horizontal_lines:
            y = int(y_b * 2)
            x1, x2 = int(min(x1_b, x2_b) * 2), int(max(x1_b, x2_b) * 2)
            charset = pick_charset(use_unicode_characters, emphasize)

            # Caps.
            block_diagram.mutable_block(x1, y).draw_curve(
                charset, right=True)
            block_diagram.mutable_block(x2, y).draw_curve(
                charset, left=True)

            # Span.
            for x in range(x1 + 1, x2):
                block_diagram.mutable_block(x, y).draw_curve(
                    charset, left=True, right=True, crossing_char=crossing_char)

        # Place entries.
        for (x, y), v in self.entries.items():
            x *= 2
            y *= 2
            block_diagram.mutable_block(x, y).content = v.text

        return block_diagram.render()