Skip to content

qt: Preserve complex script ligatures and shaping in kdenlivetitle - #1334

Open
keashan wants to merge 6 commits into
mltframework:masterfrom
keashan:work/complex-script-titler-shaping
Open

keashan wants to merge 6 commits into
mltframework:masterfrom
keashan:work/complex-script-titler-shaping

Conversation

@keashan

@keashan keashan commented Oct 2, 2026

Copy link
Copy Markdown

Summary

qt: Preserve complex script ligatures and OpenType shaping in kdenlivetitle producer.

Related Bug Report

Verification & Language Testing

  • Sinhala Verification: Explicitly tested and verified with Sinhala complex script title clips (ශ්‍රී) and confirmed working cleanly during preview and export.
  • Formatted with clang-format.

@j-b-m

j-b-m commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Thanks for this proposal. However I am about to merge a rather important change to the Kdenlive titler to allow rich text formatting, allowing to have different font styles in each element:
#1308

It would be great to rebase this work on top of this change. @klg90 I would be interested to also have your input about how to integrate this into your changes.

@keashan
keashan force-pushed the work/complex-script-titler-shaping branch from 037e7e4 to 24f8995 Compare October 2, 2026 10:14
@keashan

keashan commented Oct 2, 2026

Copy link
Copy Markdown
Author

Thanks @j-b-m ! I have successfully rebased this PR on top of @klg90's rich text branch (klg90:kdenlivetitle-richtext / PR #1308) and verified clean compilation.

Both rich text formatting and standard title clips in MLT now preserve full HarfBuzz complex OpenType script shaping (Sinhala Rakaransaya ligatures, Indic conjuncts, and Arabic cursive joining) with LayoutDirectionAuto.

@klg90

klg90 commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Thanks @j-b-m ! I have successfully rebased this PR on top of @klg90's rich text branch (klg90:kdenlivetitle-richtext / PR #1308) and verified clean compilation.

Both rich text formatting and standard title clips in MLT now preserve full HarfBuzz complex OpenType script shaping (Sinhala Rakaransaya ligatures, Indic conjuncts, and Arabic cursive joining) with LayoutDirectionAuto.

Nice, thanks for rebasing it on top of my branch! Glad it's working with both rich text and standard titles. I'll take a look at the changes and see if I notice anything with the integration.

@klg90 klg90 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for rebasing this on top of my branch. I looked through the diff and the shaping approach looks useful, but I found a few regressions caused by the new PlainTextItem rendering path.
The main ones I found:

  • gradients get reduced to a single color because the new fill path uses m_brush.color() instead of preserving the full brush
  • outlines no longer seem to be rendered as a true glyph stroke with the new QTextLayout::draw() pass
  • the existing custom tab width handling is removed, so saved tab spacing is no longer respected
  • shadows are built from a separate shaped path, so alignment/position can diverge from the visible text
Image

I also noticed the new image cache starts at (0, 0) with no ink-bounds padding, which can clip glyphs that extend left of the logical origin, like some italic characters.
I tested these as focused Qt rendering cases rather than a full MLT/Kdenlive integration run. I think the shaping fix itself is worth keeping, but it would be good to preserve the existing gradient, outline, tab and shadow behavior while using the shaped layout data.

Refactor PlainTextItem to populate QPainterPath directly using HarfBuzz-shaped
vector glyph runs via appendShapedText().

This preserves HarfBuzz complex OpenType script shaping (Sinhala Rakaransaya,
Indic conjuncts, and Arabic cursive joining) while fully preserving:
- Multi-color linear/radial gradients (QBrush)
- True stroke path outlines (painter->strokePath)
- Custom tab width calculations (m_tabWidth)
- Aligned drop shadow path geometry
- Italic glyph ink bounds without QImage clipping
@keashan
keashan force-pushed the work/complex-script-titler-shaping branch from 24f8995 to 3f18566 Compare October 4, 2026 03:32
@keashan

keashan commented Oct 4, 2026

Copy link
Copy Markdown
Author
11

Thanks @klg90 for the detailed feedback and test cases! You were completely right.

I have updated the PR to remove the intermediate QImage wrapper. Instead, PlainTextItem now populates m_path directly with HarfBuzz-shaped vector glyph runs using appendShapedText().

This resolves all 5 reported regressions:

  1. Gradients: m_brush is passed directly to painter->fillPath(m_path, m_brush), preserving full linear/radial gradient brushes.
  2. Outlines: painter->strokePath(m_path.simplified(), m_pen) restores true path stroke outlines.
  3. Custom Tabs: Restores m_tabWidth tab geometry calculations.
  4. Shadows: Drop shadows build directly from m_path, ensuring 100% geometry alignment.
  5. Italic Bounds & Clipping: Removed the QImage buffer, so italic font ascenders/descenders are no longer clipped.

Complex script OpenType shaping (Sinhala Rakaransaya ligatures ශ්‍රී, Indic conjuncts, Arabic cursive joining) remains 100% active. Verified locally in Kdenlive title clips.

@ddennedy ddennedy added this to the v7.44.0 milestone Oct 4, 2026
@klg90

klg90 commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Thanks for addressing the issues from my previous review. I went back and compared the current implementation against the pre-shaping PlainTextItem behavior so I could separate regressions from limitations that were already there.
A couple of the things I previously mentioned, particularly the whitespace/tab edge case and some of the negative-bearing bounds behavior, appear to predate this change, so I don't think it's fair to count those against this PR.
There are still some behavioral differences from the previous renderer that concern me, particularly around baseline positioning, text decorations such as underline, and alignment.
At this point, rather than continuing to find these cases individually through review iterations, I'd like to see broader regression testing included with the change. Since this replaces a fairly fundamental part of the PlainTextItem rendering path, I think the contributor-side testing should exercise the existing behavior that isn't intentionally changing: positioning/alignment, decorations, gradients, outlines, shadows, tabs, multiline text, italic/overhanging glyphs, font fallback, and combinations of those features.
Since the purpose of this PR is complex-script shaping, I'd also like the shaping coverage to go beyond a single example and include a representative set of widely used scripts with large real-world user bases. At minimum, representative cases across Sinhala; Devanagari and a few other major Indic scripts such as Bengali, Tamil, Telugu and Malayalam; Arabic and Urdu; Simplified/Traditional Chinese; Japanese kana/kanji; and Korean Hangul would be useful.
The goal isn't exhaustive coverage of every writing system or every possible font. It's to exercise the major shaping behaviors users are likely to encounter in practice: combining marks, conjuncts and ligatures, RTL joining, contextual shaping, CJK glyph coverage, punctuation, multiline text, font fallback, and different fonts/font sizes where practical.
I'm not expecting every possible title, language, font, or effect combination to be tested, and I understand that text shaping has a lot of difficult edge cases. What I'm looking for is a systematic attempt to exercise the new path broadly enough that review isn't the primary mechanism for discovering regressions in each revision.
The complex-script shaping fix itself is valuable and I'd like to see it land. I'm happy to review another revision once that regression coverage is in place, but I don't think I'm comfortable approving the rendering-path replacement without it.
image

This branch has not been deployed

No deployments
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.

4 participants