From 8693507ead6662aa604516722f09fd364e4f82eb Mon Sep 17 00:00:00 2001 From: attila Date: Tue, 15 Oct 2024 14:05:10 +0200 Subject: [PATCH] ShapedText: Apply extra kerning only before clusters This avoids inserting tracking between glyphs in a single cluster e.g. a base glyph and diacritic marks. --- modules/juce_graphics/fonts/juce_SimpleShapedText.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/juce_graphics/fonts/juce_SimpleShapedText.cpp b/modules/juce_graphics/fonts/juce_SimpleShapedText.cpp index 3be1acdc9f..d4d8ea3be8 100644 --- a/modules/juce_graphics/fonts/juce_SimpleShapedText.cpp +++ b/modules/juce_graphics/fonts/juce_SimpleShapedText.cpp @@ -504,6 +504,8 @@ static std::vector lowLevelShape (const String& string, std::vector characterLookup; std::vector glyphs; + std::optional lastCluster; + for (size_t i = 0; i < infos.size(); ++i) { const auto j = (embeddingLevel % 2) == 0 ? i : infos.size() - 1 - i; @@ -528,12 +530,18 @@ static std::vector lowLevelShape (const String& string, && font.getTypefacePtr()->getGlyphBounds (font.getMetricsKind(), (int) glyphId).isEmpty() && xAdvance > 0; + // Tracking is only applied at the beginning of a new cluster to avoid inserting it before + // diacritic marks. + const auto appliedTracking = std::exchange (lastCluster, infos[j].cluster) != infos[j].cluster + ? trackingAmount + : 0; + glyphs.push_back ({ glyphId, (int64) infos[j].cluster + range.getStart(), (infos[j].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) != 0, whitespace, - Point { HbScale::hbToJuce (xAdvance) + trackingAmount, -HbScale::hbToJuce (positions[j].y_advance) }, + Point { HbScale::hbToJuce (xAdvance) + appliedTracking, -HbScale::hbToJuce (positions[j].y_advance) }, Point { HbScale::hbToJuce (positions[j].x_offset), -HbScale::hbToJuce (positions[j].y_offset) }, }); }