Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I display emoji in JavaFX on OS X?

I'm having trouble getting emoji to display in my JavaFX application on Mac OS X. On Linux, as long as I have an emoji font (Symbola, Noto Emoji) on the system, font substitution will kick in.

On OS X, however, no such luck. I have tried adding the Symbola font as a resource, and that only works if I change the label's font to Symbola. I would prefer not to do this because:

  • Symbola is a serif font and doesn't fit the aesthetic of my application
  • The user should eventually be able to choose their own font

Apple has the "Apple Color Emoji" font. If I set my label that font, emoji will display but text-spacing is erratic.

Here's a sample application to see the issue:

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Main extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        Group root = new Group();
        Scene scene = new Scene(root, 300, 130, Color.WHITE);
        GridPane gridpane = new GridPane();
        gridpane.setPadding(new Insets(5));

        // Add cat emoji
        Label label = new Label("\uD83D\uDC31");

        GridPane.setHalignment(label, HPos.CENTER);
        gridpane.add(label, 0, 0);

        root.getChildren().add(gridpane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

The above was adapted from a JavaFX tutorial

Black bars instead of the cat emoji

As you can see, black bars are displayed instead of 🐱.

I'm really curious as to how one resolves this. It always feels strange not having emoji support on the platform that pioneered it!

like image 213
Ted Morin Avatar asked Apr 26 '16 03:04

Ted Morin


1 Answers

I think that the default Apple Emoji Font (Apple Color Emoji) can't be rendered in JavaFX. Normally a font defines a vector based visualization for each character. There are some fonts that use images for specific characters. The emojis in the Apple font are defined as images. You can easily test it by adding an emoji in Pages or Keynote and change the font size to 500 or so. By doing so you will see that the emoji is pixelated. I think Apple added each emoji in several dimensions to the font (like 32px, 64px, 128px, 256px) but if you make it big enough you can see the pixels. enter image description here

I think that JavaFX can't render that kind of font and supports only vector based fonts. Therefore the emoji isn't rendered on your Mac.

What you can do: You can add a vector based emoji font to your project (in the resources) and load it in Java code or by using CSS (see http://www.guigarage.com/2014/10/integrate-custom-fonts-javafx-application-using-css/). If you did it by using CSS you can simply define a CSS rule for the ".text" class and define the loaded font. By doing so you will set the font for (mostly) all texts in your application. There are some cases where you need some additional CSS rules to have really everything shown in your custom font.

If you want to display the emojis only at some special points you can check if using a JavaFX TextFlow isn't a better approach (see http://www.guigarage.com/2013/09/make-your-app-smile-d/). Here you can parse a text and split it in several JavaFX text nodes that are part of a TextFlow. In that case you will end in some text nodes that contain an emoji and you can change the font only for this text nodes. By doing so the rest of your application can be displayed in the default font or any font of your choose.

like image 186
Hendrik Ebbers Avatar answered Nov 09 '22 22:11

Hendrik Ebbers