2012-02-20 17 views
8

Actualmente estoy trabajando en la representación de un mapa de bits, que luego quiero enviar a una impresora móvil. Sin embargo, estoy luchando para medir la altura de mi texto, por lo que puedo avanzar en la posición y de manera apropiada.Android: medir la altura del texto en un lienzo

Mi configuración básica de mapa de bits/lienzo/pintura es esto (Tamaño de la Fuente tiene 16 años y las dimensiones del mapa de bits son 200x400 (ancho x alto):

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

Hasta aquí todo bien, ahora lo que quieren do es: si uso el método PaintText tengo que proporcionar las coordenadas xey.En cuanto a x eso es cero (suponiendo texto alineado a la izquierda) pero en cuanto a y, tendría que calcular la altura de cada texto que imprimo y agréguelo, entonces puedo hacer un seguimiento de mi posición y actual.

Y aquí es donde se pone extraño: estoy usando el siguiente método para determinar la altura de un texto (usando el Pai) nt objetar que yo ya iniciada - se llama "cepillo"):

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

El método anterior devuelve los siguientes valores para los siguientes textos:

  1. "Hello World" devuelve una altura de
  2. "Una instancia de cámara se puede usar para calcular transformaciones 3D y generar una matriz. "devuelve una altura de 16
  3. " Introducción del diseño de Android: El lugar para aprender acerca de los principios, bloques de construcción, y las pautas de la creación de interfaces de usuario de Android de clase mundial. Si usted es un profesional de UI o un desarrollador que desempeña ese papel, estos documentos le muestran cómo tomar buenas decisiones de diseño, grandes y pequeñas. "devuelve una altura de

Tiene sentido para mí, ese número 2 y 3 de retorno una altura mayor que el número 1, pero si una línea tiene una altura de 12 (como el número uno hace) - se no tiene sentido, que las líneas múltiples tienen una altura de 16?

Me falta algo aquí? Hay un método práctico para medir el ancho de un texto (utilizando una instancia de pintura y llamada measureText ("myText") que funciona perfectamente, sin embargo, estoy bastante perdido, cuando se trata de la altura, ya que los resultados anteriores no tienen ningún sentido para mí.

EDITAR

Soy consciente, que getTextBounds probablemente no hace auto-pack de texto multi-revestido, y eso está bien, ya he escrito un método para el texto de división, pero incluso si sólo medidas de una línea, lo anterior los valores de longitud dados todavía parecen poco probables.

Respuesta

16

Creo que es porque la "p" en "calcular" se extiende por debajo de la línea de base mientras que "Hello World" solo contiene letras que están por encima de la línea de base.

Dado que la distancia de la línea no debe depender de las letras específicas que contiene el texto, probablemente esté buscando Paint.FontMetrics que se puede obtener a través del Paint.getFontMetrics(). Compute descent - ascent + leading para obtener la distancia base recomendada (porque el ascenso tiene un valor negativo).

+0

calculé la distancia de línea de base (según su cálculo) para los tres anteriores textos dados, siempre devuelve 19. Would es decir, si tomo 19 tiene la altura, ¿todavía habría espacio suficiente para que la línea siguiente no se superponga con la línea actual? ¡Muchas gracias por adelantado! – AgentKnopf

+0

Es una característica de la fuente, no tiene que calcularla repetidamente para diferentes textos. Desea que la distancia siempre sea la misma, independientemente de en qué caracteres esté el texto. Y sí, las líneas no se superpondrán. – devconsole

+0

Muchas gracias, eso es lo que hice y hacer que mi mapa de bits funcione bien ahora :). Inicializo la "altura de línea" una vez en el constructor de MyRenderer. – AgentKnopf

4

Hay un pequeño error en la respuesta aceptada. Si desea que el texto altura, se debe utilizar

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

Y si desea que el línea altura, se debe utilizar

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

líder es espaciado interlineal opcional, por lo que si usted necesita obtener la línea alta puede incluirlo. Pero si solo quieres la altura del texto, entonces puedes dejarlo.

Nota

  • nunca he visto realmente leading ser otra cosa que 0, y por lo que yo puedo decir que incluso parece ser ignorado en el TextView source code (y su asociado Layout, StaticLayout, etc.). Por favor corrígeme si estoy equivocado. Por lo tanto, es probable que lo dejen fuera de línea, pero no estoy completamente seguro de eso.

Ver también

Cuestiones relacionadas