Exemple #1
0
def draw_text(draw_im: ImageDraw, w: int, text: str, y_text: float,
              font: any) -> int:
    """Draws the text on the image of width w, starting at height y_text

    Args:
        draw_im (ImageDraw): image to draw on
        w (int): with of the image
        text (str): text to write
        y_text (int): height of the text
        font (any): font of the text

    Returns:
        int: final height of the text
    """
    return_text = text.split(
        "\n")  # split the title based on the return char \n
    multiline_text = []
    for return_line in return_text:
        for line in textwrap.wrap(
                return_line, config_map['image']
            ['line_width']):  # split the line if the string is too long
            multiline_text.append(line)
    for line in multiline_text:  # write each line of the title
        t_w, t_h = font.getsize(line)
        draw_im.multiline_text(xy=((w - t_w) / 2, y_text),
                               text=line,
                               fill="white",
                               font=font)
        y_text += t_h
    return y_text
Exemple #2
0
def draw_clean_text(draw: ImageDraw, text: str, lang: str, box: Box, fill: str = 'black', spacing: int = 0, pad: int = 0) -> None:
    '''Place the text at the center of the bounding box.
    Input:
        draw:    ImageDraw instance
        text:    Content to add
        lang:    Language
        box:     Bounding box
        fill:    Color of text
        spacing: Vertical spacing between lines
        pad:     Inner padding to add to the bounding box
    '''
    box.pad(p=pad)
    W, H = (box.R - box.L), (box.B - box.T)
    font_path = f'data/fonts/indic/{lang}.ttf'
    F = ImageFont.truetype(font=font_path, size=1)

    size = 1

    w, h = draw.multiline_textsize(text, font=F, spacing=spacing)
    while w < W and h < H:
        size += 1
        F = ImageFont.truetype(font=font_path, size=size)
        w, h = draw.multiline_textsize(text, font=F, spacing=spacing)

    # TODO: fix, uncomment this if you want a static size & not dynamic size for texts
    # size = 30 if size < 70 else 100

    F = ImageFont.truetype(font=font_path, size=size)
    w, h = F.getsize_multiline(text)

    cx = (W - w) / 2 + box.L
    cy = (H - h) / 2 + box.T - 10

    draw.multiline_text((cx, cy), text, fill=fill, font=F, align='center', spacing=spacing)
Exemple #3
0
def draw_outlined_text(draw: ImageDraw, position, text: str, **kwargs):
    x, y = position
    shadowcolor = 'black'
    nonfill_kargs = {k: v for (k, v) in kwargs.items() if k != 'fill'}  # gross
    draw.multiline_text((x - 1, y - 1),
                        text,
                        fill=shadowcolor,
                        align='center',
                        spacing=4,
                        **nonfill_kargs)
    draw.multiline_text((x + 1, y - 1),
                        text,
                        fill=shadowcolor,
                        align='center',
                        spacing=4,
                        **nonfill_kargs)
    draw.multiline_text((x - 1, y + 1),
                        text,
                        fill=shadowcolor,
                        align='center',
                        spacing=4,
                        **nonfill_kargs)
    draw.multiline_text((x + 1, y + 1),
                        text,
                        fill=shadowcolor,
                        align='center',
                        spacing=4,
                        **nonfill_kargs)
    draw.multiline_text(position, text, align='center', spacing=4, **kwargs)
Exemple #4
0
def centeredText(draw: ImageDraw, font: ImageFont, x: int, y: int, text: str,
                 color: str):
    textSize = draw.multiline_textsize(text, font)
    draw.multiline_text((x - textSize[0] / 2, y - textSize[1] / 2),
                        text,
                        color,
                        font,
                        align="center")
    def render_layer(self, dungeon: Dungeon,
                     paintableRooms: Dict[DungeonRoom, PaintableRoom],
                     img: Image, draw: ImageDraw) -> None:
        """See RenderLayer for docs."""

        for room in dungeon.rooms:
            if room.type is None:
                continue

            text, lines = self.word_wrap(room.type.name,
                                         paintableRooms[room].size - 8)

            w, h = self.font.getsize(text)

            r = paintableRooms[room].rect
            draw.multiline_text((r[0] + 4, r[3] - h * lines - 2),
                                text, fill=self.color, font=self.font)
Exemple #6
0
def draw_text(draw_im: ImageDraw, w: int, text: str, y_text: float, font_size: int) -> int:
    """Draws the text on the image of width w, starting at height y_text

    Args:
        draw_im (ImageDraw): image to draw on
        w (int): with of the image
        text (str): text to write
        y_text (int): height of the text
        font (any): font of the text

    Returns:
        int: final height of the text
    """
    font = ImageFont.truetype(font="data/font/UbuntuCondensed-Regular.ttf", size=font_size)
    for line in wrap_text(text=text, max_w=w / 3 * 2, font=font):  # write each line of the text
        t_w, t_h = font.getsize(line)
        draw_im.multiline_text(xy=((w - t_w) / 2, y_text), text=line, fill="white", font=font)
        y_text += t_h + 5
    return y_text
Exemple #7
0
    def render_list(self, result: Image, draw: ImageDraw, draw_property: Mapping,
                    bounding_box: Tuple[Tuple[int, int], Tuple[int, int]], current_x: int, current_y: int,
                    backwards: bool) -> Tuple[int, int]:
        theme_font = None
        if "text" in draw_property["type"]:
            theme_font = ImageFont.truetype(draw_property["font"], draw_property["font_size"])
        items = self.properties.get(draw_property["property"])
        current_x, current_y = self.resolve_position(draw_property["position"], bounding_box, current_x, current_y)
        size_x, size_y = draw_property["size"]
        if size_x == "auto":
            size_x = bounding_box[1][0] - current_x + bounding_box[0][0]
            if backwards:
                size_x = current_x - bounding_box[0][0]
        if size_y == "auto":
            size_y = bounding_box[1][1] - current_y + bounding_box[0][1]
        print(current_x, size_x, backwards)
        if backwards:
            current_x = current_x - size_x
        orientation = draw_property["orientation"]
        internal_current_y = current_y
        internal_current_x = current_x
        if items is not None:
            cached_current_x = current_x
            cached_current_y = current_y
            spacing = draw_property["spacing"]
            x_border = current_x + size_x
            y_border = current_y + size_y
            rows = draw_property["rows"]
            columns = draw_property["columns"]
            first = True
            # CodeReview: Specify an order that all will conform to
            for item in items:
                resource_name = f"resources/icons/{item}.png"
                if "icon" in draw_property["type"] and os.path.isfile(resource_name):
                    icon = Image.open(resource_name)
                    icon_width, icon_height = icon.size
                    icon = icon.resize((self.format["icon_height"] * icon_width // icon_height,
                                        self.format["icon_height"]), Image.HAMMING)
                    icon_width, icon_height = icon.size
                    x_coord = internal_current_x
                    y_coord = internal_current_y
                    if orientation == "horizontal":
                        if not first:
                            x_coord += spacing
                        first = False
                        if draw_property["centered_height"]:
                            y_coord += (size_y // (rows or 1) - icon_height) // 2
                    if orientation == "vertical":
                        if not first:
                            y_coord += spacing
                        first = False
                        if draw_property["centered_width"]:
                            x_coord += (size_x // (columns or 1) - icon_width) // 2
                    if orientation == "horizontal" and x_coord + icon_width > x_border \
                            and rows is not None and internal_current_y < current_y + (rows - 1) * (size_y // rows):
                        internal_current_y += size_y // rows
                        internal_current_x = cached_current_x
                        x_coord = internal_current_x
                        y_coord += size_y // rows
                    elif orientation == "vertical" and y_coord + icon_height > y_border \
                            and columns is not None and \
                            internal_current_x < current_x + (columns - 1) * (size_y // columns):
                        internal_current_x += size_x // rows
                        internal_current_y = cached_current_y
                    result.paste(icon, (x_coord, y_coord))
                    if orientation == "horizontal":
                        internal_current_x = x_coord + icon_width
                    elif orientation == "vertical":
                        internal_current_y = y_coord + icon_height
                elif "text" in draw_property["type"]:
                    text_width, text_height = draw.textsize(item, theme_font)
                    if draw_property["wrap"] is not None:
                        item = textwrap.fill(item, draw_property["wrap"])
                        text_width, text_height = draw.multiline_textsize(item, theme_font)
                    x_coord = internal_current_x
                    y_coord = internal_current_y
                    text_color = self.properties.get(draw_property["text_color_property"]) or \
                        draw_property["text_color_default"]
                    if draw_property["bulleted"]:
                        draw.ellipse((internal_current_x + spacing,
                                      internal_current_y + (text_height - draw_property["font_size"]) // 2,
                                      internal_current_x + spacing + draw_property["font_size"],
                                      internal_current_y + (text_height + draw_property["spacing"]) // 2),
                                     fill=text_color)
                        x_coord += spacing*2 + draw_property["font_size"]
                    if orientation == "horizontal":
                        if not first:
                            x_coord += spacing
                        first = False
                        if draw_property["centered_height"]:
                            y_coord += (size_y // (rows or 1) - text_height) // 2
                    if orientation == "vertical":
                        if not first:
                            y_coord += spacing
                        first = False
                        if draw_property["centered_width"]:
                            x_coord += (size_x // (columns or 1) - text_width) // 2
                    print(x_coord, text_width, x_border, cached_current_x, internal_current_y)
                    if orientation == "horizontal" and x_coord + text_width > x_border \
                            and rows is not None and internal_current_y < current_y + (rows - 1) * (size_y // rows):
                        internal_current_y += size_y // rows
                        internal_current_x = cached_current_x
                        x_coord = internal_current_x
                        y_coord += size_y // rows
                    elif orientation == "vertical" and y_coord + text_height > y_border \
                            and columns is not None and \
                            internal_current_x < current_x + (columns - 1) * (size_y // columns):
                        internal_current_x += size_x // rows
                        internal_current_y = cached_current_y
                    if draw_property["wrap"] is None:
                        draw.text((x_coord, y_coord), item, fill=text_color, font=theme_font)
                    else:
                        draw.multiline_text((x_coord, y_coord), item, fill=text_color, font=theme_font)

                    if orientation == "horizontal":
                        internal_current_x = x_coord + text_width
                    elif orientation == "vertical":
                        internal_current_y = y_coord + text_height
                else:
                    raise Exception(f"Could not find handler for {item} for {draw_property['type']}")
            if not backwards:
                current_x += size_x
            if orientation == "vertical":
                current_y += size_y
        else:
            if draw_property["required"]:
                raise Exception(f"Missing required property: {draw_property['property']} from card {self.properties}")
        return current_x, current_y