vah*_*eza 7 javafx arabic right-to-left farsi arabic-support
我想用 JavaFX 显示文本。该消息是波斯语或阿拉伯语。然而,如此处所述,波斯语或阿拉伯语字母的表示形状取决于其相邻字母。
如果我构建一个包含整个消息的TextFlow单个消息,它会正确显示。Text但是当我将它分割成多个Texts 时,消息就被破坏了。
例如,以下代码片段产生上图:
public class HelloFX extends Application {
@Override
public void start(Stage stage) throws Exception {
Font font = new Font("Arial", 48);
String message = "\u0627\u0644\u0633\u0644\u0627\u0645 \u0639\u0644\u064a\u0643\u0645";
TextFlow textFlow1 = new TextFlow();
Text text1 = new Text(message);
text1.setFont(font);
textFlow1.getChildren().addAll(text1);
TextFlow textFlow2 = new TextFlow();
for (int i = 0; i < message.length(); i++) {
char ch = message.charAt(i);
Text text2 = new Text(ch + "");
if (i % 2 == 0)
text2.setFill(Color.RED);
text2.setFont(font);
textFlow2.getChildren().add(text2);
}
VBox box = new VBox(textFlow1, textFlow2);
box.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
Scene scene = new Scene(box, 400, 150);
stage.setScene(scene);
stage.show();
}
}
Run Code Online (Sandbox Code Playgroud)
我在 Mac OS 上使用 javafx 版本 18.0.1 和 java 17。但对于 Linux 来说结果也是一样的。
正如我在评论中提到的,这是一个已知的错误,大约 10 年前在 openjdk 问题跟踪系统中报告过(请参见此处)。不幸的是它被标记为低优先级。
因此,我决定此时手动解决这个问题(感谢@SedJ601的鼓舞人心的评论)。Text如果 s 的边界在流动中被破坏,我必须在它们的边界上施展一些魔法。我认为有两种可能的解决方案:
然而,这两种解决方案都存在一些问题,特别是在 lam 和 alef 的情况下。但第二个看起来更好。
例如,在下面,我TextFlow在之前的示例代码中添加了关于上述解决方案的两个新内容。
public class HelloFX extends Application {
@Override
public void start(Stage stage) throws Exception {
Font font = new Font("Arial", 48);
String message = "\u0627\u0644\u0633\u0644\u0627\u0645 \u0639\u0644\u064a\u0643\u0645";
TextFlow textFlow1 = new TextFlow();
Text text1 = new Text(message);
text1.setFont(font);
textFlow1.getChildren().addAll(text1);
TextFlow textFlow2 = new TextFlow();
for (int i = 0; i < message.length(); i++) {
char ch = message.charAt(i);
Text text2 = new Text(ch + "");
if (i % 2 == 0)
text2.setFill(Color.RED);
text2.setFont(font);
textFlow2.getChildren().add(text2);
}
List prefixes = Arrays.asList(2,3,4,9,10,11,12);
List suffixes = Arrays.asList(1, 2,3,8,9,10,11);
message = "\u0627\u0644\u0633\u0644\u0627\u0645 \u0639\u0644\u064a\u0643\u0645";
TextFlow textFlow3 = new TextFlow();
for (int i = 0; i < message.length(); i++) {
char ch = message.charAt(i);
String suffix = "", prefix = "";
if (suffixes.contains(i)) suffix = "\u0640";
if (prefixes.contains(i)) prefix = "\u0640";
Text text3 = new Text(prefix + ch + suffix);
if (i % 2 == 0)
text3.setFill(Color.RED);
text3.setFont(font);
textFlow3.getChildren().add(text3);
}
TextFlow textFlow4 = new TextFlow();
message = "\u0627\uFEE0\uFEB4\uFEDf\uFE8e\u0645 \uFECb\uFEDf\uFEF4\uFEDc\uFEE2";
for (int i = 0; i < message.length(); i++) {
char ch = message.charAt(i);
Text text4 = new Text(ch + "");
if (i % 2 == 0)
text4.setFill(Color.RED);
text4.setFont(font);
textFlow4.getChildren().add(text4);
}
VBox box = new VBox(textFlow1, textFlow2, textFlow3, textFlow4);
box.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
Scene scene = new Scene(box, 500, 250);
stage.setScene(scene);
stage.show();
}
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,我Text自己生成了最终的 s 。然而在实际应用中,需要一些计算来找到位置。
请注意,第一个解决方案看起来非常难看。因为我的样品需要太多的Kashidas。随着休息次数和相应的 Kashidas 的减少,情况会变得更好。
| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |