# AttributedString: Character Counting Bug with Font Ligatures

**URL:** <https://forum.juce.com/t/attributedstring-character-counting-bug-with-font-ligatures/65355>\
**Category:** General JUCE discussion\
**Created:** [February 26, 2025, 12:13pm UTC](https://forum.juce.com/t/attributedstring-character-counting-bug-with-font-ligatures/65355 "2025-02-26T12:13:48Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![martinrobinson-2](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/martinrobinson-2/32/630_2.png) [@martinrobinson-2](https://forum.juce.com/u/martinrobinson-2)\
**Post date:** [February 26, 2025, 12:13pm UTC](https://forum.juce.com/t/attributedstring-character-counting-bug-with-font-ligatures/65355/1 "2025-02-26T12:13:48Z")

</div>

Here’s a fun one! In JUCE 8 I am experiencing what looks like a bug to do with font ligatures (e.g., a combined ‘ff’ into a single shape in some fonts). I’ve narrowed it down to this example using Proxima Nova:

```auto
#include <JuceHeader.h>

class MainComponent : public Component
{
public:
    MainComponent()
    {
        auto fonts = Font::findAllTypefaceNames();

        if (! fonts.contains ("Proxima Nova"))
            throw std::runtime_error (
                "\nPlease install the 'Proxima Nova Regular.otf' font to reproduce this example. See: \n"
                "https://github.com/roshinthomas/Proximanova-fonts/blob/master/Proxima%20Nova%20Regular.otf");

        Font font ("Proxima Nova", 18.0f, Font::plain);

        string.append ("Hello, World!\n", font.withHeight (36.0f).withStyle (Font::bold), Colours::black);
        string.append ("Different, World!\n", font, Colours::red);
        string.append ("Why is 'W' in 'Why' red?\n", [font] () mutable{ font.setTypefaceName ("Arial"); return font; }(), Colours::blue);
        string.append ("Is it the 'ff' ligature throwing off the counting?\n", font, Colours::red);

        setSize (320, 240);
    }

    ~MainComponent() override = default;

    void paint (Graphics& g) override
    {
        g.fillAll (Colours::lightgrey);
        string.draw (g, getLocalBounds().reduced (20).toFloat());
    }

private:
    AttributedString string;
};

```

I’m testing this with JUCE 8 [using latest develop](https://github.com/juce-framework/JUCE/tree/389516feeb632adb5d20b111cf4c6fa45632c9d8).

(I’m deliberately using the deprecated `Font` constructor so I can show this doesn’t happen in JUCE 7, using the `FontOptions` constructors yields the same results in JUCE 8.)

As the text suggest, the ‘W’ in the first ‘Why’ on line 3 is carried on in red from the previous line (and ‘I’ on the last line continues in blue):

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/3X/1/2/121e7a084d75515a3b5e257c488064c4b95bbf7f.png)

Using JUCE 7.0.12 it renders correctly:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/3X/7/5/75e970aa60246a98950119a6d8fefb537e292ca7.png)

---

<div class="post-metadata">

**Author:** ![attila](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/attila/32/11206_2.png) [@attila](https://forum.juce.com/u/attila)\
**Post date:** [February 27, 2025, 12:28pm UTC](https://forum.juce.com/t/attributedstring-character-counting-bug-with-font-ligatures/65355/2 "2025-02-27T12:28:58Z")

</div>

Thank you reporting this issue and providing the example code. This is indeed a problem caused by mishandling the ligature. We are working on a fix.

---

<div class="post-metadata">

**Author:** ![martinrobinson-2](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/martinrobinson-2/32/630_2.png) [@martinrobinson-2](https://forum.juce.com/u/martinrobinson-2)\
**Post date:** [March 13, 2025, 3:20pm UTC](https://forum.juce.com/t/attributedstring-character-counting-bug-with-font-ligatures/65355/3 "2025-03-13T15:20:48Z")

</div>

I see some related commits on develop today, is it worth giving this a try or is this still in progress?

---

<div class="post-metadata">

**Author:** ![attila](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/attila/32/11206_2.png) [@attila](https://forum.juce.com/u/attila)\
**Post date:** [March 13, 2025, 6:07pm UTC](https://forum.juce.com/t/attributedstring-character-counting-bug-with-font-ligatures/65355/4 "2025-03-13T18:07:39Z")

</div>

Yes, these changes should also fix the problem described in this thread. Although you might want to wait for a C++20 fix that’s arriving soon. I’ll update this thread when it’s out.

---

<div class="post-metadata">

**Author:** ![martinrobinson-2](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/martinrobinson-2/32/630_2.png) [@martinrobinson-2](https://forum.juce.com/u/martinrobinson-2)\
**Post date:** [March 14, 2025, 8:38am UTC](https://forum.juce.com/t/attributedstring-character-counting-bug-with-font-ligatures/65355/5 "2025-03-14T08:38:59Z")

</div>

Great thanks, yeah I had to change the lamdba arguments for `std::accumulate()` to `auto, const auto&` in two places for our build system…

```auto
diff --git forkSrcPrefix/modules/juce_gui_basics/widgets/juce_TextEditor.cpp forkDstPrefix/modules/juce_gui_basics/widgets/juce_TextEditor.cpp
index 37742feea7f9ea1a979b1a36b21aeb27176a4151..5140fd839b4b21622935efa115f4079a52dc49b1 100644
--- forkSrcPrefix/modules/juce_gui_basics/widgets/juce_TextEditor.cpp
+++ forkDstPrefix/modules/juce_gui_basics/widgets/juce_TextEditor.cpp
@@ -106,7 +106,7 @@ struct TextEditor::RemoveAction final : public UndoableAction
         return std::accumulate (removedText.texts.begin(),
                                 removedText.texts.end(),
                                 0,
- [] (auto& sum, auto& value)
+ [] (auto sum, const auto& value)
                                 {
                                     return sum + (int) value.getNumBytesAsUTF8();
                                 });
diff --git forkSrcPrefix/modules/juce_graphics/detail/juce_SimpleShapedText.cpp forkDstPrefix/modules/juce_graphics/detail/juce_SimpleShapedText.cpp
index 227edd00d36ab1fa46505d05944b49a820c9ee71..e560cab37955c1aa2e60a0d077df2da114d7176e 100644
--- forkSrcPrefix/modules/juce_graphics/detail/juce_SimpleShapedText.cpp
+++ forkDstPrefix/modules/juce_graphics/detail/juce_SimpleShapedText.cpp
@@ -1320,7 +1320,7 @@ void SimpleShapedText::shape (const String& data,
                                                         glyphSpansInLine.end(),
                                                         std::make_pair (std::numeric_limits<int64>::max(),
                                                                         std::numeric_limits<int64>::min()),
- [&] (auto& sum, auto& elem) -> std::pair<int64, int64>
+ [&] (auto sum, const auto& elem) -> std::pair<int64, int64>
                                                         {
                                                             const auto r = elem.textRange + lineRange.getStart();
 

```

---

<div class="post-metadata">

**Author:** ![attila](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/attila/32/11206_2.png) [@attila](https://forum.juce.com/u/attila)\
**Post date:** [March 14, 2025, 11:04am UTC](https://forum.juce.com/t/attributedstring-character-counting-bug-with-font-ligatures/65355/6 "2025-03-14T11:04:03Z")

</div>

A fix is out on `develop`

> <https://github.com/juce-framework/JUCE/commit/432a7e1c9a2fa0b570bdd382643f7becdbef30fc>
