Tweak font selection
This commit is contained in:
parent
7d8842b4ac
commit
52776494cb
87
test/fixtures/page_generation/page.py
vendored
87
test/fixtures/page_generation/page.py
vendored
@ -105,6 +105,11 @@ from funcy import (
|
||||
repeatedly,
|
||||
mapcat,
|
||||
lmapcat,
|
||||
without,
|
||||
merge,
|
||||
omit,
|
||||
project,
|
||||
complement,
|
||||
)
|
||||
|
||||
from cv_analysis.locations import TEST_PAGE_TEXTURES_DIR
|
||||
@ -733,26 +738,39 @@ def dump_plt_to_image(rectangle):
|
||||
|
||||
class RandomFontPicker:
|
||||
def __init__(self, font_dir=None, size=None):
|
||||
self.fonts = get_fonts(font_dir)
|
||||
self.fonts_lower = [font.lower() for font in self.fonts]
|
||||
fonts = get_fonts(font_dir)
|
||||
fonts_lower = [font.lower() for font in fonts]
|
||||
domestic_fonts_mask = lmap(complement(self.looks_foreign), fonts_lower)
|
||||
self.fonts = list(itertools.compress(fonts, domestic_fonts_mask))
|
||||
self.fonts_lower = list(itertools.compress(fonts_lower, domestic_fonts_mask))
|
||||
|
||||
self.test_image = Image.new("RGB", (200, 200), (255, 255, 255))
|
||||
self.draw = ImageDraw.Draw(self.test_image)
|
||||
self.size = size or 11
|
||||
|
||||
def looks_foreign(self, font):
|
||||
# This filters out foreign fonts (e.g. 'Noto Serif Malayalam')
|
||||
return len(font.split("-")[0]) > 10
|
||||
|
||||
def pick_random_font_available_on_system(self, includes=None, excludes=None) -> ImageFont: # FIXME: Slow!
|
||||
|
||||
self.shuffle_fonts()
|
||||
includes = [i.lower() for i in includes] if includes else []
|
||||
excludes = [i.lower() for i in excludes] if excludes else []
|
||||
|
||||
includes_pattern = (lambda f: includes.lower() in f) if includes else (lambda f: True)
|
||||
excludes_pattern = (lambda f: excludes.lower() not in f) if excludes else (lambda f: True)
|
||||
logger.debug(f"Picking font by includes={includes} and excludes={excludes}.")
|
||||
|
||||
def includes_pattern(font):
|
||||
return not includes or any(include in font for include in includes)
|
||||
|
||||
def excludes_pattern(font):
|
||||
return not excludes or not any(exclude in font for exclude in excludes)
|
||||
|
||||
self.shuffle_fonts()
|
||||
|
||||
mask = lmap(lambda f: includes_pattern(f) and excludes_pattern(f), self.fonts_lower)
|
||||
fonts = itertools.compress(self.fonts, mask)
|
||||
fonts = keep(map(self.load_font, fonts))
|
||||
fonts = filter(self.font_is_renderable, fonts) # FIXME: this does not work
|
||||
fonts = (font for font in fonts if font.getname()[1].lower() not in ["italic"])
|
||||
fonts = (font for font in fonts if font.getname()[1].lower() in ["bold"])
|
||||
|
||||
font = first(fonts)
|
||||
logger.info(f"Using font: {font.getname()}")
|
||||
@ -764,7 +782,7 @@ class RandomFontPicker:
|
||||
self.fonts, self.fonts_lower = lzip(*l)
|
||||
|
||||
def pick_random_mono_space_font_available_on_system(self) -> ImageFont:
|
||||
return self.pick_random_font_available_on_system(includes="mono", excludes="oblique")
|
||||
return self.pick_random_font_available_on_system(includes=["mono"], excludes=["oblique"])
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def load_font(self, font: str):
|
||||
@ -794,14 +812,30 @@ def get_font_picker(**kwargs):
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def pick_random_mono_space_font_available_on_system(**kwargs):
|
||||
font_picker = get_font_picker(**kwargs)
|
||||
font_picker = get_font_picker(**omit(kwargs, ["includes", "excludes"]))
|
||||
return font_picker.pick_random_mono_space_font_available_on_system()
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def pick_random_font_available_on_system(**kwargs):
|
||||
font_picker = get_font_picker(**kwargs)
|
||||
return font_picker.pick_random_font_available_on_system(includes="mono")
|
||||
# kwargs["excludes"] = (
|
||||
# *kwargs.get(
|
||||
# "excludes",
|
||||
# ),
|
||||
# "hebrew",
|
||||
# "armenian", # TODO: De-hardcode / find a better way to filter out fonts that can not be rendered
|
||||
# "arabic",
|
||||
# "cyrillic",
|
||||
# "georgian",
|
||||
# "greek",
|
||||
# "telugu",
|
||||
# "tamil",
|
||||
# "thai",
|
||||
# "vietnamese",
|
||||
# "ethiopic",
|
||||
# )
|
||||
font_picker = get_font_picker(**omit(kwargs, ["includes", "excludes"]))
|
||||
return font_picker.pick_random_font_available_on_system(**project(kwargs, ["includes", "excludes"]))
|
||||
|
||||
|
||||
class RandomPlot(RandomContentRectangle):
|
||||
@ -910,7 +944,14 @@ def maybe():
|
||||
|
||||
|
||||
def generate_random_text_block(rectangle: Rectangle, n_sentences=3000) -> ContentRectangle:
|
||||
block = TextBlock(*rectangle.coords)
|
||||
block = TextBlock(
|
||||
*rectangle.coords,
|
||||
font=pick_random_font_available_on_system(
|
||||
size=30, # TODO: De-hardcode font size... Seems to have no effect on top of that
|
||||
includes=("serif", "sans-serif"),
|
||||
excludes=("bold", "mono", "italic", "oblique", "cursive"),
|
||||
),
|
||||
)
|
||||
block.content = rectangle.content if isinstance(rectangle, ContentRectangle) else None # TODO: Refactor
|
||||
block.generate_random_text(rectangle, n_sentences)
|
||||
return block
|
||||
@ -925,14 +966,30 @@ def generate_random_table_caption(rectangle: Rectangle) -> ContentRectangle:
|
||||
|
||||
|
||||
def generate_random_caption(rectangle: Rectangle, caption_start, n_sentences=1000) -> ContentRectangle:
|
||||
block = TextBlock(*rectangle.coords, text_generator=CaptionGenerator(caption_start=caption_start), font_size=5)
|
||||
block = TextBlock(
|
||||
*rectangle.coords,
|
||||
text_generator=CaptionGenerator(caption_start=caption_start),
|
||||
font=pick_random_font_available_on_system(
|
||||
size=8,
|
||||
includes=("italic"),
|
||||
excludes=("bold", "mono"),
|
||||
),
|
||||
font_size=5, # TODO: De-hardcode font size... Seems to have no effect on top of that
|
||||
)
|
||||
block.content = rectangle.content if isinstance(rectangle, ContentRectangle) else None # TODO: Refactor
|
||||
block.generate_random_text(rectangle, n_sentences)
|
||||
return block
|
||||
|
||||
|
||||
def generate_text_block(rectangle: Rectangle, text) -> ContentRectangle:
|
||||
block = TextBlock(*rectangle.coords)
|
||||
block = TextBlock(
|
||||
*rectangle.coords,
|
||||
font=pick_random_font_available_on_system(
|
||||
size=11, # TODO: De-hardcode font size... Seems to have no effect on top of that
|
||||
includes=("serif", "sans-serif"),
|
||||
excludes=("bold", "mono", "italic", "oblique", "cursive"),
|
||||
),
|
||||
)
|
||||
block.content = rectangle.content if isinstance(rectangle, ContentRectangle) else None # TODO: Refactor
|
||||
block.put_text(text, rectangle)
|
||||
return block
|
||||
@ -1036,7 +1093,7 @@ class CaptionGenerator(TextBlockGenerator):
|
||||
class TextBlock(ContentRectangle):
|
||||
def __init__(self, x1, y1, x2, y2, text_generator=None, font=None, font_size=None):
|
||||
super().__init__(x1, y1, x2, y2)
|
||||
self.font = pick_random_font_available_on_system(size=font_size) # ImageFont.load_default()
|
||||
self.font = font or ImageFont.load_default() # pick_random_font_available_on_system(size=font_size)
|
||||
self.text_generator = text_generator or ParagraphGenerator()
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user