Embedding unicode string literals in your cpp files

...maybe I'm struck with blindness, but when I put

g.setFont (Font ("MusicalSymbols", 32.0f, Font::plain));
g.setColour (Colours::white);
const juce_wchar myUnicodeString[] = { 0x00D11E, 0x000000, 0 }; // 1D11E
String s (myUnicodeString);
g.drawText (s, getLocalBounds(), Justification::centred, true);

into the Hello World, I don't see anything. And this is with the standard font and with some other free musical fonts I downloaded...

I also tried 0x001234, 0x005678 and several other combinations... Sorry, probably I think too complicated?

That says 0xd11e, not 0x1d11e (?)

I've no idea about the unicode chars you actually need or which ones are in your font, but this is just showing you how to turn extended unicode chars into a string.

..ok, typo in the example, from trying several combinations. But that didn't help. The symbols I am after are defined in unicode standard Rev. 8, as described in the link I posted before: http://www.unicode.org/charts/PDF/U1D100.pdf

What confuses me also is, that your example had three bytes. I remember that UTF32 is always multibyte, so that was the moment I was insecure. At least I know now, that it "should" print something.

Thanks for your time.

I tried to write a geometric shape symbol inside a textbutton and didn't work as it worked when I used it before.

Why isn't this method working anymore ?

 

Edit : It works but not when I choose "Arial Unicode MS" font type.

Did it use to work before with that specific font type?

Yes, it worked well.

Anyway, now I'm using " Segoe UI Symbol " font type and it has a huge variety of symbols if anyone else needs it. ;)

It does not work for me.

I don’t think current versions of Windows have a Arial Unicode MS font, so you would use “Arial”.

Anyway it’s generally not possible to display arbitrary unicode in Juce, because (1) it uses a very outdated way to render text, and (2) the design of the look-and-feel system makes it hard to globally override the default font in widgets.

It also does not work with “Arial”.
Windows 10 have a Arial Unicode MS font, but juce seems not to supoort it.

Hi Folks,

Thought I’d pitch in on this old thread, as I’ve been unpicking all the UTF-8 / font issues for myself while localising Wotja.

To compile for Windows, such that the Source Code is compiled as UTF-8, simply define this compiler flag:
/utf-8

You can then do stuff like this (provided you’re compiling for C++17 or later).
auto myString = juce::String::fromUTF8(u8"攟束");

That is Simplified Chinese, BTW.

This code works 100% fine for iOS, macOS, Windows and Android.

To force use of the correct font, implement something like this in your LookAndFeel class.
Sorry about the layout :slight_smile:

This works for all of iOS, macOS, Windows and Android (at least for me, anyhow!).
You’d have to expand it to handle other locales/fonts.

virtual juce::Typeface::Ptr getTypefaceForFont (const juce::Font& font) override {

  #if defined(IM_TARGET_IOS)
  juce::String locale =  juce::SystemStats::getDisplayLanguage();

  if (locale.startsWith("zh")) {
    juce::Font f(font);
    f.setTypefaceName("PingFang SC");
    return juce::Typeface::createSystemTypefaceFor(f);
  }

  #elif defined(IM_TARGET_MACOS)

  juce::String locale =  juce::SystemStats::getDisplayLanguage();

  if (locale.startsWith("zh")) {
    juce::Font f(font);
    f.setTypefaceName("PingFang SC");
    return juce::Typeface::createSystemTypefaceFor(f);
  }

  #elif defined(IM_TARGET_WINDOWS)

  // See https://forum.juce.com/t/font-woes-again-chinese/23832

  juce::String locale =  juce::SystemStats::getDisplayLanguage();

  if (locale.startsWith("zh")) {
    juce::Font f(font);
    f.setTypefaceName("Microsoft YaHei");
    return juce::Typeface::createSystemTypefaceFor(f);
  }
  #endif //

  return lookAndFeel.juce::LookAndFeel_V3::getTypefaceForFont(font);
}

Pete

4 Likes

Thanks Pete!

The other important thing for people to note is that they also need to make sure their text editor is saving the file as UTF8. There’s not much point telling the compiler to treat it as UTF8 if the editor actually dumped it as some other codepage format!

(And you can make your code readable by surrounding it with triple-backticks or just indenting it all be 4 spaces)

Thanks Jules - I’ve just tidied-up my example code. I’d suggest you maybe add some or all of the above to the code generated by the Introjucer! :wink:

Pete

Still this code is not working if you display Chinese characters on an English system


Hi - which platform are you having problems with?

I found that I had to override a lot of LookAndFeel methods, to force use of the correct font to match the current Locale.

See also this post, if you’re using Windows:

Pete

dont think is a good idea if the user wants to select they favorite language;

Hi! Well, what I put in place does work. Also, we allow the user to override the display language if they so wish through the Wotja menu system; which is also a really helpful feature for testing.

dont very understand

could you show me a complete example?
thanks

the char problem is a headache 

It’s strange use a code “CharPointer_UTF8 (”\xe4\xb8\x80\xe4\xba\x9b\xe6\x96\x87\xe5\xad\x97"); everywhere like this

qt will have a locaze function globally


I know this is an old thread, but thought I’d add my latest code
 as we now support Japanese, and this whole area is tricky to get right. I hope it helps somebody!

juce::String WJX_StringLocale::sGetTypefaceNameForCurrentLocale(bool isMonospaced) {
  
#if defined(IM_TARGET_IOS) || defined(IM_TARGET_TVOS)
  auto&& locale = WJUI_StringLocale::sGetLocale();
  if (locale.hasPrefix("zh")) {
    return "PingFang SC";
  } else if (locale.hasPrefix("ja")) {
    return "Hiragino Sans";
  } else {
    return ".SFUIText";
  }
#elif defined(IM_TARGET_MACOS)
  auto&& locale = WJUI_StringLocale::sGetLocale();
  if (locale.hasPrefix("zh")) {
    return "PingFang SC";
  } else if (locale.hasPrefix("ja")) {
    return "Hiragino Sans";
  } else {
    auto macOSVersionNumber = NSAppKitVersionNumber;
    if (floor(macOSVersionNumber) <= NSAppKitVersionNumber10_12) {
      // On a 10.12.x or earlier system ... i.e. Sierra!
      return "Heletica Neue";
    }
    return ".AppleSystemUIFont";
  }
#elif defined(IM_TARGET_WINDOWS)
  if (isMonospaced) {
    return "Consolas";
  }

  auto&& locale = WJUI_StringLocale::sGetLocale();
  if (locale.hasPrefix("zh")) {
    return "Microsoft YaHei"; // Chinese font
  } else if (locale.hasPrefix("ja")) {
    return "Yu Gothic UI";    // Japanese font
  }

  // Default case: English font
  // Note: "Segoe UI Symbol" supports the Unicode tick if you need it.
  return "Segoe UI";
#else // IM_TARGET_ANDROID
  return "Roboto";
#endif //
}

juce::Typeface::Ptr WJX_StringLocale::sGetTypefaceForFont(juce::LookAndFeel_V3& lookAndFeel, const juce::Font& font) {

  juce::Font f(font);
  if (font.getTypefaceName() == "<Monospaced>") {
    // This is the Code Editor case...
#ifdef IM_TARGET_WINDOWS
    f.setTypefaceName(sGetTypefaceNameForCurrentLocale(true)); // true means - monospaced
#else // IM_TARGET_WINDOWS
    f.setTypefaceName(juce::Font::getDefaultMonospacedFontName());
#endif // IM_TARGET_WINDOWS
  } else {
    f.setTypefaceName(sGetTypefaceNameForCurrentLocale());
  }
  return juce::Typeface::createSystemTypefaceFor(f);
}
3 Likes

Hi @t0m just FWIW, you might want to consider putting something like the above in a future JUCE update. The macOS font selection by JUCE “out of the box” is never quite right :slight_smile: and for Chinese / Japanese, it is essential to use the correct font especially for Windows.

Best wishes, Pete