setFallbackFontName broken?


#1

Hi There,
It seems that the setFallbackFontName seems to broken again.
This feature has been broken and fixed a couple of times.

We set the fallback like this:
Font::setFallbackFontName(“Arial Unicode MS”);
I looked in the Juce code and it seems this typeface is actually already set as default.

When i try to display filenames with Japanese characters Juce tries first to find the Glyph in the default ‘Lucida Grande’ and it it fails it should try finding the glyph in the fallback font.
When i have a filename with these japanese characters:
ように定義.mov

It displays like you see in the screenshot below.
The screenshot is taken from the DragAndDrop example in the JuceDemo (compiled with the code from the tip).

Tested on OSX 10.6.7


Current state of Fonts/Emoji/Unicode symbols
#2

Yes, when I moved to the CoreGraphics text renderer, it basically made it awkward/impossible to use a custom fallback font - I was trying to find a workaround but had no luck…


#3

Jules, could you tell me in which part of the code i can find the CoreGraphics text rendering so i can have a look myself?
You should have really put a ‘jassertfalse’ in the setFallbackFontName method.
It’s really annoying that lost a couple of hours trying to find out what is wrong with code that always worked fine to find out you left it unfinished.

Does someone has suggestions on what kind of mechanism they would use since the fallback does not work?
Thinks i can think off would be this:

  • Switch back to Software Renderer, this should work with the fallback right?
  • Use ‘Arial Unicode MS’ for all text rendering so it doesn’t need the fallback, but well that would be just plain ugly.
  • Use The Vinn’s freetype renderer, does this have a fallback?

#4

Sorry - you’re right, I should have added an assertion. :oops:

The problem is that in MacTypeface::getGlyphPositions(), it converts characters to glyphs by directly passing the string to the OS functions - and if some of those glyphs aren’t available in the font, the system doesn’t tell you, it just replaces them with defaults. I couldn’t find any way around this - it’s not even possible to manually go through a string and ask the OS whether each glyph exists or not… I’m a bit stuck as to what could be done about it!


#5

I had a dig around and found some info on how to work with a fallback (cascade they call it) font on OSX. But i just realized this functionality is broken on Windows as well.
Could you have a look to see what’s wrong on the Windows side of this.
Test:
I used the Demo to test how files with Japanese characters are shown using the Treeviews (FileTreeComponent showing the filesystem) example.
All Japanese characters show up blank.

Could you give some clarity on this, we have a cross-platform multi-language piece of software that sells in 70 countries which had proper support for these kind of characters which JUCE supported just out of the box (which i think is a really great feature).
Jules, please don’t tell me you dropped support for the fallback method altogether!
Don’t tell me i have to start writing this myself now, i would be lost ;-(


#6

Are you setting a fallback font that definitely includes japanese characters? I’m pretty sure it was working ok last time I checked.


#7

We are using “MS UI Gothic” on Windows and “Arial Unicode MS” on OSX.
Just to be clear on this, we have successfully used those fonts as fallback for two years already.

We use the 1.53 stable release for development, but i also just checked with the tip (like i always do) and does not work either.

I got the tip like this:
git clone --depth 1 git://juce.git.sourceforge.net/gitroot/juce/juce

I then opened the JuceDemo project and added the fallback method to initialise.

    void initialise (const String& /*commandLine*/)
    {
	Font::setFallbackFontName("MS UI Gothic");

      #if JUCE_IOS || JUCE_ANDROID
        theMainWindow.setVisible (true);
        theMainWindow.setFullScreen (true);
      #else
        theMainWindow.centreWithSize (700, 600);
        theMainWindow.setVisible (true);
      #endif

        // this little function just demonstrates a few system info calls
        Logger::outputDebugString (collectSomeSystemInfo());

        /*  on return from this method, the app will go into its the main event
            dispatch loop, and this will run until something calls
            JUCEAppliction::quit().

            In this case, JUCEAppliction::quit() will be called by the
            demo window when the user clicks on its close button.
        */
    }

I than navigate to a file with Japanese characters using the FileTreeComponent example (TreeViews) and it shows up blank.
I you go the ‘Fonts and Text’ demo and you select 'MS UI Gothic" from the list and enter the following characters ‘漢字仮名交’ (same characters as in the filename) it renders the text fine.


#8

I noticed that the CustomTypeFace is the one that actually checks if there is a Fallback TypeFace, the WindowsTypeface does not seem to do this.
Check getGlyphPositions method for example.


#9

Ok, thanks, I’ll do some digging…


#10

Jules, did you find some time to have a look at the FontFallback mechanism?


#11

Sorry, am working on about 4 other simultaneous things right now. It looks like it’d be a really quite complicated job to get it going, even just on windows, so I’d need to find some uninterrupted time to concentrate on it.


#12

Ok, please let me know if you find some time. I’m curious though why you removed functionality that seemed to work fine. I understand the Font rendering on OSX changed things but it did work fine on Windows, can’t you just copy it back or is that a stupid suggestion.


#13

The old system dealt with one character at a time, converting it to a glyph index, and added the kerning later. That’s a bad design, and also not possible on OSX, so I changed it to work on complete lines of text, producing a line of glyph indexes and kernings.

Of course that means that it’s non-trivial (and on OSX probably impossible) to spot which glyphs are missing from the finished sequence, and to go back and replace them with glyphs from a different font, re-kerning the whole line to fit them.


#14

How about CTFontCreateForString (with your attributed string) with the fallback font in the cascade list? Or is that overly simplistic?


#15

That only returns one font. What we’d need to handle is a string where some of the characters end up using a fallback font, and other don’t.


#16

Good point. Well, it may be too slow, but if a glyph isn’t found(via CTFontGetGlyphsForCharacters) how about calling CTFontCreateForString with just that UniChar?

Pain in the butt though…


#17

The real problem on OSX is that there’s no way I’ve found to actually find out whether a glyph exists in the font or not. Any missing ones are just replaced with default glyphs, but it doesn’t tell you that it’s done so.


#18

CTFontGetGlyphsForCharacters returns true if the font could encode all the characters.

[quote]
If a glyph could not be encoded, a value of 0 is passed back at the corresponding index in the glyphs array and the function returns False.[/quote]

Let me see if I can hack something together to send you, lord knows you have enough on your plate!


#19

Ah, I didn’t see that one. I think CoreText is only available on 10.5 and above, but better than nothing!


#20

I hacked on this, first for a 10.4 version, and while I got the glyph substitution working. (Instead of [nsFont _defaultGlyphForChar: text.getAndAdvance()] I made a slew of cocoa classes NSTextStorage, NSTextContainer, and a NSLayoutManager, stuffed the attributed string in there and used NSLayoutManager’s glyphAtIndex:i].

This worked, and if I iterated over the attributes of the layoutmanager, I could see font substitution worked (in my case I used the Katakana string プールの and the layout went from using Helvetica to HiraKakuProN-W3 for those characters.)

The problem though is that the Mac drawGlyph in CoregraphicsContext sets the context’s font and draws the glyph(even though that glyph doesn’t exist in the font.) In my case I’ve gone from the missing square boxes for the characters to some incoherent glyphs!

There seems to be ways for the glyph array to be manipulated outside the typeface class(ellipses for instance), so keeping the NSLayoutManager in sync with the string to draw would need to happen somewhere, then drawGlyph could call into the typeface and get the font for the character at index n.

Anyway, i think i’ll just continue setting to a unicode font for now!