Summary
PictexSubtitleRenderer renders multi-word captions with no gaps between words. The same template rendered with CssSubtitleRenderer is correct. It fails silently: the render completes without error, so the only signal is looking at a frame.
Observed with the bundled word-focus template at 1080x1920. Script line "like my phone went from" renders as Likemyphonewentfrom. Also reproduces on explosive.
Cause
The two renderers disagree on what get_word_size should include, and the preset templates space words with CSS padding on the word element rather than a word-spacing property:
word-focus/styles.css: padding: 4px 4px
explosive/styles.css: padding: 5px 8px
CssSubtitleRenderer.get_word_size measures each letter plus a NON_CONTENT_WIDTH sentinel, and the comment there states why:
# All letters are measured without padding/borders/etc, the "NON_CONTENT_WIDTH" is used to measure the paddings/borders/etc
# So, each word must have the "NON_CONTENT_WIDTH" to include its padding/border/etc
letters = list(word.text) + ["NON_CONTENT_WIDTH"]
PictexSubtitleRenderer.get_word_size instead renders the word and returns the cropped image's size:
image = canvas.render(root_element, crop_mode=CropMode.CONTENT_BOX, scale_factor=self._scale_factor)
return (image.width, image.height)
CropMode.CONTENT_BOX crops to the content box, which by definition excludes padding. So pictex reports a glyph-only width where the layout expects width-plus-padding, and each word is placed hard against the previous one.
At 1080x1920 the scale factor is BASE_SCALE_FACTOR 2.0 * (1920 / 1280) = 3.0, so word-focus loses about 12px per side, roughly 24px between adjacent words. It reads as a total collapse rather than tight kerning.
Note render_word (line 71) uses the same crop mode. That one is arguably correct, since the drawn glyph image should not carry padding; the measurement at line 102 is where the mismatch bites.
Reproduction
renderer: pictex
template: word-focus
video: 1080x1920
Any caption with two or more words in a line. Rendered here via a downstream project, but the code path is PictexSubtitleRenderer.get_word_size directly.
Suggested direction
Make the pictex measurement include non-content width so the two renderers return comparable values. CropMode exposes SMART and NONE alongside CONTENT_BOX, so one option is measuring with a mode that retains padding while continuing to draw with CONTENT_BOX. Deriving the padding from the styled tree and adding it to the returned width would also work.
Happy to test a patch against the reproduction above.
Environment
- pycaps 0.2.1 (also present at
68a6843b, current default-branch HEAD)
- pictex 2.3.0, html2pic 0.2.2
- Python 3.12, Linux
Summary
PictexSubtitleRendererrenders multi-word captions with no gaps between words. The same template rendered withCssSubtitleRendereris correct. It fails silently: the render completes without error, so the only signal is looking at a frame.Observed with the bundled
word-focustemplate at 1080x1920. Script line "like my phone went from" renders asLikemyphonewentfrom. Also reproduces onexplosive.Cause
The two renderers disagree on what
get_word_sizeshould include, and the preset templates space words with CSS padding on the word element rather than a word-spacing property:word-focus/styles.css:padding: 4px 4pxexplosive/styles.css:padding: 5px 8pxCssSubtitleRenderer.get_word_sizemeasures each letter plus aNON_CONTENT_WIDTHsentinel, and the comment there states why:PictexSubtitleRenderer.get_word_sizeinstead renders the word and returns the cropped image's size:CropMode.CONTENT_BOXcrops to the content box, which by definition excludes padding. So pictex reports a glyph-only width where the layout expects width-plus-padding, and each word is placed hard against the previous one.At 1080x1920 the scale factor is
BASE_SCALE_FACTOR 2.0 * (1920 / 1280) = 3.0, soword-focusloses about 12px per side, roughly 24px between adjacent words. It reads as a total collapse rather than tight kerning.Note
render_word(line 71) uses the same crop mode. That one is arguably correct, since the drawn glyph image should not carry padding; the measurement at line 102 is where the mismatch bites.Reproduction
Any caption with two or more words in a line. Rendered here via a downstream project, but the code path is
PictexSubtitleRenderer.get_word_sizedirectly.Suggested direction
Make the pictex measurement include non-content width so the two renderers return comparable values.
CropModeexposesSMARTandNONEalongsideCONTENT_BOX, so one option is measuring with a mode that retains padding while continuing to draw withCONTENT_BOX. Deriving the padding from the styled tree and adding it to the returned width would also work.Happy to test a patch against the reproduction above.
Environment
68a6843b, current default-branch HEAD)