如何使用代号一准确获取绘制字符串的宽度(以像素为单位)?

How to accurately get the width of a drawn String (in pixel) with Codename One?

我正在尝试在代号一中的图像上准确放置一段短文本。我根据文本的宽度计算文本应该开始的位置,以便它显示在中间。

但是我从

得到的文本宽度
myFont.stringWidth(myStringToMeasure);

总是比实际绘制的文本大很多(在绘制文本的图形周围绘制了一个矩形)。因此文本看起来根本不居中。这是我从模拟器中得到的。

我试图将 myString 中每个字符的宽度与

求和
for (char c : myString.toCharArray()) {
     stringWidth += myFont.charWidth(c);
}

但结果比上一个更大(几乎是原来的两倍)。

我是否误用了 stringWidth 方法?有没有办法可靠地获取绘制字符串的宽度?

注意:我刚刚在设备上试了一下,文本看起来和预期的一样。是我运气好还是它可以在其他真实设备上运行?

编辑 1:

这很奇怪,我知道@Shai 是对的,但我无法让它工作!如果我只是在我的方法中加入他的代码片段,我会得到完全不同的结果:

    // width and height are the Graphics width and height that
    // has been created via Image.createImage(myImage.getWidth(), myImage.getHeight())
    public void paintOnBackground(Graphics g, 
        int width, int height) {

     Font myFont = g.getFont();
        g.setFont(myFont);
        int w = myFont.stringWidth("Hi World");
        int h = myFont.getHeight();

        // Added just to see the background
        g.setColor(0x0000FF);
        g.fillRect(0, 0, width, height);

        g.setColor(0xff0000);
        // Because g.getTranslateX() is equivalent to getX() (not available here)
        int x = g.getTranslateX() + width / 2 - w / 2;
        int y = g.getTranslateY() + height / 2 - h / 2;

        // The rectangle is centered
        g.drawRect(x, y, w, h, 20); // large thickness to see it at a glance!
        // The string is outside the rectangle
        g.drawString("Hi World", x, y);

我什至没有得到@Shai 的结果:

知道我做错了什么吗?

编辑 2:好的,如果我在设备 (Android 4.4) 上测试它,该字符串将出现在 Shai 的屏幕截图中。 所以看起来这是一个与模拟器相关的问题(所有皮肤/Linux/Eclipse 4.5)! Shai 的代码(实际上也是我的)在真实设备上运行良好。

编辑 3:问题已解决:将项目库从 114 升级到 115 解决了问题 => 请参阅

如有任何帮助,我们将不胜感激!

干杯

根据定义,字符宽度将不准确,因为字符可能单独绘制不同。

当使用相同的字体对象时,字符串宽度在任何地方都应该完全准确:

Form f = new Form("Width", new BorderLayout());
f.add(BorderLayout.CENTER, new Component() {

    @Override
    protected void initComponent() {
        super.initComponent(); 
        setUIID("Label");
    }


    @Override
    public void paint(Graphics g) {
        Font myFont = getStyle().getFont();
        g.setFont(myFont);
        int w = myFont.stringWidth("Hi World");
        int h = myFont.getHeight();
        g.setColor(0xff0000);
        int x = getX() + getWidth() / 2 - w / 2;
        int y = getY() + getHeight() / 2 - h / 2;
        g.drawRect(x, y, w, h);
        g.drawString("Hi World", x, y);
    }

});
f.show();

并使用不同的字体...

@Override
protected void initComponent() {
    super.initComponent(); 
    setUIID("Label");
    Font handleeFont = Font.createTrueTypeFont("Handlee", "Handlee-Regular.ttf").
                    derive(Font.getDefaultFont().getHeight(), Font.STYLE_PLAIN);
    Font handleeFontLarge = handleeFont.derive(handleeFont.getHeight() * 1.5f, Font.STYLE_PLAIN);
    getUnselectedStyle().setFont(handleeFontLarge);
}