A DESCRIPTION OF THE PROBLEM :
Background: the Mongolian script (Unicode range 0x1800 - 0x18AF) is a "complex" script, requiring contextual shaping of glyphs, much like Arabic, and for instance when implemented in OpenType fonts requires the use of tables like `isol`, `init`, `medi`, `fina` and `rlig`.
If a Mongolian string, i.e. "ᠪᠠᠢᠨá Âá  ", is inserted alone in a JavaFx control, it is not shaped at all (resulting in something like "á ª á  á ¢ á ¨ á  ").
If some additional text in a script recognised as "complex", for instance DevanÃÂgarë (i.e. "à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦"), is also inserted in the control, then the Mongolian part too is shaped correctly.
A simple single-file JavaFx application is attached below, detailing which cases work and which do not.
PATCH:
The issue originates in the file `jfx/modules/javafx.graphics/src/main/java/com/sun/javafx/text/ScriptMapper.java`; if the lines 154 - 156:
```
else if (code
</div>
</div>
<br /> <br /> <br /> <br /> <br /> <br />
<div class="form-group">
<label for="system_os_info" class="col-sm-2 control-label">System
/ OS / Java Runtime Information </label>
<div class="col-sm-8">
<textarea id="system_os_info" name="system_os_info" style="resize: none;" placeholder="Additional system configuration information here." class="form-control" rows="4">
Linux Mint 19.3 with OpenJDK 11.0.8 and OpenJFC 11.0.2
Windows 10 with OpenJDK 14.0.2 and OpenJFX 14.0.2.1
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In any, however simple, JavaFx project:
a) Insert in a control (WevView, Label, Text, ...) a string with only some Mongolian text
b) in another control insert some Mongolian text AND some DevanÃÂgarë text
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both the Mongolian only and the Mongolian + DevanÃÂgarë text are shaped correctly.
ACTUAL -
The Mongolian only text is not shaped at all (approx. as in "á ª á  á ¢ á ¨ á  "), but in the Mongolian + DevanÃÂgarë text both scripts are shaped correctly
---------- BEGIN SOURCE ----------
package com.vistamaresoft.fxtest;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class Main
{
static final String html =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n\"http://www.w3.org/TR/html4/strict.dtd\">\n" +
"<html>\n<body>\n" +
"<p style='font-size: 18pt;'>Sample text: ᠪᠠᠢᠨá Âá  </p>" + // NOT CORRECT!
"<p style='font-size: 18pt;'>ᠪᠠᠢᠨá Âá  ÃÂêçè </p>" + // NOT CORRECT!
"<p style='font-size: 18pt;'>à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦ ᠪᠠᠢᠨá Âá  </p>" + // CORRECT!
"<p><input type='text' name='title' size='20' maxlength='50' style='font-size: 18pt;' /></p>" +
"</body></html>\n";
public static void main(String[] args)
{
Application.launch(MainApp.class, args);
}
public static class MainApp extends Application
{
@Override public void start(Stage primaryStage) throws Exception
{
WebView webView = new WebView();
webView.getEngine().loadContent(html);
Label lab1 = new Label("ᠪᠠᠢᠨá Âá  "); // NOT CORRECT
lab1.setStyle("-fx-font-size: 18pt;");
Label lab2 = new Label("ᠪᠠᠢᠨá Âá  ÃÂêçè"); // NOT CORRECT
lab2.setStyle("-fx-font-size: 18pt;");
Label lab3 = new Label("ÃÂêçè ᠪᠠᠢᠨá Âá  "); // NOT CORRECT
lab3.setStyle("-fx-font-size: 18pt;");
Label lab4 = new Label("ᠪᠠᠢᠨá Âá  à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦"); // CORRECT
lab4.setStyle("-fx-font-size: 18pt;");
Label lab5 = new Label("à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦ ᠪᠠᠢᠨá Âá  "); // CORRECT
lab5.setStyle("-fx-font-size: 18pt;");
Text text1 = new Text("ᠪᠠᠢᠨá Âá  "); // NOT CORRECT
text1.setStyle("-fx-font-size: 22pt;");
Text text2 = new Text("ᠪᠠᠢᠨá Âá  à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦"); // CORRECT
text2.setStyle("-fx-font-size: 22pt;");
VBox vBox = new VBox(webView, lab1, lab2, lab3, lab4, lab5, text1, text2);
Scene scene = new Scene(vBox, 800, 600);
primaryStage.setTitle("JavaFX Mongolian Test");
primaryStage.setScene(scene);
primaryStage.show();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As adding arbitrary strings in order to trigger the correct shaping is of course not acceptable, I am aware of no workaround.
Background: the Mongolian script (Unicode range 0x1800 - 0x18AF) is a "complex" script, requiring contextual shaping of glyphs, much like Arabic, and for instance when implemented in OpenType fonts requires the use of tables like `isol`, `init`, `medi`, `fina` and `rlig`.
If a Mongolian string, i.e. "ᠪᠠᠢᠨá Âá  ", is inserted alone in a JavaFx control, it is not shaped at all (resulting in something like "á ª á  á ¢ á ¨ á  ").
If some additional text in a script recognised as "complex", for instance DevanÃÂgarë (i.e. "à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦"), is also inserted in the control, then the Mongolian part too is shaped correctly.
A simple single-file JavaFx application is attached below, detailing which cases work and which do not.
PATCH:
The issue originates in the file `jfx/modules/javafx.graphics/src/main/java/com/sun/javafx/text/ScriptMapper.java`; if the lines 154 - 156:
```
else if (code
</div>
</div>
<br /> <br /> <br /> <br /> <br /> <br />
<div class="form-group">
<label for="system_os_info" class="col-sm-2 control-label">System
/ OS / Java Runtime Information </label>
<div class="col-sm-8">
<textarea id="system_os_info" name="system_os_info" style="resize: none;" placeholder="Additional system configuration information here." class="form-control" rows="4">
Linux Mint 19.3 with OpenJDK 11.0.8 and OpenJFC 11.0.2
Windows 10 with OpenJDK 14.0.2 and OpenJFX 14.0.2.1
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
In any, however simple, JavaFx project:
a) Insert in a control (WevView, Label, Text, ...) a string with only some Mongolian text
b) in another control insert some Mongolian text AND some DevanÃÂgarë text
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both the Mongolian only and the Mongolian + DevanÃÂgarë text are shaped correctly.
ACTUAL -
The Mongolian only text is not shaped at all (approx. as in "á ª á  á ¢ á ¨ á  "), but in the Mongolian + DevanÃÂgarë text both scripts are shaped correctly
---------- BEGIN SOURCE ----------
package com.vistamaresoft.fxtest;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class Main
{
static final String html =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n\"http://www.w3.org/TR/html4/strict.dtd\">\n" +
"<html>\n<body>\n" +
"<p style='font-size: 18pt;'>Sample text: ᠪᠠᠢᠨá Âá  </p>" + // NOT CORRECT!
"<p style='font-size: 18pt;'>ᠪᠠᠢᠨá Âá  ÃÂêçè </p>" + // NOT CORRECT!
"<p style='font-size: 18pt;'>à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦ ᠪᠠᠢᠨá Âá  </p>" + // CORRECT!
"<p><input type='text' name='title' size='20' maxlength='50' style='font-size: 18pt;' /></p>" +
"</body></html>\n";
public static void main(String[] args)
{
Application.launch(MainApp.class, args);
}
public static class MainApp extends Application
{
@Override public void start(Stage primaryStage) throws Exception
{
WebView webView = new WebView();
webView.getEngine().loadContent(html);
Label lab1 = new Label("ᠪᠠᠢᠨá Âá  "); // NOT CORRECT
lab1.setStyle("-fx-font-size: 18pt;");
Label lab2 = new Label("ᠪᠠᠢᠨá Âá  ÃÂêçè"); // NOT CORRECT
lab2.setStyle("-fx-font-size: 18pt;");
Label lab3 = new Label("ÃÂêçè ᠪᠠᠢᠨá Âá  "); // NOT CORRECT
lab3.setStyle("-fx-font-size: 18pt;");
Label lab4 = new Label("ᠪᠠᠢᠨá Âá  à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦"); // CORRECT
lab4.setStyle("-fx-font-size: 18pt;");
Label lab5 = new Label("à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦ ᠪᠠᠢᠨá Âá  "); // CORRECT
lab5.setStyle("-fx-font-size: 18pt;");
Text text1 = new Text("ᠪᠠᠢᠨá Âá  "); // NOT CORRECT
text1.setStyle("-fx-font-size: 22pt;");
Text text2 = new Text("ᠪᠠᠢᠨá Âá  à ¤ à ¤¨à ¥Âà ¤Âà ¥Âà ¤Âà ¥Âà ¤¦"); // CORRECT
text2.setStyle("-fx-font-size: 22pt;");
VBox vBox = new VBox(webView, lab1, lab2, lab3, lab4, lab5, text1, text2);
Scene scene = new Scene(vBox, 800, 600);
primaryStage.setTitle("JavaFX Mongolian Test");
primaryStage.setScene(scene);
primaryStage.show();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As adding arbitrary strings in order to trigger the correct shaping is of course not acceptable, I am aware of no workaround.
- relates to
-
JDK-8252091 UI Incorrect shaping of chars in the Unicode Mongolian range (0x1800-0x18FF)
- Open