Source code for todays_paper_web.widgets.core.rectangle

import webcolors
from PIL import Image, ImageDraw
from pydantic import Field

from todays_paper_web.widgets import registerView, View
from todays_paper_web.widgets.params import Color
from todays_paper_web.widgets.view import ViewParams

# Pillow's rounded_rectangle corners order: (top-left, top-right, bottom-right, bottom-left).
_CORNER_GROUPS = {
    "all": ("tl", "tr", "br", "bl"),
    "none": (),
    "top": ("tl", "tr"),
    "bottom": ("bl", "br"),
    "left": ("tl", "bl"),
    "right": ("tr", "br"),
}


def _parseCorners(value):
    if not value:
        return (True, True, True, True)
    names = set()
    for token in value.split(","):
        token = token.strip().lower()
        names.update(_CORNER_GROUPS.get(token, (token,)))
    return tuple(name in names for name in ("tl", "tr", "br", "bl"))


[docs] class RectangleParams(ViewParams): width: int = Field(1, description="Rectangle width in pixels.") height: int = Field(1, description="Rectangle height in pixels.") color: Color = Field( default_factory=lambda: webcolors.name_to_rgb("black"), description="Fill color (if `fill` is set) or outline color otherwise.", ) fill: bool = Field( False, description="Fill the rectangle with `color` instead of just outlining it." ) radius: int = Field( 0, description="Corner radius in pixels; 0 draws sharp corners." ) corners: str = Field( "all", description="Which corners `radius` rounds: `all`, `none`, `top`, `bottom`, `left`, " "`right`, or a comma-separated list of `tl`/`tr`/`br`/`bl`.", )
@registerView("rectangle") class RectangleView(View): Params = RectangleParams def render(self): img = Image.new("RGBA", (self.params.width, self.params.height), (0, 0, 0, 0)) draw = ImageDraw.Draw(img) box = (0, 0, self.params.width - 1, self.params.height - 1) if self.params.radius > 0: draw.rounded_rectangle( box, radius=self.params.radius, fill=self.params.color if self.params.fill else None, outline=self.params.color, corners=_parseCorners(self.params.corners), ) else: draw.rectangle( box, fill=self.params.color if self.params.fill else None, outline=self.params.color ) return img