2011-10-10 41 views
7

Tôi đã đấu tranh với các thước đo văn bản và canvas được chia tỷ lệ.đo văn bản trên canvas thu nhỏ

Khi canvas được bỏ kích thước, getTextBounds và measureText cung cấp kết quả chính xác. Tuy nhiên, khi canvas được chia tỷ lệ cả hai phương pháp không phân phối kết quả phù hợp với kích thước thực tế của văn bản được in.

Để thử nghiệm tôi đã tạo ra một lớp con của View với phương pháp onDraw sau:

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

cho nhân rộng = 0,5 tôi nhận được kết quả như sau: canvas scaling 0.5

cho nhân rộng = 0,51 kết quả sau được hiển thị: canvas scaling 0.51

Đường viền màu vàng màu vàng đánh dấu đoạn thẳng được phân phối từ getTextBounds, đường thẳng lục lam bị đứt được hiển thị bằng chiều rộng được phân phối fr om measureText.

Như bạn có thể thấy, văn bản có tỷ lệ = 0,5 nhỏ hơn kích thước được đo và với tỷ lệ = 0,51 văn bản được vẽ lớn hơn kích thước được đo.

Mọi trợ giúp đều được đánh giá cao!

Trả lời

4

Ok, chỉ cần tìm ra cách để phá vỡ vấn đề.

Vấn đề là Paint không biết về tỷ lệ Canvas. Do đó measureText và getTextBounds cung cấp kết quả chưa được đánh số. Nhưng kể từ khi kích thước font không quy mô tuyến tính (tuy nhiên, rect rect), bạn phải bù đắp cho hiệu ứng đó bằng tay.

Vì vậy, các giải pháp sẽ là:

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

Sử dụng Mono for Android tôi đã sử dụng số liệu hiển thị như hình ở đây:

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

đâu f.DrawingFont là một Androdid.Text.TextPaint GetDisplay là:

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

Và cùng một phương pháp trong Java là:

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

bạn đang chỉnh được áp dụng luôn và không bù đắp cho một giá trị mở rộng quy mô trong Canvas, không? Tôi thực sự không nghĩ rằng việc tính toán đường biên giới hạn là không chính xác, nhưng mã hiển thị phông chữ không chọn kích thước phông chữ phù hợp theo tỷ lệ khung hình ... –

+0

Vâng, nó luôn được tính toán rằng kích thước văn bản là cần thiết mà không cần chia tỷ lệ canvas. –

+0

Quên đề cập đến điều này được sử dụng chủ yếu được sử dụng để định vị văn bản trong canvas, biết kích thước chính xác và vị trí là cần thiết. –

Các vấn đề liên quan