Font size support
This commit is contained in:
68
app.py
68
app.py
@@ -17,10 +17,16 @@ FONT_PATH = "./fonts/ubuntu/Ubuntu-Regular.ttf"
|
||||
FONT_PATH_BOLD = "./fonts/ubuntu/Ubuntu-Bold.ttf"
|
||||
FONT_PATH_OBLIQUE = "./fonts/ubuntu/Ubuntu-Italic.ttf"
|
||||
FONT_PATH_BOLDITALIC = "./fonts/ubuntu/Ubuntu-BoldItalic.ttf"
|
||||
FONT_SIZE = 24
|
||||
HEADER_SIZE_1 = 56
|
||||
HEADER_SIZE_2 = 34
|
||||
HEADER_SIZE_3 = 28
|
||||
DEFAULT_FONT_SIZE = 24
|
||||
FONT_SIZE_OPTIONS = {
|
||||
"small": 18,
|
||||
"normal": 24,
|
||||
"large": 30,
|
||||
"xlarge": 36,
|
||||
}
|
||||
HEADER_RATIO_1 = 56 / 24
|
||||
HEADER_RATIO_2 = 34 / 24
|
||||
HEADER_RATIO_3 = 28 / 24
|
||||
BANNER_FONT_SIZE = 300
|
||||
IMAGE_WIDTH = 384
|
||||
BULLET_CHAR = "• "
|
||||
@@ -343,18 +349,24 @@ def wrap_segments(segments, font, font_bold, font_italic, font_bolditalic, max_w
|
||||
if line:
|
||||
yield line
|
||||
|
||||
def render(md, dithering, printmode, uploaded_img_bytes=None, bannermode=False):
|
||||
font = ImageFont.truetype(FONT_PATH, FONT_SIZE)
|
||||
font_bold = ImageFont.truetype(FONT_PATH_BOLD, FONT_SIZE)
|
||||
font_italic = ImageFont.truetype(FONT_PATH_OBLIQUE, FONT_SIZE)
|
||||
def render(md, dithering, printmode, uploaded_img_bytes=None, bannermode=False, font_size=None):
|
||||
if font_size is None:
|
||||
font_size = DEFAULT_FONT_SIZE
|
||||
header_size_1 = round(font_size * HEADER_RATIO_1)
|
||||
header_size_2 = round(font_size * HEADER_RATIO_2)
|
||||
header_size_3 = round(font_size * HEADER_RATIO_3)
|
||||
|
||||
font = ImageFont.truetype(FONT_PATH, font_size)
|
||||
font_bold = ImageFont.truetype(FONT_PATH_BOLD, font_size)
|
||||
font_italic = ImageFont.truetype(FONT_PATH_OBLIQUE, font_size)
|
||||
font_banner = ImageFont.truetype(FONT_PATH_BOLD, BANNER_FONT_SIZE)
|
||||
try:
|
||||
font_bolditalic = ImageFont.truetype(FONT_PATH_BOLDITALIC, FONT_SIZE)
|
||||
font_bolditalic = ImageFont.truetype(FONT_PATH_BOLDITALIC, font_size)
|
||||
except:
|
||||
font_bolditalic = None
|
||||
font_h1 = ImageFont.truetype(FONT_PATH_BOLD, HEADER_SIZE_1)
|
||||
font_h2 = ImageFont.truetype(FONT_PATH_BOLD, HEADER_SIZE_2)
|
||||
font_h3 = ImageFont.truetype(FONT_PATH_BOLD, HEADER_SIZE_3)
|
||||
font_h1 = ImageFont.truetype(FONT_PATH_BOLD, header_size_1)
|
||||
font_h2 = ImageFont.truetype(FONT_PATH_BOLD, header_size_2)
|
||||
font_h3 = ImageFont.truetype(FONT_PATH_BOLD, header_size_3)
|
||||
|
||||
if bannermode:
|
||||
# Remove line breaks for single-line banner
|
||||
@@ -392,17 +404,17 @@ def render(md, dithering, printmode, uploaded_img_bytes=None, bannermode=False):
|
||||
image = bleh_image_from_url(tag[1], dithering, printmode)
|
||||
lines_out.append(('image', image))
|
||||
except Exception as e:
|
||||
lines_out.append(('text', [('text', f"[Imagen inválida: {e}]")], font, FONT_SIZE))
|
||||
lines_out.append(('text', [('text', f"[Imagen inválida: {e}]")], font, font_size))
|
||||
elif tag[0] == 'userimage':
|
||||
if uploaded_img_bytes:
|
||||
try:
|
||||
image = bleh_image_from_bytes(uploaded_img_bytes, dithering, printmode)
|
||||
lines_out.append(('image', image))
|
||||
except Exception as e:
|
||||
lines_out.append(('text', [('text', f"[Error al procesar imagen]")], font, FONT_SIZE))
|
||||
lines_out.append(('text', [('text', f"[Error al procesar imagen]")], font, font_size))
|
||||
print(f"Image processing error: {e}")
|
||||
else:
|
||||
lines_out.append(('text', [('text', "[No se subió una imagen]")], font, FONT_SIZE))
|
||||
lines_out.append(('text', [('text', "[No se subió una imagen]")], font, font_size))
|
||||
elif tag[0] == 'hr':
|
||||
lines_out.append(('hr',))
|
||||
elif tag[0] == 'header':
|
||||
@@ -410,13 +422,13 @@ def render(md, dithering, printmode, uploaded_img_bytes=None, bannermode=False):
|
||||
segments = tag[2]
|
||||
if header_level == 1:
|
||||
font_h = font_h1
|
||||
size_h = HEADER_SIZE_1
|
||||
size_h = header_size_1
|
||||
elif header_level == 2:
|
||||
font_h = font_h2
|
||||
size_h = HEADER_SIZE_2
|
||||
size_h = header_size_2
|
||||
else:
|
||||
font_h = font_h3
|
||||
size_h = HEADER_SIZE_3
|
||||
size_h = header_size_3
|
||||
for wrapped in wrap_segments(segments, font_h, font_h, font_h, font_h, IMAGE_WIDTH):
|
||||
lines_out.append(('header', wrapped, font_h, size_h))
|
||||
elif tag[0] == 'bullet':
|
||||
@@ -426,9 +438,9 @@ def render(md, dithering, printmode, uploaded_img_bytes=None, bannermode=False):
|
||||
wrapped_lines = list(wrap_segments(segments, font, font_bold, font_italic, font_bolditalic, IMAGE_WIDTH - bullet_w, start_x=0))
|
||||
for i, wrapped in enumerate(wrapped_lines):
|
||||
if i == 0:
|
||||
lines_out.append(('bullet', wrapped, bullet_font, FONT_SIZE, True, bullet_w))
|
||||
lines_out.append(('bullet', wrapped, bullet_font, font_size, True, bullet_w))
|
||||
else:
|
||||
lines_out.append(('bullet', wrapped, bullet_font, FONT_SIZE, False, bullet_w))
|
||||
lines_out.append(('bullet', wrapped, bullet_font, font_size, False, bullet_w))
|
||||
elif tag[0] == 'ordered':
|
||||
idx, segments = tag[1], tag[2]
|
||||
num_str = f"{idx}. "
|
||||
@@ -437,13 +449,13 @@ def render(md, dithering, printmode, uploaded_img_bytes=None, bannermode=False):
|
||||
wrapped_lines = list(wrap_segments(segments, font, font_bold, font_italic, font_bolditalic, IMAGE_WIDTH - num_w, start_x=0))
|
||||
for i, wrapped in enumerate(wrapped_lines):
|
||||
if i == 0:
|
||||
lines_out.append(('ordered', wrapped, number_font, FONT_SIZE, num_str, True, num_w))
|
||||
lines_out.append(('ordered', wrapped, number_font, font_size, num_str, True, num_w))
|
||||
else:
|
||||
lines_out.append(('ordered', wrapped, number_font, FONT_SIZE, num_str, False, num_w))
|
||||
lines_out.append(('ordered', wrapped, number_font, font_size, num_str, False, num_w))
|
||||
else: # normal text
|
||||
segments = tag[1]
|
||||
for wrapped in wrap_segments(segments, font, font_bold, font_italic, font_bolditalic, IMAGE_WIDTH):
|
||||
lines_out.append(('text', wrapped, font, FONT_SIZE))
|
||||
lines_out.append(('text', wrapped, font, font_size))
|
||||
|
||||
# Compute total height, including images
|
||||
height = 10 # Top margin
|
||||
@@ -453,7 +465,7 @@ def render(md, dithering, printmode, uploaded_img_bytes=None, bannermode=False):
|
||||
elif item[0] == 'hr':
|
||||
height += 10
|
||||
elif item[0] == 'blank':
|
||||
height += FONT_SIZE
|
||||
height += font_size
|
||||
elif item[0] == 'image':
|
||||
img = item[1]
|
||||
height += img.height + 10 # add margin below image
|
||||
@@ -463,7 +475,7 @@ def render(md, dithering, printmode, uploaded_img_bytes=None, bannermode=False):
|
||||
y = 0
|
||||
for item in lines_out:
|
||||
if item[0] == 'blank':
|
||||
y += FONT_SIZE
|
||||
y += font_size
|
||||
elif item[0] == 'hr':
|
||||
draw.line((0, y + 5, IMAGE_WIDTH, y + 5), fill=0, width=2)
|
||||
y += 10
|
||||
@@ -572,11 +584,14 @@ def index():
|
||||
dithering = request.form.get("dithering", "floyd")
|
||||
printmode = request.form.get("printmode", "1bpp")
|
||||
bannermode = bool(request.form.get("bannermode"))
|
||||
image = render(md, dithering, printmode, uploaded_img_bytes, bannermode=bannermode)
|
||||
fontsize_key = request.form.get("fontsize", "normal")
|
||||
font_size = FONT_SIZE_OPTIONS.get(fontsize_key, DEFAULT_FONT_SIZE)
|
||||
image = render(md, dithering, printmode, uploaded_img_bytes, bannermode=bannermode, font_size=font_size)
|
||||
session['dithering'] = dithering
|
||||
session['printmode'] = printmode
|
||||
session['rotation'] = rotation
|
||||
session['bannermode'] = bannermode
|
||||
session['fontsize'] = fontsize_key
|
||||
buf = io.BytesIO()
|
||||
image.save(buf, format="PNG")
|
||||
buf.seek(0)
|
||||
@@ -617,6 +632,7 @@ def index():
|
||||
current_rotation=session.get('rotation', 0),
|
||||
current_printmode=session.get('printmode', '1bpp'),
|
||||
current_bannermode=session.get('bannermode', False),
|
||||
current_fontsize=session.get('fontsize', 'normal'),
|
||||
t=t,
|
||||
lang=lang
|
||||
)
|
||||
|
||||
@@ -33,7 +33,12 @@
|
||||
"image_url": "Image URL",
|
||||
"leave_an_empty_line": "Leave an empty line",
|
||||
"uses_the_uploaded_image": "(uses the uploaded image)",
|
||||
"no_dithering": "No dithering"
|
||||
"no_dithering": "No dithering",
|
||||
"font_size": "Font size:",
|
||||
"font_small": "Small",
|
||||
"font_normal": "Normal",
|
||||
"font_large": "Large",
|
||||
"font_xlarge": "Extra Large"
|
||||
},
|
||||
"es": {
|
||||
"catnote": "CatNote",
|
||||
@@ -69,6 +74,11 @@
|
||||
"image_url": "URL de la imagen",
|
||||
"leave_an_empty_line": "Deje una línea vacía",
|
||||
"uses_the_uploaded_image": "(usa la imagen cargada)",
|
||||
"no_dithering": "Sin dithering"
|
||||
"no_dithering": "Sin dithering",
|
||||
"font_size": "Tamaño de fuente:",
|
||||
"font_small": "Pequeño",
|
||||
"font_normal": "Normal",
|
||||
"font_large": "Grande",
|
||||
"font_xlarge": "Extra grande"
|
||||
}
|
||||
}
|
||||
@@ -571,6 +571,15 @@
|
||||
<option value="270" {% if 270==current_rotation %}selected="selected" {% endif %}>270°</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="options-fontsize">
|
||||
<label for="fontsize">{{ t['font_size'] }}</label>
|
||||
<select name="fontsize">
|
||||
<option value="small" {% if "small"==current_fontsize %}selected="selected" {% endif %}>{{ t['font_small'] }}</option>
|
||||
<option value="normal" {% if "normal"==current_fontsize %}selected="selected" {% endif %}>{{ t['font_normal'] }}</option>
|
||||
<option value="large" {% if "large"==current_fontsize %}selected="selected" {% endif %}>{{ t['font_large'] }}</option>
|
||||
<option value="xlarge" {% if "xlarge"==current_fontsize %}selected="selected" {% endif %}>{{ t['font_xlarge'] }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="options-printmode">
|
||||
<label for="printmode">{{ t['print_mode'] }}</label>
|
||||
<select name="printmode">
|
||||
|
||||
Reference in New Issue
Block a user