3

我是波斯人,j2me 对波斯字体没有很好的支持。

我将创建一个本地字体库,获取位图字体并在 desplay 中绘制我的波斯文本。但我有一个问题。

在英语中,每个字母都是一组由 shap 和 uncode 组成。喜欢(a , U+0061)

但是在波斯语中,一个字符可能有几种形状。例如波斯字母中的字母“ب”可以是:

آب --当它是单词中的单独字母时
به --当它是单词中的开始字母时
...

如何从字体文件中获取其他形式的字母?

4

2 回答 2

2

我是一名波斯开发人员,大约 4 年前我遇到了同样的问题。你有办法解决这个问题:
1-使用自定义字体
2-在显示之前重塑您的文本。
about first 中的一篇好文章是“ MIDP 终端仿真,第 3 部分:MIDP 的自定义字体”。但是对于阿拉伯字母,我认为这并不简单。在大约第二种方式中,假设您将用正确的字符替换文本中的任何字符。这意味着当您有:

String str = "به";

如果获取 str 字符,它们将如下所示:
{1576,1607} 类似于“به”而不是“به”。因此,您可以用正确的 Unicode 代码替换不正确的 Unicode(在这种情况下,正确的字符是:{65169, 65258})。您可以使用“阿拉伯语整形器”甚至是专为 android 设计的整形器!我看到了这个整形器的 2 个链接:1- github 2-阿拉伯语 Android(我是波斯开发人员,所以我不尝试它们,而是我创建与他们有相同想法的课程)。
使用良好的整形器,您也可能会遇到从左到右而不是从右到左排列字符的问题。(有些手机从左到右绘制字符,其他从右到左绘制字符)。我使用下面的类来检测排序是否正确(从右到左)与否:

public class DetectOrdering{   
    public static boolean hasTrueOrdering()
    {
        boolean b = false;
        try {
        char[] chArr = {65169, 65258};
        String str = new String(chArr);
        System.out.println(str);
        int width = f1.charWidth(chArr[1]) / 2;
        int height = f1.getHeight();
        image1 = Image.createImage(width, height);
        image2 = Image.createImage(width, height);
        Graphics g1 = image1.getGraphics();
        Graphics g2 = image2.getGraphics();
        g1.drawString(str, 0, 0, 0);
        g2.drawChar(chArr[1], 0, 0, 0);
        int[] im1 = new int[width * height];
        int[] im2 = new int[width * height];

        image1.getRGB(im1, 0, width, 0, 0, width, height);
        image2.getRGB(im2, 0, width, 0, 0, width, height);
        if (areEqualIntArrrays(im1, im2)) {
            b = true;
        } else {
            b = false;
        }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return b;
    }

private static boolean areEqualIntArrrays(int[] i1, int[] i2) {
    if (i1.length != i2.length) {
        return false;
    } else {
        for (int i = 0; i < i1.length; i++) {
            if (i1[i] != i2[i]) {
                return false;
            }
        }
    }
    return true;
    }
}    

如果 DetectOrdering.hasTrueOrdering() 返回 true,请确保手机从右到左绘制阿拉伯字符并显示您的字符串。如果返回 false,它会从左到右绘制。如果手机从左到右绘制阿拉伯字符,您将在重塑后反转字符串它,然后你可以显示它。

于 2012-06-02T04:05:54.617 回答
1

您可以将一个 alphabet.png 用于直接 unicode 映射(波斯字符不会因为相邻字符而改变的映射)。如果你的字符是等宽的,你可以从下面的类开始,如http://smallandadaptive.blogspot.com.br/2008/12/custom-monospaced-font.html所示:

    公共类 MonospacedFont {

    私有图像图像;
    私有字符 firstChar;
    私人 int numChars;
    私人 int charWidth;

    公共等宽字体(图像图像,char firstChar,int numChars){

        如果(图像==空){
            throw new IllegalArgumentException("image == null");
        }

        // 第一个可见的 Unicode 字符是 '!' (价值 33)
        如果(firstChar <= 33){
            throw new IllegalArgumentException("firstChar <= 33");
        }

        // 图像上必须至少有一个字符
        如果(numChars <= 0){
            throw new IllegalArgumentException("numChars <= 0");
        }

        this.image = 图像;
        this.firstChar = firstChar;
        this.numChars = numChars;
        this.charWidth = image.getWidth() / this.numChars;
    }

    公共无效drawString(图形g,字符串文本,int x,int y){

        // 存储当前图形剪辑区域以便以后恢复
        int clipX = g.getClipX();
        int clipY = g.getClipY();
        int clipWidth = g.getClipWidth();
        int clipHeight = g.getClipHeight();
        char[] 字符 = text.toCharArray();

        for (int i = 0; i < chars.length; i++) {

            int charIndex = chars[i] - this.firstChar;

            // 当前字符存在于图像上
            if (charIndex >= 0 && charIndex <= this.numChars) {
                g.setClip(x, y, this.charWidth, this.image.getHeight());
                g.drawImage(image, x - (charIndex * this.charWidth), y,
                图形.TOP | 图形.左);
                x += this.charWidth;
            }
        }

        // 恢复初始剪辑区域
        g.setClip(clipX,clipY,clipWidth,clipHeight);
    }

}

并将其更改为对每个因相邻字符而更改的波斯字符使用不同的 char_uxxxx.png 文件。

解析字符串时,在绘画之前,您必须检查哪个 png 文件适合使用。希望这是一个很好的起点。

于 2012-06-01T11:36:05.630 回答