Support for Ligatures

Scott Palmer swpalmer at gmail.com
Tue Oct 25 02:25:18 UTC 2022


I guess everything you’ve written below about querying and requesting features still falls into the hole of “stuff we could do with Swing, but can’t do with JavaFX”.  I don’t use Swing anymore, but every once in a while I run into one of these issues. There are workarounds for some, like NSMenuFX to get proper menu support on macOS, or using AWT Desktop support in combination with JavaFX to get the missing support for the system tray, dock, opening documents with the OS-defined default handler, etc... but it’s less than ideal.   However, this issue doesn’t appear to have any workaround.

I did a quick search in the JavaFX code for ligature support and it seems there is quite a bit of incomplete support in many parts of the font processing.  E.g. com.sun.javafx.scene.control.skin.Utils contains the commented out block that appears to be from older AWT code:

    private static boolean requiresComplexLayout(Font font, String string) {
        /*        Map attrs = font.getAttributes();
           if (contains(attrs, KERNING, KERNING_ON) ||
           contains(attrs, LIGATURES, LIGATURES_ON) ||
           (attrs.containsKey(TRACKING) && attrs.get(TRACKING) != null)) {
           return true;
           }
           return isComplexLayout(string.toCharArray(), 0, string.length());
         */
        return false;
    }

So complexLayout is always ‘false', which is good because where it is used the path for 'true' looks like:
        if (complexLayout) {
            // TODO needs implementation
            return 0;
        } else {


com.sun.javafx.font.FontResources defines a bunch of constants related to ligatures, but they don’t appear to be used anywhere.  Looks like they are intended for the value returned by getFeatures() in FontResource and PGFont.

com.sun.javafx.font.PrismFont and the interface it implements PGFont (what does PG stand for?) defines a getFeatures method:
    /*
     * Returns the features the user has requested.
     * (kerning, ligatures, etc)
     */
    @Override public int getFeatures() {
        return features;
    }

but features is always 0, with no means to set it.

com.sun.javafx.text.GlyphLayout where ‘features’ is used in two places compares the features of Font to FontResource. PrismFont defaults to 0, and the PrismFontFile implementation of FontResource returns -1, so for GlyphLayout  the supported features are always “everything” and the requested features are always “nothing”, so boolean feature = false, always. This is used to compute ‘complex’ (initially false)
                    if (!complex) {
                        complex = feature || ScriptMapper.isComplexCharCode(codePoint);
                    }
So ScriptMapper is the only thing really deciding what’s ‘complex’… which seems to bring me back to what you’ve stated, that required ligatures like those needed for Arabic are supported.  Now I wonder if ‘feature’ was true would my Fira Code experiment render correctly or is there a lot more to it than that?

It seems there is some otherwise ‘dead’ code already in place to support requesting these openType features.
Is exposing an API to initialize the features of FontResource enough to get some meaningful results?

I was going to try some experiments, but I’m unable to build OpenJFX on my Mac for some reason:

> > Task :graphics:compileJava FAILED
> You specified both --module-source-path and a sourcepath. These options are mutually exclusive. Ignoring sourcepath.
> error: option --upgrade-module-path cannot be used together with --release
> Usage: javac <options> <source files>
> use --help for a list of possible options

 (using JDK 17 running a simple ./gradlew)
I didn’t have trouble when I last built it a couple years ago, so I’m not sure what’s changed.

Cheers,

Scott

> On Oct 24, 2022, at 3:43 PM, Philip Race <philip.race at oracle.com> wrote:
> 
> FX does (of course) support required ligatures, meaning those without which some script (eg Arabic)
> can't even be rendered.
> 
> But that is implementation, no API.
> 
> So this is about adding an API to request optional ligatures - and other OpenType features.
> For example I think we'd want to support things like small caps etc.
> 
> Of course we'd need to make sure all the measuring code is up to that .. and BTW
> the APIs to do measurement probably should be in the queue ahead of this ..
> 
> And I am not sure about just an API to request ligatures without an API to query
> if ligatures are available for a font. However that may turn out to be tricky for a
> few reasons, but we should at least study it.
> 
> And to try to answer the "when" question .. it is on a "desired" list in my head and maybe
> even on a wiki somewhere .. but no concrete timetable exists.
> 
> But it is good to get feedback like this so we know it is interesting to developers.
> 
> -phil.
> 
> On 10/24/22 12:07 PM, Scott Palmer wrote:
>> Something I noticed while experimenting with RichTextFX, when I set it to use Fira Code for the font, like I do in NetBeans, I see that JavaFX doesn't support ligatures.  I found this issue that's been around for quite some time:
>> https://bugs.openjdk.org/browse/JDK-8091616
>> 
>> Is there any drive to get this implemented within the next few releases?  I would help, but unfortunately I suspect it will take more time than I can commit to it.
>> I’m hoping that eliminating some of the remaining gaps between what JavaFX supports and Swing supports would be a priority, as it removes some barriers to JavaFX adoption... but maybe not?
>> 
>> Regards,
>> 
>> Scott
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20221024/32e76161/attachment-0001.htm>


More information about the openjfx-dev mailing list