[PATCH] Fix bug to handle minus value glyph_id on Windows
Nakajima Akira
nakajima.akira at nttcom.co.jp
Wed Jun 27 05:52:17 UTC 2018
# This patch is separated from
http://mail.openjdk.java.net/pipermail/openjfx-dev/2018-June/022005.html
Java issue error of ArrayIndexOutOfBoundsException by run following Test
program on Windows.
This bug is that Java handles big glyph_id as minus value.
For Example,
Inside JavaFX, glyph_id 49496(Uint16) is now handled as -16040(short).
ScreenShots of before/after applying this patch.
Windows10 x64 (openjfx11 and Oracle JDK 10.0.1)
https://drive.google.com/drive/folders/1UHPfCbQF4X_SSvjqgNGGKfEm-8GiNP80
# NOTICE
Now Windows API provide glyphIndices as UINT16.
Exsample)
https://msdn.microsoft.com/en-us/library/windows/desktop/dd316625%28v=vs.85%29.aspx
But originally, Windows API should provide as UINT32.
Because CMAP Format 8,12,13 have UINT32.
https://docs.microsoft.com/en-us/typography/opentype/spec/cmap
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
I have not reported to Microsoft, since I guess Microsoft knows this
problem.
CMap.java provide char (UINT16).
Freetype2 provide UINT32.
Thanks.
Akira Nakajima
[PATCH]
javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java
javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java
=========================
PATCH
=========================
diff --git
a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java
b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java
---
a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java
+++
b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyph.java
@@ -52,6 +52,7 @@
private static D2D1_COLOR_F WHITE = new D2D1_COLOR_F(1f, 1f, 1f, 1f);
private static D2D1_MATRIX_3X2_F D2D2_MATRIX_IDENTITY = new
D2D1_MATRIX_3X2_F(1,0, 0,1, 0,0);
+ static final int intMask = 0x0000ffff;
DWGlyph(DWFontStrike strike, int glyphCode, boolean drawShapes) {
this.strike = strike;
@@ -303,12 +304,12 @@
@Override
public int getGlyphCode() {
- return run.glyphIndices;
+ return ((int)run.glyphIndices & intMask);
}
@Override
public RectBounds getBBox() {
- return strike.getBBox(run.glyphIndices);
+ return strike.getBBox((int)run.glyphIndices & intMask);
}
@Override
@@ -321,7 +322,7 @@
@Override
public Shape getShape() {
- return strike.createGlyphOutline(run.glyphIndices);
+ return strike.createGlyphOutline((int)run.glyphIndices & intMask);
}
@Override
diff --git
a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java
b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java
---
a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java
+++
b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWGlyphLayout.java
@@ -138,6 +138,7 @@
int i, j;
int[] iglyphs = new int[glyphCount];
int slotMask = slot << 24;
+ final int intMask = 0x0000ffff;
boolean missingGlyph = false;
i = 0; j = rtl ? glyphCount - 1 : 0;
while (i < glyphCount) {
@@ -145,7 +146,7 @@
missingGlyph = true;
if (composite) break;
}
- iglyphs[i] = glyphs[j] | slotMask;
+ iglyphs[i] = ((int)glyphs[j] & intMask) | slotMask;
i++;
j+=step;
}
=========================
Test for Win10
=========================
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
public class TestHandlingBigGlyphID_Win10 extends Application {
@Override
public void start(Stage stage) throws Exception {
final String fontName = "ARIALUNI.TTF"; // Arial Unicode MS
// download from
https://www.wfonts.com/download/data/2015/05/16/arial-unicode-ms/ARIALUNI.TTF
// and place in $(user.home)/fonts/
// e.g. C:/Users/username/fonts/arialuni.ttf
Font ourFont =
Font.loadFont("file://"+System.getProperty("user.home")+"/fonts/"+fontName.toString(),
48);
TextFlow textFlow = new TextFlow();
// Unicode(GlyphID)
Text text = new Text("\uD7A3\u0E3F"); // U+D7A3(49496) +
U+0E3F(1262)
/* Inside JavaFX, 49496(Uint16) is handled as -16040(short).
* By ScriptMapper.isComplexCharCode(), U+0E3F is handled as
complex.
* When in condition with minus glyphID value and complex
* , JavaFX is forcibly terminated.
* (java.lang.ArrayIndexOutOfBoundsException)
*/
text.setFill(Color.GREEN);
text.setFont(ourFont);
textFlow.getChildren().addAll(text);
Group group = new Group(textFlow);
Scene scene = new Scene(group, 100, 60, Color.WHITE);
stage.setScene(scene);
stage.show();
}
}
=========================
Test for Win7 and Win10
=========================
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
public class TestHandlingBigGlyphID_Win7_and_Win10 extends Application {
@Override
public void start(Stage stage) throws Exception {
final String family = "Arial Unicode MS"; // ARIALUNI.TTF
// download from
https://www.wfonts.com/download/data/2015/05/16/arial-unicode-ms/ARIALUNI.TTF
// and You NEED install font.
Font ourFont = Font.font(family, 48);
TextFlow textFlow = new TextFlow();
// Unicode(GlyphID)
Text text = new Text("\uD7A3\u0E3F"); // U+D7A3(49496) +
U+0E3F(1262)
/* Inside JavaFX, 49496(Uint16) is handled as -16040(short).
* By ScriptMapper.isComplexCharCode(), U+0E3F is handled as
complex.
* When in condition with minus glyphID value and complex
* , JavaFX is forcibly terminated.
* (java.lang.ArrayIndexOutOfBoundsException)
*/
text.setFill(Color.GREEN);
text.setFont(ourFont);
textFlow.getChildren().addAll(text);
Group group = new Group(textFlow);
Scene scene = new Scene(group, 100, 60, Color.WHITE);
stage.setScene(scene);
stage.show();
}
}
--------------------------------------
Company: NTT Comware Corporation
Name: Akira Nakajima
E-Mail: nakajima.akira at nttcom.co.jp
--------------------------------------
More information about the openjfx-dev
mailing list