Problem with drawing AttributedString under Windows


#1

I am on the latest tip from today and have issues with some asian characters not being drawn correctly when using AttributedString.

 

The character I need to draw has the UTF8 byte sequence F0 A9 AA 97. I can see in the debugger that the byte sequence shows up correctly in the data member of my juce::String. Then I do basically the following:

 

juce::AttributedString aS(textToDraw);

aS.setFont(Font("Arial Unicode MS", 24, Font::bold));

aS.draw(g, Rectangle<float>(x, y, width, height);

All I get is a square character as a kind of replacement character.

x, y, width, height are set to correct values, and all other texts I tried to draw this way did show up correctly in the GUI, even all Asian test strings that I got, except the mentioned one above. I am wondering why this is, because all other applications I tried have no problem to show the correct asian glyph with that UTF8 encoding (eg. Notepad++ or some audio editing software I tried).

I have Direct Write support enabled.

Do you have any idea what is going wrong here? Do you need more information to reproduce?


#2

Can someone confirm this problem? Do I need to supply more information for reproducing this?

My understanding was that the underlying font rendering system should automatically select a font that is capable of rendering the given Unicode glyph. Is that correct?


#3

Hi - can you post us a complete code snippet that we can use to reproduce it, please, and we'll take a look!


#4

Hi,

given you have a juce::Graphics g to paint on, you can execute the following code:



  AttributedString aS(CharPointer_UTF8("\xF0\xA9\xAA\x97"));
  aS.setJustification(Justification::left);
  aS.setWordWrap(AttributedString::none);
  aS.setFont(Font("Arial Unicode MS", 24, Font::bold));
  aS.setColour(Colours::white);

  aS.draw(g, Rectangle<float>(0, 0, 100, 100));

 

This should draw an Asian character. Instead, a square replacement character is drawn. You can paste the hex codes into an hex editor and open the resulting file with UTF-8 encoding in Notepad++ to see the glyph that was expected. It seems that there are a lot of glyphs affected, but the given byte sequence is one example to reproduce the problem.

 


#5

Is there definitely a bold version of Arial Unicode MS? Could be that the problem is just that you're not actually using the font that you think you are..

A good test would be to go into the juce demo fonts page, select Arial Unicode MS and paste this character into the textbox. If that displays OK then it must be that this isn't actually using the right font.


#6

You are right that the font is not containing this character.

However, should AttributedString not automatically fall back to an installed font containing the character? If not, what would be the correct way to draw this? I receive international UTF-8 strings from several sources and I need to draw them with a preferred font, and if not possible with any fall-back font on the system capable of drawing the character.


#7

It's complicated.. To do that depends on the OS calls that we're using - there are some platforms where it'll do that, but others where it's not even possible to find out whether a character is missing from a font. It's something we need to look into to try to find a solid cross-platform solution.


#8

That's interesting. I have been using this technique with the AttributedString for some time now on both Windows and Mac and everything was fine. Specifically, I was using the "Segoe UI" font set in AttributedString, but I was able to draw Japanese and Chinese strings with it - although Segoe UI is not containing any of those Asian characters. So, I was under the impression that AttributedString indeed uses font fall-back, and the characters like the one I reported above might just lead to a bug in this mechanism.

Should the font fall-back work with a Windows build of Juce? Or what other platform dependencies come into play?


#9

There are lots of combinations of OS and font-rendering API and I can't actually remember the exact details of how they all work.. It's on our list of things to look into.


#10

I am also having similar problem. I had been using the "Arial Unicode MS" in OSX and Windows to display Chinese Characters since beginning of 2014 for my JUCE application. And it was working perfectly well. But recently, I discovered that this stop working anymore.

I tried to use JuceDemo and it is true that Arial Unicode MS does NOT display my chinese characters anymore. Maybe the characters are not in the fontset anymore. When I made my application in 2014, I had use FontBuilder to made up an older version of Arial Unicode MS font from OSX (actually save up for platforms that do not have Arial Unicode MS font). And if I load this previously generated font as embedded binary, things are back to normal. But my problem is that I need to embeded this big set of binary into my application and it takes up quite some space.

However, I just found out that in Introjucer,  the code editor can display all my Chinese characters perfectly. I tried to look into what font type it use, and try to use the same for my application. In Appearance Settings, it is using "Courier New" and all Chinese characters show up okay. 

I tried to test the same on JuceDemo, and in the font demo, I pick "Courier New", but my Chinese characters does NOT work there. And of course, when I use that font in my application. My application does NOT work. 

Would like to know what setup in Introducer that will make Chinese characters works? I tried to look into the jucer_SourceCodeEditor and jucer_AppearanceSettings classes, but could not see anything special there. Could anyone one point me to the correct direction.

Thanks!

 


#11

I'm on Windows 8.1 and the following code works for me (i.e. displays a chinese character):


    g.fillAll (Colours::white);
    g.setColour (Colours::black);
    g.setFont (Font("Arial Unicode MS", 24, Font::bold));
    g.drawText (TRANS(CharPointer_UTF8("\xF0\xA9\xAA\x97")),
                        12, 12, 200, 30,
                        Justification::centred, true);

Can you test this?


#12

Hi Fabian,

Thanks for your info.

I tried it on Mac and nothing show up at the location, just blank. No matter I am using the system "Arial Unicode MS" or my "embedded Arial Unicode MS", nothing show up. 

However, if I don't use TRANS(CharPointer_UTF8("\xF0\xA9\xAA\x97"))  and just use my input method to type in L"Chinese char",  then using embedded font is working fine. But system font still not showing up anything. I think the compiler can interpret the my UTF8 input correctly.

 


#13

Hi, here are my test:

Linux Ubuntu 14.04.02:

OSX 10.95

Windows 7


#14

And... although Introjucer can display non-English characters (such as Chinese, Japanese etc.), the caret moving isn't correct, especially when you're draging mouse to select the non-English characters...

JUCE can't display any non-English characters by default, but It is curious that its AlertWindow can...

BTW, characters are art, not only the computerization shapes. I've never seen the characters so ugly the 'Arial...' font displayed, for example the Chinese characters, particularly when it was used under JUCE.

I've downloaded the free Tracktion 4, try to see how the characters displayed. It was awful too. After I switched the language to Chinese, I nearly wail, it was so ugly, the translation's quality was so miserable, I can't stand any more...

Sorry to tell the truth.