Skip to content

fix(gui): route emoji through Cairo/Pango when Qt render is transparent (tincan-jyhkd)#47

Merged
quad341 merged 4 commits into
mainfrom
feature/tincan-jyhkd
Jun 5, 2026
Merged

fix(gui): route emoji through Cairo/Pango when Qt render is transparent (tincan-jyhkd)#47
quad341 merged 4 commits into
mainfrom
feature/tincan-jyhkd

Conversation

@quad341
Copy link
Copy Markdown
Owner

@quad341 quad341 commented Jun 5, 2026

What this changes

Qt 6's software rasterizer does not paint COLRv1 glyphs (Noto Color Emoji format) to QImagepainter.drawText() produces all-transparent pixels, so encoded emoji PNGs are valid files but display nothing in the QLabel HTML renderer.

This fix adds a pixel-alpha check after Qt renders. When all pixels are transparent (COLRv1 render failed), it falls back to _render_emoji_cairo() which uses Cairo + PangoCairo → FreeType 2.11+ and handles COLRv1 natively. If Cairo is unavailable (pycairo/pygobject not installed), it falls back to html.escape(emoji) so the Qt HTML renderer shows a monochrome glyph rather than nothing.

Review notes

  • New helper _has_visible_pixels(qimage) checks alpha channel — replaces the implicit "Qt always works" assumption
  • Cairo fallback path requires pycairo + pygobject; absent libraries degrade gracefully to text
  • test_transparent_qt_render_triggers_cairo_fallback mocks _has_visible_pixels=False to force the Cairo branch independent of CI Qt capability — without this the test was environment-dependent and failed on CI hosts where Qt can render COLRv1
  • Lint-only commit (c525dd9) addresses pre-existing ruff violations across several test files to unblock CI; no behavioral change

Test plan

  • pytest tests/tincan_gui/test_emoji_img_tag.py — 15 tests pass (4 new in §5 pixel visibility)
  • Full suite: pytest tests/ — 1054 passed, 1 warning, 0 failures
  • ruff check . — All checks passed
  • Release gate: release-gates/tincan-jyhkd-gate.md
  • Operator eyeball on live app: received emoji messages should show colored glyphs

Jim Wordelman and others added 4 commits June 5, 2026 14:06
…transparent (tincan-jyhkd)

Qt 6's software rasterizer does not paint COLRv1 glyphs (Noto Color Emoji
format) to QImage — painter.drawText() produces all-transparent pixels.
The resulting PNG is a valid file but shows nothing in the QLabel HTML renderer.

Fix: after Qt renders, check pixel alpha.  If all transparent (COLRv1 render
failed), fall back to Cairo + PangoCairo which calls FreeType directly and
handles COLRv1 natively.  Last resort: plain HTML-escaped text so the Qt HTML
renderer can at least show a monochrome glyph.

Tests (§5 pixel visibility, 4 new):
  - parametrized test confirms 😀 / 👍 / ❤️ all produce non-transparent PNGs
  - interaction test confirms _render_emoji_cairo is called when Qt fails
  - fallback test updated to mock both Qt save and Cairo paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-fixed F401/I001 across test files; manually fixed remaining E501
(line-length), F841 (unused `color` variables), and F811 (duplicate
register_backend definition shadowing the first).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…failure (tincan-n3fxc)

Mock _has_visible_pixels to return False so the test forces the Cairo path
regardless of whether Qt can render COLRv1 glyphs on CI. Clear _EMOJI_CACHE
explicitly to prevent cross-test pollution from the parametrized pixel-visibility
test that runs earlier with the same (😀, 16) key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@quad341 quad341 merged commit 498205e into main Jun 5, 2026
1 check passed
@quad341 quad341 deleted the feature/tincan-jyhkd branch June 5, 2026 22:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant