<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">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.</div><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div><br></div><div>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:</div><div><br></div><div><div><font face="Courier New">    private static boolean requiresComplexLayout(Font font, String string) {</font></div><div><font face="Courier New">        /*        Map attrs = font.getAttributes();</font></div><div><font face="Courier New">           if (contains(attrs, KERNING, KERNING_ON) ||</font></div><div><font face="Courier New">           contains(attrs, LIGATURES, LIGATURES_ON) ||</font></div><div><font face="Courier New">           (attrs.containsKey(TRACKING) && attrs.get(TRACKING) != null)) {</font></div><div><font face="Courier New">           return true;</font></div><div><font face="Courier New">           }</font></div><div><font face="Courier New">           return isComplexLayout(string.toCharArray(), 0, string.length());</font></div><div><font face="Courier New">         */</font></div><div><font face="Courier New">        return false;</font></div><div><font face="Courier New">    }</font></div><div><br></div><div>So complexLayout is always ‘false', which is good because where it is used the path for 'true' looks like:</div><div><div><font face="Courier New">        if (complexLayout) {</font></div><div><font face="Courier New">            // TODO needs implementation</font></div><div><font face="Courier New">            return 0;</font></div><div><font face="Courier New">        } else {</font></div></div><div><br></div><div><br></div><div>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.</div><div><br></div><div>com.sun.javafx.font.PrismFont and the interface it implements PGFont (what does PG stand for?) defines a getFeatures method:</div><div><div><font face="Courier New">    /*</font></div><div><font face="Courier New">     * Returns the features the user has requested.</font></div><div><font face="Courier New">     * (kerning, ligatures, etc)</font></div><div><font face="Courier New">     */</font></div><div><font face="Courier New">    @Override public int getFeatures() {</font></div><div><font face="Courier New">        return features;</font></div><div><font face="Courier New">    }</font></div><div><br></div><div>but features is always 0, with no means to set it.</div><div><br></div><div>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)</div><div><div><font face="Courier New">                    if (!complex) {</font></div><div><font face="Courier New">                        complex = feature || ScriptMapper.isComplexCharCode(codePoint);</font></div><div><font face="Courier New">                    }</font></div><div>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?</div><div><br></div><div>It seems there is some otherwise ‘dead’ code already in place to support requesting these openType features.</div><div>Is exposing an API to initialize the features of FontResource enough to get some meaningful results?</div><div><br></div><div>I was going to try some experiments, but I’m unable to build OpenJFX on my Mac for some reason:</div><div><br></div><div><blockquote type="cite"><p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Hack; color: rgb(255, 99, 85); background-color: rgba(255, 255, 255, 0.9);"><span style="font-variant-ligatures: no-common-ligatures"><b>> Task :graphics:compileJava</b> FAILED</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Hack; color: rgb(0, 255, 0); background-color: rgba(255, 255, 255, 0.9);"><span style="font-variant-ligatures: no-common-ligatures">You specified both --module-source-path and a sourcepath. These options are mutually exclusive. Ignoring sourcepath.</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Hack; color: rgb(0, 255, 0); background-color: rgba(255, 255, 255, 0.9);"><span style="font-variant-ligatures: no-common-ligatures">error: option --upgrade-module-path cannot be used together with --release</span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Hack; color: rgb(0, 255, 0); background-color: rgba(255, 255, 255, 0.9);"><span style="font-variant-ligatures: no-common-ligatures">Usage: javac <options> <source files></span></p>
<p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Hack; color: rgb(0, 255, 0); background-color: rgba(255, 255, 255, 0.9);"><span style="font-variant-ligatures: no-common-ligatures">use --help for a list of possible options</span></p></blockquote><div><p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Hack; color: rgb(0, 255, 0); background-color: rgba(255, 255, 255, 0.9);"><span style="font-variant-ligatures: no-common-ligatures"><br></span></p></div></div></div><div><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"> (using JDK 17 running a simple ./gradlew)</span></div><div><font color="#000000">I didn’t have trouble when I last built it a couple years ago, so I’m not sure what’s changed.</font></div><div><br></div></div><div>Cheers,</div><div><br></div><div>Scott</div><div><br><blockquote type="cite"><div>On Oct 24, 2022, at 3:43 PM, Philip Race <philip.race@oracle.com> wrote:</div><br class="Apple-interchange-newline"><div>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  
  <div>
    FX does (of course) support required ligatures, meaning those
    without which some script (eg Arabic)<br>
    can't even be rendered.<br>
    <br>
    But that is implementation, no API.<br>
    <br>
    So this is about adding an API to request optional ligatures - and
    other OpenType features.<br>
    For example I think we'd want to support things like small caps etc.<br>
    <br>
    Of course we'd need to make sure all the measuring code is up to
    that .. and BTW<br>
    the APIs to do measurement probably should be in the queue ahead of
    this ..<br>
    <br>
    And I am not sure about just an API to request ligatures without an
    API to query<br>
    if ligatures are available for a font. However that may turn out to
    be tricky for a<br>
    few reasons, but we should at least study it.<br>
    <br>
    And to try to answer the "when" question .. it is on a "desired"
    list in my head and maybe<br>
    even on a wiki somewhere .. but no concrete timetable exists.<br>
    <br>
    But it is good to get feedback like this so we know it is
    interesting to developers.<br>
    <br>
    -phil.<br>
    <br>
    <div class="moz-cite-prefix">On 10/24/22 12:07 PM, Scott Palmer
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:D2536978-0591-4BA9-AD3D-879057A10877@gmail.com">
      
      <div style="display: block;">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:</div>
      <div style="display: block;">
        <div style="-webkit-user-select: all; -webkit-user-drag:
          element; display: inline-block;" class="apple-rich-link" draggable="true" role="link" data-url="https://bugs.openjdk.org/browse/JDK-8091616"><a style="border-radius:10px;font-family:-apple-system,
            Helvetica, Arial,
sans-serif;display:block;-webkit-user-select:none;width:300px;user-select:none;-webkit-user-modify:read-only;user-modify:read-only;overflow:hidden;text-decoration:none;" class="lp-rich-link" rel="nofollow" href="https://bugs.openjdk.org/browse/JDK-8091616" dir="ltr" role="button" draggable="false" width="300" moz-do-not-send="true">
            <table style="table-layout:fixed;border-collapse:collapse;width:300px;background-color:#E5E6E9;font-family:-apple-system,
              Helvetica, Arial, sans-serif;" class="lp-rich-link-emailBaseTable" width="300" cellspacing="0" cellpadding="0" border="0">
              <tbody>
                <tr>
                  <td vertical-align="center">
                    <table style="font-family:-apple-system, Helvetica,
                      Arial,
                      sans-serif;table-layout:fixed;background-color:rgba(229,
                      230, 233, 1);" class="lp-rich-link-captionBar" width="300" cellspacing="0" cellpadding="0" bgcolor="#E5E6E9">
                      <tbody>
                        <tr>
                          <td style="padding:8px 0px 8px 0px;" class="lp-rich-link-captionBar-textStackItem">
                            <div style="max-width:100%;margin:0px 16px
                              0px 16px;overflow:hidden;" class="lp-rich-link-captionBar-textStack">
                              <div style="word-wrap:break-word;font-weight:500;font-size:12px;overflow:hidden;text-overflow:ellipsis;text-align:left;" class="lp-rich-link-captionBar-textStack-topCaption-leading"><a rel="nofollow" href="https://bugs.openjdk.org/browse/JDK-8091616" style="text-decoration: none" draggable="false" moz-do-not-send="true"><font style="" color="#272727">[JDK-8091616]
                                    Prism: font: ligature and kerning
                                    support - Java Bug System</font></a></div>
                              <div style="word-wrap:break-word;font-weight:400;font-size:11px;overflow:hidden;text-overflow:ellipsis;text-align:left;" class="lp-rich-link-captionBar-textStack-bottomCaption-leading"><a rel="nofollow" href="https://bugs.openjdk.org/browse/JDK-8091616" style="text-decoration: none" draggable="false" moz-do-not-send="true"><font style="" color="#808080">bugs.openjdk.org</font></a></div>
                            </div>
                          </td>
                          <td style="padding:6px 12px 6px 0px;" class="lp-rich-link-captionBar-rightIconItem" width="36"><a rel="nofollow" href="https://bugs.openjdk.org/browse/JDK-8091616" draggable="false" moz-do-not-send="true"><span id="cid:part1.pgghvLBj.kKB35Rev@oracle.com"><jira-favicon-hires.png></span></a></td>
                        </tr>
                      </tbody>
                    </table>
                  </td>
                </tr>
              </tbody>
            </table>
          </a></div>
      </div>
      <div><br>
      </div>
      <div>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.</div>
      <div>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?</div>
      <div><br>
      </div>
      <div>Regards,</div>
      <div><br>
      </div>
      <div>Scott</div>
    </blockquote>
    <br>
  </div>
</div></blockquote></div><br></div></div></div></div></body></html>