2011-10-10 4 views
7

Ho avuto problemi con la misurazione del testo e le tele ridimensionate.misurazione del testo su tela in scala

Quando il canvas non è in scala, getTextBounds e measureText forniscono risultati accurati. Tuttavia, quando la tela viene ridimensionata, entrambi i metodi non forniscono risultati corrispondenti alla dimensione effettiva di un testo stampato.

Per la prova ho creato una sottoclasse di vista con il seguente metodo OnDraw:

final float scaling = 0.51f; 
final int fontSize = 50; 

canvas.scale(scaling, scaling); 
font = Typeface.create("Arial", Typeface.NORMAL); 

Paint paint = new Paint(); 
paint.setColor(0xff4444ff); 
paint.setTypeface(font); 
paint.setTextSize(fontSize); 
paint.setAntiAlias(true); 

int x = 10; 
int y = 100; 
final String text = "Lorem ipsum dolor sit amet, consectetur adipisici elit..."; 
canvas.drawText(text, x, y, paint); 

// draw border using getTextBounds 

paint.setColor(0xffff0000); 
paint.setStyle(Paint.Style.STROKE); 
paint.setTypeface(font); 
paint.setTextSize(fontSize); 
Rect bounds = new Rect(); 
paint.getTextBounds(text, 0, text.length(), bounds); 
bounds.offset(x, y); 
paint.setColor(0x80ffff00); 
canvas.drawRect(bounds, paint); 

// draw border using measureText 

float w = paint.measureText(text); 
bounds.left = x; 
bounds.right = (int) Math.ceil(bounds.left + w); 
bounds.top -= 10; 
bounds.bottom += 10; 
paint.setColor(0x8000ffff); 
paint.setPathEffect(new DashPathEffect(new float[] { 10, 10 }, 0)); 
canvas.drawRect(bounds, paint); 

per il ridimensionamento = 0.5 ottengo il seguente output: canvas scaling 0.5

per scalare = 0.51 il seguente risultato è mostrato: canvas scaling 0.51

Il bordo solido giallo indica il rettangolo consegnato da getTextBounds, il retto cyan viene eseguito utilizzando la larghezza fornita da om measureText.

Come si può vedere, il testo con ridimensionamento = 0,5 è inferiore alle dimensioni misurate e con ridimensionamento = 0,51 il testo disegnato è molto più grande della dimensione misurata.

Qualsiasi aiuto è apprezzato!

risposta

4

Ok, ho appena scoperto come aggirare il problema.

Il problema è che Paint non è a conoscenza del ridimensionamento della tela. Pertanto measureText e getTextBounds forniscono il risultato non graduato. Ma dal momento che la dimensione del font non viene ridimensionata linearmente (tuttavia, il rect disegnato fa), devi recuperare manualmente quell'effetto.

Quindi la soluzione sarebbe:

// paint the text as usual 
Paint paint = new Paint(); 
paint.setTypeface(font); 
paint.setTextSize(fontSize); 
canvas.drawText(text, x, y, paint); 


// measure the text using scaled font size and correct the scaled value afterwards 
Paint paint = new Paint(); 
paint.setTypeface(font); 
paint.setTextSize(fontSize * scaling); 
float w = paint.measureText(text)/scaling; 
0

Utilizzando Mono for Android Ho dovuto usare metriche di visualizzazione come mostrato di seguito:

public override System.Drawing.SizeF MeasureString(MyFont f, string text) 
{ 
    Rect r = new Rect(); 

    f.DrawingFont.GetTextBounds(text, 0, text.Length, r); 

    //Manual scaling using DisplayMetrics due to Android 
    //issues for compatibility with older versions 
    Android.Util.DisplayMetrics metrics = new Android.Util.DisplayMetrics(); 
    GetDisplay.GetMetrics(metrics); 

    return new System.Drawing.SizeF(r.Width(), r.Height() * metrics.Density); 
} 

Dove f.DrawingFont è un Androdid.Text.TextPaint GetDisplay è:

private Display GetDisplay() 
{ 
    return this.GetSystemService(Android.Content.Context.WindowService).JavaCast<Android.Views.IWindowManager>().DefaultDisplay; 
} 

E lo stesso metodo in Java è:

private Display getDisplay() { 
    return ((WindowManager) getContext().getSystemService(
      Context.WINDOW_SERVICE)).getDefaultDisplay(); 
} 
+0

voi sono correzione viene applicata sempre e non compensa per un valore di scala nel Canvas, no? In realtà non penso che il calcolo del rettangolo di delimitazione sia errato, ma che il codice di rendering dei caratteri non scelga la dimensione corretta del font in base al ridimensionamento del canvas ... –

+0

Sì, si calcola sempre che le dimensioni del testo siano necessarie senza ridimensionamento la tela. –

+0

Dimenticato di menzionare questo è usato principalmente per posizionare il testo nella tela, conoscendo le dimensioni esatte e la posizione è necessaria. –