2012-02-20 20 views
8

Attualmente sto lavorando al rendering di una bitmap, che poi desidero inviare a una stampante portatile. Tuttavia, sto lottando con la misurazione dell'altezza del mio testo, così posso avanzare appropriatamente la posizione y.Android: misura l'altezza del testo su una tela

La mia configurazione di base bitmap/tela/pittura è presente (dimensione del carattere è 16 e le dimensioni del bitmap sono 200x400 (larghezza x altezza):

public MyRenderer() { 
    // Initialize bitmap 
    bitmap = Bitmap.createBitmap(200, 400, Bitmap.Config.ARGB_8888); 

    // Initialize canvas 
    canvas = new Canvas(bitmap); 

    // Initialize brush (Paint instance) 
    brush = new Paint(); 
    brush.setTextSize(16); 
    brush.setTypeface(Typeface.SANS_SERIF); 
    brush.setColor(Color.BLACK); 
    brush.setStyle(Paint.Style.FILL); 
    brush.setAntiAlias(true); 
    brush.setTextAlign(Align.LEFT); 
} 

Fin qui tutto bene, ora quello che voglio do is: Se uso il metodo Paint drawText ho bisogno di fornire le coordinate x e y. Come x che è zero (assumendo il testo allineato a sinistra) ma per quanto riguarda y, dovrei calcolare l'altezza di ogni testo che stampo e aggiungilo, quindi posso tenere traccia della mia posizione attuale.

E questo è dove diventa strano: sto usando il seguente metodo per determinare l'altezza di un testo (usando il Pai nt obiettato che ho inizializzato in precedenza - si chiama "pennello"):

public int measureHeight(String text) { 
    Rect result = new Rect(); 
    // Measure the text rectangle to get the height 
    brush.getTextBounds(text, 0, text.length(), result); 
    return result.height(); 
} 

Il metodo di cui sopra restituisce i seguenti valori per i seguenti testi:

  1. "Ciao Mondo" restituisce un'altezza di
  2. "Un'istanza telecamera può essere utilizzata per calcolare trasformazioni 3D e generare una matrice. "restituisce un'altezza di 16
  3. " Introducendo design Android: il luogo ideale per conoscere i principi, blocchi da costruzione, ed i modelli per la creazione di classe mondiale interfacce utente Android. Che tu sia un professionista dell'interfaccia utente o uno sviluppatore che giochi questo ruolo, questi documenti ti mostrano come prendere buone decisioni di progettazione, grandi e piccole. "restituisce un'altezza di

Ha senso per me, che il numero 2 e 3 di ritorno un'altezza maggiore di numero 1, ma se una riga ha un'altezza di 12 (come il numero uno fa) - è non ha senso, che più righe hanno un'altezza di 16?

Mi manca qualcosa qui? C'è un metodo comodo per misurare la larghezza di un testo (usando un'istanza di vernice e chiamata measureText ("myText") che funziona perfettamente, tuttavia sono abbastanza in perdita, quando si arriva all'altezza, poiché i risultati sopra riportati non hanno alcun senso per me.

EDIT

Sono consapevole, che getTextBounds probabilmente non fa auto-wrapping di testo su più righe, e questo è ok, ho già scritto un metodo per il testo scissione, ma anche se misura una sola riga, di cui sopra i valori di lunghezza dati sembrano ancora improbabili.

risposta

16

Penso che sia perché la "p" in "calcolo" si estende al di sotto della linea di base mentre "Hello World" contiene solo lettere che si trovano sopra la linea di base.

Poiché la distanza della linea non deve dipendere da quali lettere specifiche il testo è composto da te probabilmente stai cercando Paint.FontMetrics che può essere ottenuto tramite Paint.getFontMetrics(). Calcola descent - ascent + leading per ottenere la distanza della linea di base raccomandata (perché la risalita ha un valore negativo).

+0

ho calcolato la distanza della linea di base (come per il calcolo) per coloro che tre di cui sopra riportati testi, restituisce sempre 19. Would cioè, se prendo 19 ha l'altezza, ci sarebbe ancora abbastanza spazio per la linea successiva da non sovrapporsi alla linea corrente? Grazie mille in anticipo! – AgentKnopf

+0

È una caratteristica del carattere, non è necessario calcolarlo ripetutamente per testi diversi. Vuoi che la distanza sia sempre la stessa, indipendentemente da quali caratteri il tuo testo consista. E sì, le linee non si sovrappongono. – devconsole

+0

Grazie mille - questo è quello che ho fatto e il rendering della mia bitmap funziona bene ora :). Inizializzo la "altezza della linea" una volta nel costruttore di MyRenderer. – AgentKnopf

4

C'è un piccolo errore nella risposta accettata. Se si desidera che il testo altezza, si dovrebbe usare

Paint.FontMetrics fm = mTextPaint.getFontMetrics(); 
float textHeight = fm.descent - fm.ascent; 

E se si desidera che la linea di altezza, si dovrebbe usare

float lineHeight = fm.bottom - fm.top + fm.leading; 

leader è la spaziatura interlinea opzionale, quindi se avete bisogno di ottenere la linea alta si può includere. Ma se vuoi solo l'altezza del testo, puoi lasciarlo fuori.

Nota

  • non ho mai visto leading essere altro che 0, e, per quanto posso dire che sembra addirittura essere ignorato nel TextView source code (e il suo associato Layout, StaticLayout, eccetera.). Per favore correggimi se sbaglio. Quindi è probabilmente sicuro che lo lasci fuori linea, ma non ne sono completamente sicuro.

Vedi anche