Complex Text Support

[quote=“X-Ryl669”]Well choosing a compile time option means that for the vast majority of US developper, who still work in ASCII 7-bit :wink:, with no knowledge of TRANS whatsoever, still using “cout << untranslatableSentence << variableHardcoded << anotherPartOfTheEnglishSentence”, the overhead of FreeType + Harfbuzz + Fribidi (or equivalent) would be avoided.

For any other one, that’s ok to set up the compile time option, and like you’re saying, select it with a LookAndFeel.
IMHO, the glyph positionning shouldn’t be part of a look and feel of an application (semantically), but I’m probably over-pedantic here.[/quote]

That’s not what I’m saying at all. What I am suggesting is that out-of-the-box, Juce will provide a TypeLayout that supports traditional Western scripts (or whatever you call it).

If you want right to left, or any other kind of layout, you would need to do the following:

  • Download a separate source package that implements a subclass of TypeLayout
  • Download the dependencies of this separate library (for example, it might require FreeType or Harfbuzz)
  • Create a subclass of LookAndFeel in your application and set it as the default
  • In the LookAndFeel subclass, override some member “ReferenceCountedObjectPtr LookAndFeel::getTypeLayout()” to return an instance of the TypeLayout subclass that implements the new script.


  1. Current Juce users are completely unaffected
  2. Jules doesn’t have to maintain the custom TypeLayout
  3. multiple TypeLayout objects can exist at runtime within the same application
  4. No forking of code paths from a compile-time macro, everyone executes the same code (at the top level).

Design Issue #4: Should we treat all text (Simple and Complex) as Complex and pass them all to the Complex Text API?


There is a performance penalty when using a Complex Text API
This penalty is unavoidable when dealing with Complex Text
This penalty is avoidable when dealing with Simple Text, by using the regular Text API instead of the Complex Text API

My Opinion

We should use the existing regular text API when using Simple Text and only use the Complex Text API when using Complex Text

Design Issue #5: How do we determine when to use the Regular Text API or the Complex Text API?


Uniscribe has a function ScriptIsComplex to determines whether a Unicode string requires complex script processing.
CoreText does not have a similar function

My Opinion

I can think of a couple ways to do this:
Create a function to check for Complex Text by comparing the characters in a string to specific Unicode code points.
Store whether a language uses Simple or Complex Text in a language file and then change which API to use when calling LocalisedStrings::setCurrentMappings.
TheVinn has mentioned using a member in a LookAndFeel subclass.

Regardless of how it’s done, we should be able to change APIs at runtime so performance can be optimized for the language the user may select.

There is yet another choice, and that is a combination of both. Pass most of the code through a common interface, and special-case some parts.

Common interface:

  • Turn GlyphArrangement into an abstract base class, perhaps with some common functionality
  • Derived class WesternScriptGlyphArrangement absorbs the existing Juce text layout code
  • New class ComplexScriptGlyphArrangement contains all the implementation details of complex text layout, and exists outside of the Juce GIT, in it’s own separately licensed project.
  • New abstract base class TypeLayout is added, which creates GlyphArrangement objects used by common code
  • New class WesternTypeLayout subclass is provided, comes with Juce, and absorbs the existing Juce text layout code
  • New class ComplexTypeLayout contains an implementation which produces a ComplexScriptGlyphArrangement, and goes in the separately licensed project


  • TextEditor is left alone
  • new ComplexTextEditor is written from scratch to fulfill the more demanding layout needs.
  • ComplexTextEditor exists outside of the Juce GIT in its own separately licensed project

Advantages of this approach:

  • Minimum change required to Juce
  • Existing users are not affected
  • Jules’ programming burden is limited only to abstracting the layout of text
  • Modifications to the TextEditor can be made without disturbing complex text layout
  • Maintenance of complex layout code is done by the people who use it the most (those who read right to left)

I agree with that.

I am not sure these classes are really needed as layout code mostly resides in GlyphArrangement and PositionedGlyph. I’m not exactly sure what you’d put into a WesternTypeLayout class.

That could work.

The other things that need to be addressed is:
Font::getStringWidth, font::getGlyphPositions - Maybe we can create complex versions of these and add them to Font
CustomTypeface::getStringWidth, CustomTypeface::getGlyphPositions - Maybe we can create complex versions of these and add them to CustomTypeface
Where to put the native API calls to Uniscribe and CoreText? The place that makes the most sense is with the rest of the platform dependent CustomTypface code inside native/windows/juce_win32_Fonts.cpp and native/mac/

I’m not a big of a fan of Fribidi due to it being licensed under the LGPL so I’m interested to know if a BSD licensed bidi algorithm exists.[/quote]
For example you have: UCPGA, “Pretty Good Bidi Algorithm”, from the UCData lib

I’m not fond of out-of-tree code. Due to the speed Juce evolves, and unless there is someone dedicated to this task, both trees will diverge, and then it’ll be a pain to the user.
If I had choice, I would prefer in-tree modification. After all, we can send our code to Jules, he’ll include it, and then later, whenever he changes the String class, or the TextEditor, he can ensure everything compiles.
Then, as usual, we would report bug, if any found, and he’ll fix them, like he always did.

Found this topic was accidental when I searched for something. I agree with the authors of some of the arguments.

All along, JUCE program text appearance and the appearance of the native program’s text is inconsistent, which makes me very confused. Perhaps OSX and Linux platforms looks good, but feel really weird in the Windows platform. I have raised this issue but since I don‘t know how to correct the description. I once thought that all cross-platform C++ class library is such…until one day I met wxWidgets, changed my opinion. But, I have throw into JUCE too much energy and time, I have no courage and confidence to study wxWidgets.

I’m always concerned about how to make JUCE program text looks exactly the same appearance of native programs. (Or, how to make JUCE text rendering using Windows GDI rendering?)

However, I don’t understand that this very important issue why has not become a priority agenda of Jules? Too difficult or too much work it? Compared to the huge JUCE library, this should be nothing, right?

I don’t understand these knowledge even more, maybe I just from a user’s perspective and not from programmers perspective on this problem. if my words wrong or unpleasant, I apologize.

I’m only guessing here, but I’m pretty sure it was never Jules intention to make JUCE programs look like native OS programs. If you want native text and native widgets, you really should be looking to wxWidgets or QT.
I highly doubt Jules will ever write any sort of GDI rendering himself. Its an old and deprecated API so there is not much point.
If you really want GDI rendered text in a JUCE program, it should be possible, by writing your own GDI LowLevelGraphicsContext.

I think native Windows text will eventually make it’s way into Juce. Once Windows 8 comes out, Jules will probably finally finish the Direct2D LowLevelGraphicsContext as D2D is the only 2D graphics API available on Windows 8 ARM. At that point all text will be rendered using Direct2D/DirectWrite just like the rest of Windows 8.

Thanks for your suggestions and reminders.

JUCE widgets really feels pretty if user can adapt to, I don’t like the gray monotony, boxy of Windows things yet. The only dissatisfied was JUCE text, it seems somewhat vague.

In contrast, I’m more interested in JUCE. I don’t have enough capacity at present to contribute the development and expansion JUCE, I would prefer to continue to helplessly waiting for. hoping that one day, JUCE text can be clearer, sharper. This should be a lot of people Shared desire.

This is my impression as well. Where Juce really shines is when you want to have all the controls in your app be custom-designed.

My opinion, the main useful purpose of the default look of the Juce controls is to be able to get something up on the screen quickly, or when you don’t care too much about how it looks.