2011-10-10 8 views
7

私はテキスト測定とスケーリングされたキャンバスに苦労しました。スケーリングされたキャンバスでテキストを測定する

キャンバスがスケーリングされていない場合、getTextBoundsとmeasureTextは正確な結果を返します。しかし、キャンバスが拡大縮小されている場合、両方のメソッドは印刷されたテキストの実際のサイズに一致する結果を出力しません。

私はonDraw、以下の方法でビューのサブクラスを作成したテストでは

:スケーリング= 0.51以下の結果を canvas scaling 0.5

:私は次の出力を得る= 0.5をスケーリングするための

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

canvas scaling 0.51

黄色の実線の境界線はgetTextBoundsから渡された矩形をマークし、破線のシアンの矩形はfrの幅を使用してレンダリングされますom measureText。

ご覧のとおり、スケーリング= 0.5のテキストは測定されたサイズよりも小さく、スケーリング= 0.51では描画されたテキストが測定されたサイズよりかなり大きくなります。

ご協力いただきましてありがとうございます。私はここに示すように、表示メトリックを使用していたMono for Androidを使用し

答えて

4

[OK]を、ちょうど問題を回避する方法を見つけた。

問題は、ペイントがCanvasスケーリングについて認識していないことです。したがって、measureTextとgetTextBoundsはスケーリングされていない結果を返します。しかし、フォントサイズは線形に拡大されません(しかし、描かれたrectはそうします)ので、その効果を手動で補う必要があります。

だから、解決策は次のようになります。

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

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

f.DrawingFontAndrodid.Text.TextPaint GetDisplayあるところは以下のとおりです。

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

とJavaで同じ方法では、次のとおりです。

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

あなたはありません、常に補正適用されているとキャンバスでのスケーリング値を補償しませんか?私は実際に境界矩形の計算が間違っているとは思っていませんが、フォントレンダリングコードはキャンバススケーリングに応じて適切なフォントサイズを選択しません。 –

+0

はい、スケーリングせずにテキストサイズが必要であると計算されますキャンバス。 –

+0

忘れてしまったのは、キャンバス内のテキストの配置に使用され、正確な寸法と位置が必要であることがわかっています。 –

関連する問題