Exemple #1
0
    def renderLine(self, raw: str, image: Image, y: int, height: int,
                   font: ImageFont.FreeTypeFont) -> ImageDraw:
        """
        Render a single line
        """
        # Get the number of blanks
        blanks = raw.count("_blank_")
        no_line = raw.replace("_blank_", "")
        ascent, descent = font.getmetrics()
        w, h = font.getsize(no_line)
        (width, baseline), (offset_x, offset_y) = font.font.getsize(no_line)

        if height < h:
            line = ascent
        else:
            line = height - descent / 2
            y = y - height + h

        ascent, descent = font.getmetrics()

        draw = ImageDraw.Draw(image)

        #  draw.line((0, y, w, y), fill=(255, 0, 0))
        #  draw.line((0, y + height, w, y + height), fill=(0, 255, 0))
        #  draw.line((0, y + h, w, y + h), fill=(0, 0, 255))

        if blanks > 0:
            # Get the size of each blank.

            blank_size = (image.size[0] - w) / blanks
            groups = raw.split("_blank_")

            # Render each group
            x = 0
            for group in groups:
                # Draw the text
                draw.text((x, y), group, self.color, font)

                w, _ = font.getsize(group)
                x += w

                if blanks > 0:
                    # Draw the line
                    draw.line(
                        ((x + 5, y + line), (x + blank_size - 5, y + line)),
                        fill=self.color,
                        width=2)

                    x += blank_size
                    blanks -= 1
            return
        draw.text((0, y), raw, self.color, font)
Exemple #2
0
def __get_x_centered(text_line: str, width_avail: int,
                     font: ImageFont.FreeTypeFont) -> int:
    """Get the X coordinate at which to draw a text line horizontally-centered.

    Parameters
    ----------
    text_line : str
        Text line to draw.
    width_avail : int
        Width available to draw (essentially the image's width).
    font : ImageFont.FreeTypeFont
        Font used to draw.

    Returns
    -------
    int
        The X coordinate at which to draw the text line horizontally-centered.
    """
    # https://stackoverflow.com/a/46220683/9263761
    ascent, descent = font.getmetrics()

    # Width needed to draw the line
    width_text = font.getmask(text_line).getbbox()[2] + font.font.getsize(
        text_line)[1][0]

    # Calculate the centered X coordinate
    x = (width_avail - width_text) // 2

    # Return the first Y coordinate and a list with the height of each line
    return x
Exemple #3
0
def __get_y_and_heights(text_wrapped: List[str], height_avail: int,
                        margin: float,
                        font: ImageFont.FreeTypeFont) -> Tuple[int, List[int]]:
    """Calculate the height needed to draw all text lines, vertically centered.
    Return the vertical coordinate to draw the first line at and a list of the heights for each line (margin included).

    Parameters
    ----------
    text_wrapped : List[str]
        Lines of text to draw.
    height_avail : int
        Height available to draw in (essentially the image's height).
    margin : float
        Vertical margin between text lines.
    font : ImageFont.FreeTypeFont
        Font used to draw.

    Returns
    -------
    Tuple[int, List[int]]
        The vertical coordinate of the first text line and a list with the heights of all lines.
    """
    # https://stackoverflow.com/a/46220683/9263761
    ascent, descent = font.getmetrics()

    # Calculate the height needed to draw each line of text
    height_lines = [
        font.getmask(text_line).getbbox()[3] +
        font.font.getsize(text_line)[1][1] + margin
        for text_line in text_wrapped
    ]
    # The last line doesn't have a bottom margin
    height_lines[-1] -= margin

    # Total height needed
    height_text = sum(height_lines)

    # Calculate the Y coordinate at which to draw the first line of text
    y = (height_avail - height_text) // 2

    # Return the first Y coordinate and a list with the height of each line
    return (y, height_lines)
Exemple #4
0
def getsize(font: FreeTypeFont, text_str: str) -> Tuple[int, int]:
    """get the size of text"""
    if USE_PIL:
        # original behavior
        # size = font.getsize(text_str)

        # new behavior
        width, _ = font.getsize(text_str)
        ascent, descent = font.getmetrics()
        height = ascent + descent
        size = (width, height)

    else:
        info = text_scala.get_info(text_str, _font_to_tuple(font), 0,
                                   BORDER_DEFAULT)
        # Important note! Info height and width may not include some antialiasing pixels!
        # import numpy as np
        # column_sums = np.sum(img, axis=0)
        # present = np.where(column_sums > 0)[0]
        # calculated_width = (present[-1] - present[0]) + 1
        # print("metrics width:", info["width"])
        # print("calculated width:", calculated_width)
        size = (info["width"], info["height"])
    return size