Skip to content

OpenTypeFontPeer: implement canDisplay() and canDisplayUpTo() - #68

Open
duncanmcqueen wants to merge 2 commits into
ingelabs:masterfrom
duncanmcqueen:fix-opentype-candisplay
Open

duncanmcqueen wants to merge 2 commits into
ingelabs:masterfrom
duncanmcqueen:fix-opentype-candisplay

Conversation

@duncanmcqueen

Copy link
Copy Markdown
Contributor

Split from #58.

Problem and fix

OpenTypeFontPeer.canDisplay() and canDisplayUpTo() throw UnsupportedOperationException("Not yet implemented"). Font.canDisplay() and Font.canDisplayUpTo() call them. Thus these Font methods fail with each toolkit that uses OpenTypeFontPeer, for example the X peer (gnu.java.awt.peer.x). The GTK peer uses GdkFontPeer and does not have this problem.

Now a character can be displayed when the font maps it to a glyph that is not the missing glyph. canDisplayUpTo() returns the index of the first character that cannot be displayed, or -1.

How to reproduce

The test makes an OpenTypeFontPeer directly, so it does not need a toolkit or a display. It needs the font file that gnu/java/awt/font/fonts.properties gives for FreeSans: /usr/share/fonts/truetype/freefont/FreeSans.ttf. On Debian and Ubuntu, this file is in the package fonts-freefont-ttf. My system does not have this file, so I put a fonts.properties that maps FreeSans/p to DejaVu Sans before glibj.zip (-Xbootclasspath/p:).

OpenTypeFontPeer maps the font file with FileChannel.map(). If configure did not find mmap, the font does not load (see #62). In that case, use autoconf 2.71 or earlier, or apply #62.

javac OpenTypeCanDisplay.java
java OpenTypeCanDisplay
OpenTypeCanDisplay.java
import gnu.java.awt.font.OpenTypeFontPeer;
import java.awt.Font;
import java.text.StringCharacterIterator;

/**
 * OpenTypeFontPeer.canDisplay() and canDisplayUpTo() must work. Font
 * calls them for Font.canDisplay() with toolkits that use
 * OpenTypeFontPeer, such as the X peer. Needs a font that
 * gnu/java/awt/font/fonts.properties lists, for example
 * /usr/share/fonts/truetype/freefont/FreeSans.ttf (package fonts-freefont-ttf).
 */
public class OpenTypeCanDisplay
{
  public static void main(String[] args)
  {
    OpenTypeFontPeer peer = new OpenTypeFontPeer("FreeSans", Font.PLAIN, 12);
    boolean failed = false;
    try
      {
        boolean a = peer.canDisplay(null, 'A');
        // U+0378 is not assigned, so no font has a glyph for it.
        boolean unassigned = peer.canDisplay(null, 0x0378);
        int upTo = peer.canDisplayUpTo(null,
                     new StringCharacterIterator("AB͸C"), 0, 4);
        int all = peer.canDisplayUpTo(null,
                    new StringCharacterIterator("ABC"), 0, 3);
        failed = !a || unassigned || upTo != 2 || all != -1;
        System.out.println((failed ? "FAIL" : "PASS") + ": canDisplay('A') = "
                           + a + ", canDisplay(U+0378) = " + unassigned
                           + ", canDisplayUpTo(\"AB\\u0378C\") = " + upTo
                           + ", canDisplayUpTo(\"ABC\") = " + all);
      }
    catch (RuntimeException e)
      {
        System.out.println("FAIL: " + e);
        failed = true;
      }
    System.exit(failed ? 1 : 0);
  }
}

Results

Linux x86_64, ingelabs/classpath master (0406074), JamVM master, javac from JDK 8, autoconf 2.73, automake 1.19, the configure options of the CI Linux job, out-of-tree build. "Before" is master. "After" is master with this commit.

Before:
FAIL: java.lang.UnsupportedOperationException: Not yet implemented

After:
PASS: canDisplay('A') = true, canDisplay(U+0378) = false, canDisplayUpTo("AB\u0378C") = 2, canDisplayUpTo("ABC") = -1

Platforms

Not specific to Haiku. The problem occurs with all toolkits that use OpenTypeFontPeer. The Haiku toolkit (#61) also uses it.

AI assistance

An AI model (Claude Code, by Anthropic) wrote this change, the test and this text. The repository owner directed the work and checked the results. Please review it as you review other contributions.

🤖 Generated with Claude Code

Both methods threw UnsupportedOperationException, so Font.canDisplay()
failed for all OpenType fonts. A character can be displayed when the
font maps it to a glyph other than the missing glyph.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: duncanmcqueen <206344294+duncanmcqueen@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant