<div dir="ltr">Hi Philip,<div><br></div><div>I did some more testing and noticed an even more serious problem on macOS: I couldn’t seem to select the font weight.</div><div><br></div><div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><font face="monospace">jshell> Font.getFontNames("JetBrains Mono").forEach(System.out::println)<br>JetBrains Mono ExtraLight Italic<br>JetBrains Mono ExtraBold Italic<br>JetBrains Mono Medium<br>JetBrains Mono Thin Italic<br>JetBrains Mono ExtraBold<br>JetBrains Mono Light<br>JetBrains Mono SemiBold<br>JetBrains Mono Medium Italic<br>JetBrains Mono Bold Italic<br>JetBrains Mono SemiBold Italic<br>JetBrains Mono Bold<br>JetBrains Mono Regular<br>JetBrains Mono Light Italic<br>JetBrains Mono Italic<br>JetBrains Mono ExtraLight<br>JetBrains Mono Thin<br><br>jshell> Font.font("JetBrains Mono Thin")<br>$3 ==> Font[name=System Regular, family=System, style=Regular, size=13.0]<br><br>jshell> Font.font("JetBrains Mono", FontWeight.THIN, 13)<br>$4 ==> Font[name=JetBrains Mono Medium, family=JetBrains Mono Medium, style=Regular, size=13.0]<br><br>jshell> Font.font("JetBrains Mono", FontWeight.THIN, FontPosture.REGULAR, 13)<br>$5 ==> Font[name=JetBrains Mono Medium, family=JetBrains Mono Medium, style=Regular, size=13.0]<br><br>jshell> Font.font("JetBrains Mono", FontWeight.THIN, FontPosture.ITALIC, 13)<br>$6 ==> Font[name=JetBrains Mono ExtraLight Italic, family=JetBrains Mono ExtraLight, style=Italic, size=13.0]</font></blockquote></div><div><br></div><div><font face="monospace">Font.font(...) </font>is working in a way that is hard for me to understand :(</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Some of it may come from the platform APIs being different.<br>Can you give me additional examples ?</blockquote><div><br></div><div> I think the most serious inconsistency is: what do we mean when we talk about "the family of the font"?</div><div><ul><li>On Windows, it usually means the localized name of the font family name (nameID=1);</li><li>On Linux, 

it usually means the non-localized font family name (nameID=1);</li><li>On macOS, 

it usually means the non-localized typographical family name (nameID=16).</li></ul></div><div><br></div><div>I think the behavior on macOS is relatively correct - provided that the problems I mentioned earlier are resolved.</div><div>Using font family names (nameID=1) means it is difficult to select variants.</div><div>If we want to get JetBrains Mono Bold on Windows, we need to use <font face="monospace">Font.font("JetBrains Mono", FontWeight.BOLD, 13)</font>, </div><div>but to get JetBrains Mono ExtraBold, we need to use <font face="monospace">Font.font("JetBrains Mono ExtraBold", FontWeight.NORMAL, 13)</font>.</div><div><br></div><div style="">Honestly, I feel like the entire Font API is poorly documented, extremely confusing, and lacks useful methods.</div><div style="">If I don't test it on every platform, I have no idea how it will work. I think it really needs a huge refactor.</div><div><br></div><div>Glavo</div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Jul 16, 2025 at 3:20 AM Philip Race <<a href="mailto:philip.race@oracle.com">philip.race@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  
  <div>
    I can't be sure - without inspecting the font and debugging the code
    - but this looks<br>
    like in the first case you get the ID=16 typographic font family
    ("JetBrains Mono") and<br>
    in the other case you get the ID=1 font family ("JetBrains Mono
    Medium").<br>
    Without debugging I can't explain why there's this apparent
    inconsistency.<br>
    <br>
    ID=1 is the traditional 4 member font family with
    regular/bold/italic/bold italic<br>
    <br>
    The typographic (some times called extended) family supports weight
    and sometimes width<br>
    and these days they may even be combined into a single font via font
    variations.<br>
    <br>
    There may be a bug here (can't be sure without investigating) and
    there also may be a need<br>
    for API which works with the typographic family.<br>
    <br>
    <div><br>
    </div>
    <div>>Besides these issues, I also get tired of the subtle
      differences in behavior between different platforms.</div>
    <div>>Can we bridge the differences in how JavaFX handles font
      family names on different platforms?</div>
    <br>
    Some of it may come from the platform APIs being different.<br>
    Can you give me additional examples ?<br>
    <br>
    -phil.<br>
    <br>
    <div>On 7/15/25 7:21 AM, Glavo wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">Hi Philip,
        <div><br>
        </div>
        <div>Thanks for your reply.</div>
        <div>
          <div><br>
          </div>
        </div>
        <div>> (1) fixing this for DW wouldn't help Linux or Mac so
          there'd need to be separate implementations if they also don't
          do it automatically</div>
        <div><br>
        </div>
        <div>I also tested on Linux and macOS. I think this problem does
          not exist on these two platforms.</div>
        <div>JavaFX uses the English font family names everywhere on
          both platforms, rather than the localized names, so this
          problem does not occur.</div>
        <div><br>
        </div>
        <div>However, I encountered another annoying behavior on macOS:</div>
        <div><br>
        </div>
        <div>
          <blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><font face="monospace">jshell>
              Font.getFamilies().stream().filter(it ->
              it.contains("JetBrains Mono")).toList()<br>
              $2 ==> [JetBrains Mono, JetBrains Mono NL]<br>
              <br>
              jshell> Font.font("JetBrains Mono")<br>
              $3 ==> Font[name=JetBrains Mono Medium,
              family=JetBrains Mono Medium, style=Regular, size=13.0]<br>
              <br>
              jshell> $3.getFamily()<br>
              $4 ==> "JetBrains Mono Medium"<br>
              <br>
              jshell> Font.font("JetBrains Mono Medium")<br>
              $5 ==> Font[name=System Regular, family=System,
              style=Regular, size=13.0]</font></blockquote>
        </div>
        <div><br>
        </div>
        <div>As you can see, multiple weights of a font on macOS are
          unified into the same font family.</div>
        <div>We can find a Font by this font family name, but the family
          name returned by Font:getFamily() includes the weight, </div>
        <div>and we cannot find the font based on the returned name.</div>
        <div>This problem does not occur on Linux and Windows, because
          those platforms do not unify fonts into a single family.</div>
        <div><br>
        </div>
        <div>Besides these issues, I also get tired of the subtle
          differences in behavior between different platforms.</div>
        <div>Can we bridge the differences in how JavaFX handles font
          family names on different platforms?</div>
        <div><br>
        </div>
        <div>Glavo</div>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">On Tue, Jul 15, 2025 at
          3:50 AM Philip Race <<a href="mailto:philip.race@oracle.com" target="_blank">philip.race@oracle.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div> Font.font will, on Windows, use
            IDWriteFontCollection::FindFamilyName(..)<br>
            The docs for that appear to be silent on whether the
            matching process will check all localized names,<br>
            but it sounds like it must not.  I don't see an alternative
            look up API, such as one that accepts a locale arg.<br>
            <br>
            <a href="https://learn.microsoft.com/en-us/windows/win32/api/dwrite/nn-dwrite-idwritefontcollection" target="_blank">https://learn.microsoft.com/en-us/windows/win32/api/dwrite/nn-dwrite-idwritefontcollection</a>
            <p>It seems like the app (which in this case means the FX
              implementation) will have to do this itself which is going
              to be tedious.</p>
            <p>We would need to compare with every localized name of
              every font on the system looking for a match.</p>
            <p>And one annoying aspect of this is that until you've done
              that exhaustive search you don't<br>
              know if the name the application supplied is present at
              all on the system.</p>
            <p>How would you know that someone mis-spelled Arial as
              Ariel and not that Ariel is the German localized name for
              Arial ?</p>
            <p>So failed lookups will be slow.</p>
            <p>In Java 2D we already do this but I'd have hoped DW used
              by FX was better than this than GDI used by 2D.</p>
            Also note that<br>
            (1) fixing this for DW wouldn't help Linux or Mac so there'd
            need to be separate implementations if they also don't do it
            automatically<br>
            (2) There isn't any FX API which lets you enumerate or
            access localized names, so as you note, that also is an
            issue.<br>
            Although I'm actually a little surprised FX finds 幼圆 but
            reports YouYuan. I would have thought it would be
            consistent.<br>
            <br>
            I'm also a little surprised that it has taken this long for
            anyone to even implicitly ask for FX to support localized
            font names.<br>
            Java2D has had this support for a very long time.<br>
            <br>
            -phil.<br>
            <br>
            <div>On 7/12/25 4:18 AM, Glavo wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="ltr">
                <div dir="ltr">
                  <div dir="ltr">
                    <div>Hi,</div>
                    <div><br>
                    </div>
                    <div>We recently noticed a problem: For fonts with
                      localized names, <font face="monospace">Font.font(String)</font>
                      can only find the font based on the localized name
                      in the current locale.</div>
                    <div><br>
                    </div>
                    <div>For example, the Chinese version of Windows
                      comes with a font called "YouYuan", and its
                      Chinese name is "幼圆".</div>
                    <div>When the system language is Chinese, JavaFX has
                      the following behaviors:</div>
                    <div><br>
                    </div>
                  </div>
                  <blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">
                    <div dir="ltr">
                      <div><font face="monospace">jshell>
                          Font.font("YouYuan")<br>
                          $2 ==> Font[name=System Regular,
                          family=System, style=Regular,
                          size=13.333333015441895]<br>
                          <br>
                          jshell> Font.font("幼圆")<br>
                          $3 ==> Font[name=YouYuan, family=YouYuan,
                          style=Regular, size=13.333333015441895]<br>
                          <br>
                          jshell> $3.getFamily()<br>
                          $4 ==> "YouYuan"</font></div>
                    </div>
                  </blockquote>
                  <br>
                  <div>As you can see, we cannot find the font based on
                    the English name, we can only use the Chinese name.</div>
                  <div>But <font face="monospace">Font::getName()</font>
                    returns the English name, so we can't get the
                    Chinese name from the <font face="monospace">Font</font>.</div>
                  <div>This makes it impossible to generate a style
                    sheet based on a <font face="monospace">Font</font><font face="arial, sans-serif"> object, </font>because </div>
                </div>
                <blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">
                  <div dir="ltr">
                    <div><font face="monospace">"-fx-font-family:
                        \"%s\";".formatted(font.getFamily())</font></div>
                  </div>
                </blockquote>
                <div dir="ltr">
                  <div>will not work with these fonts.</div>
                  <div><br>
                  </div>
                  <div>The only workaround I can think of is to generate
                    a mapping table from English names to Chinese names
                    like this:</div>
                </div>
                <blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px">
                  <div dir="ltr">
                    <div><font face="monospace"><br>
                      </font></div>
                    <div><font face="monospace">Font.getFamilies().stream().collect(Collectors.toMap(it
                        -> Font.font(it).getFamily(),
                        Function.identity()))</font></div>
                  </div>
                </blockquote>
                <div dir="ltr">
                  <div><br>
                  </div>
                  <div>But this seems like a lot of overhead :( </div>
                  <div><br>
                  </div>
                  <div>So, I want JavaFX to provide the following
                    features:</div>
                  <div>
                    <ol>
                      <li>Regardless of the current system language, <font face="monospace">Font.font(String)</font>
                        should be able to find the font by its English
                        name;</li>
                      <li>Provide a new method <font face="monospace">Font::getLocalizedFamily()</font>
                        to get the localized name of the font.</li>
                    </ol>
                  </div>
                  <div>Glavo</div>
                </div>
              </div>
            </blockquote>
            <br>
          </div>
        </blockquote>
      </div>
    </blockquote>
    <br>
  </div>

</blockquote></div>