Handle small-caps synthesis

Fix #123.
This commit is contained in:
Guillaume Ayoub
2025-01-11 22:53:41 +01:00
parent ccbfac5bb0
commit fc147ba8a1
4 changed files with 32 additions and 8 deletions
+7 -6
View File
@@ -78,8 +78,7 @@ def draw_first_line(stream, textbox, text_overflow, block_ellipsis, matrix):
if not textbox.text.strip():
return []
font_size = textbox.style['font_size']
if font_size < 1e-6: # default float precision used by pydyf
if textbox.style['font_size'] < 1e-6: # default float precision used by pydyf
return []
pango.pango_layout_set_single_paragraph_mode(textbox.pango_layout.layout, True)
@@ -126,7 +125,7 @@ def draw_first_line(stream, textbox, text_overflow, block_ellipsis, matrix):
utf8_text = textbox.pango_layout.text.encode()
previous_utf8_position = 0
stream.set_text_matrix(*matrix.values)
last_font = None
last_font = last_font_size = None
string = ''
x_advance = 0
emojis = []
@@ -141,8 +140,10 @@ def draw_first_line(stream, textbox, text_overflow, block_ellipsis, matrix):
offset = glyph_item.item.offset
clusters = glyph_string.log_clusters
# Add font file content.
# Add font file content and get font size.
pango_font = glyph_item.item.analysis.font
description = pango.pango_font_describe(pango_font)
font_size = pango.pango_font_description_get_size(description) * FROM_UNITS
font = stream.add_font(pango_font)
# Get positions of the glyphs in the UTF-8 string.
@@ -150,12 +151,12 @@ def draw_first_line(stream, textbox, text_overflow, block_ellipsis, matrix):
utf8_positions.append(offset + glyph_item.item.length)
# Go through the run glyphs.
if font != last_font:
if (font, font_size) != (last_font, last_font_size):
if string:
stream.show_text(string)
string = ''
stream.set_font_size(font.hash, 1 if font.bitmap else font_size)
last_font = font
last_font, last_font_size = font, font_size
string += '<'
for i in range(num_glyphs):
glyph_info = glyphs[i]
+9
View File
@@ -38,6 +38,15 @@ PANGO_WRAP_MODE = {
'WRAP_CHAR': pango.PANGO_WRAP_CHAR,
'WRAP_WORD_CHAR': pango.PANGO_WRAP_WORD_CHAR
}
PANGO_VARIANT = {
'normal': pango.PANGO_VARIANT_NORMAL,
'small-caps': pango.PANGO_VARIANT_SMALL_CAPS,
'all-small-caps': pango.PANGO_VARIANT_ALL_SMALL_CAPS,
'petite-caps': pango.PANGO_VARIANT_PETITE_CAPS,
'all-petite-caps': pango.PANGO_VARIANT_ALL_PETITE_CAPS,
'unicase': pango.PANGO_VARIANT_UNICASE,
'titling-caps': pango.PANGO_VARIANT_TITLE_CAPS,
}
# Language system tags
# From https://docs.microsoft.com/typography/opentype/spec/languagetags
+12
View File
@@ -145,6 +145,16 @@ ffi.cdef('''
PANGO_WRAP_WORD_CHAR
} PangoWrapMode;
typedef enum {
PANGO_VARIANT_NORMAL,
PANGO_VARIANT_SMALL_CAPS,
PANGO_VARIANT_ALL_SMALL_CAPS,
PANGO_VARIANT_PETITE_CAPS,
PANGO_VARIANT_ALL_PETITE_CAPS,
PANGO_VARIANT_UNICASE,
PANGO_VARIANT_TITLE_CAPS,
} PangoVariant;
typedef enum {
PANGO_TAB_LEFT
} PangoTabAlign;
@@ -291,6 +301,8 @@ ffi.cdef('''
PangoFontDescription *desc, double size);
void pango_font_description_set_variations (
PangoFontDescription* desc, const char* variations);
void pango_font_description_set_variant (
PangoFontDescription* desc, PangoVariant variant);
PangoStyle pango_font_description_get_style (const PangoFontDescription *desc);
const char* pango_font_description_get_variations (
+4 -2
View File
@@ -14,8 +14,8 @@ from ..logger import LOGGER
from ..urls import FILESYSTEM_ENCODING, fetch
from .constants import ( # isort:skip
CAPS_KEYS, EAST_ASIAN_KEYS, FONTCONFIG_STRETCH, FONTCONFIG_STYLE,
FONTCONFIG_WEIGHT, LIGATURE_KEYS, NUMERIC_KEYS, PANGO_STRETCH, PANGO_STYLE)
CAPS_KEYS, EAST_ASIAN_KEYS, FONTCONFIG_STRETCH, FONTCONFIG_STYLE, FONTCONFIG_WEIGHT,
LIGATURE_KEYS, NUMERIC_KEYS, PANGO_STRETCH, PANGO_STYLE, PANGO_VARIANT)
from .ffi import ( # isort:skip
TO_UNITS, ffi, fontconfig, gobject, harfbuzz, pango, pangoft2, unicode_to_char_p)
@@ -319,6 +319,8 @@ def get_font_description(style):
pango.pango_font_description_set_weight(font_description, font_weight)
font_size = int(style['font_size'] * TO_UNITS)
pango.pango_font_description_set_absolute_size(font_description, font_size)
font_variant = PANGO_VARIANT[style['font_variant_caps']]
pango.pango_font_description_set_variant(font_description, font_variant)
if style['font_variation_settings'] != 'normal':
string = ','.join(
f'{key}={value}' for key, value in