2016-06-21 7 views
1

Ich versuche, einen genauen Text über ein Bild in Codename One zu platzieren. Ich berechne den Ort, an dem der Text beginnen soll, basierend auf seiner Breite, so dass er zentriert erscheint.Wie wird die Breite einer gezeichneten Zeichenfolge (in Pixel) mit Codename One genau berechnet?

jedoch die Textbreite, die ich von

myFont.stringWidth(myStringToMeasure); 

bekommen, ist immer viel größer als die tatsächliche gezeichneten Text (ein Rechteck um die Grafik gezeichnet wird, wo der Text gezeichnet wird). Daher sieht der Text überhaupt nicht zentriert aus. Hier ist was ich vom Simulator bekomme.

Part of the background image with the text over it (simulator)

ich versuchte, die Breite jedes char innerhalb myString mit

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

aber das Ergebnis war sogar noch größer, dass die vorhergehende (fast doppelt so groß) zu summieren.

Habe ich die Methode stringWidth missbraucht? Gibt es eine Möglichkeit, die Breite einer gezogenen Saite zuverlässig zu ermitteln?

NB: Ich habe es gerade auf einem Gerät versucht und der Text sah wie erwartet aus. War ich nur glücklich oder funktioniert es auf anderen realen Geräten?

EDIT 1:

Das ist seltsam, ich weiß @Shai richtig ist, aber ich kann es nicht funktioniert bekommen! Wenn ich nur in meiner Methode in seinem Code-Schnipsel fallen bekomme ich völlig anderes Ergebnis:

// 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); 

Ich weiß nicht einmal @ Shais Ergebnis:

Generated image that reflects what is on the simulator's screen (the grey background comes from Gimp)

Jede Idee, was ich falsch gemacht habe?

EDIT 2: OK, wenn ich es auf dem Gerät (Android 4.4) testen, erscheint die Zeichenfolge wie in Shai Bildschirm erfassen. Es sieht also so aus als wäre es eher ein Problem im Zusammenhang mit dem Simulator (alle Skins/Linux/Eclipse 4.5)! Shais Code (und meiner auch tatsächlich) funktioniert gut auf dem echten Gerät.

EDIT 3: Problem gelöst: Ein Upgrade Projekt Libs 114-115 das Problem behoben =>this other SO question which was related

Jede Hilfe willkommen wäre sehr sehen!

Prost

Antwort

1

Char Breite wird definitionsgemäß ungenau sein als Zeichen möglicherweise anders einzeln gezogen werden.

String Breite sollte absolut genau überall sein, wenn das gleiche Font-Objekt:

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(); 

enter image description here

Und mit einer anderen Schriftart ...

@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); 
} 

enter image description here

+0

Dank @Shai. Ich verwende das gleiche Font-Objekt, aber ich erstelle ttf-Font wie 'Font font = Font.createTrueTypeFont (myFontFeatures.get (" FontName_Name "), myFontFeatures.get (" FontName_Name ") +" .ttf "). Derivate (fontSize, styleName); '. Könnte es der Grund sein, warum ich ein anderes Ergebnis erhalte als deines? Ich überprüfe, ob ich irgendwo einen Fehler gemacht habe. – HelloWorld

+0

Siehe aktualisierte Antwort –

+0

Danke Shai, ich habe Ihren ersten Codeausschnitt ausprobiert. Und selbst damit bekomme ich ein anderes Ergebnis (siehe meine Bearbeitung)! Ich habe vielleicht irgendwo etwas verändert, das zu diesem Verhalten führt ... aber ich weiß nicht was! – HelloWorld

Verwandte Themen