测量缩放画布上的文本
我一直在努力处理文本测量和缩放画布。
当画布未缩放时,getTextBounds 和measureText 可提供准确的结果。但是,当画布缩放时,这两种方法都无法提供与打印文本的实际大小相匹配的结果。
为了进行测试,我使用以下 onDraw 方法创建了 View 的子类:
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);
对于缩放 = 0.5,我得到以下输出:
对于缩放 = 0.51,显示以下结果:
黄色实线边框标记从 getTextBounds 传递的矩形,青色虚线矩形使用从measureText传递的宽度渲染。
如您所见,缩放 = 0.5 的文本小于测量的尺寸,而缩放 = 0.51 的绘制文本远大于测量的尺寸。
任何帮助表示赞赏!
I've been struggling with text measuring and scaled canvases.
When the canvas is unscaled, getTextBounds and measureText deliver accurate results. However, when the canvas is scaled both methods do not deliver results that match the actual size of a printed text.
For testing I've created a subclass of View with the following onDraw method:
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);
for scaling = 0.5 I get the following output:
for scaling = 0.51 the following result is shown:
The yellow solid border marks the rect delivered from getTextBounds, the dashed cyan rect is rendered using the width delivered from measureText.
As you can see, the text with scaling = 0.5 is smaller than the measured dimensions and with scaling=0.51 the drawn text is way bigger than the measured dimension.
Any help is appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,刚刚知道如何规避这个问题。
问题是 Paint 不知道 Canvas 缩放。因此,measureText 和 getTextBounds 提供未缩放的结果。但由于字体大小不会线性缩放(但是,绘制的矩形会线性缩放),因此您必须手动弥补该影响。
所以解决方案是:
Ok, just found out how to circumvent the issue.
The problem is that the Paint does not know about the Canvas scaling. Therefore measureText and getTextBounds deliver the unscaled result. But since the font size does not scale linearly (however, the drawn rect does ), you have to make up for that effect manually.
So the solution would be:
使用 Mono for Android 我必须使用显示指标,如下所示:
其中 f.DrawingFont 是 Androdid.Text.TextPaint GetDisplay 是:
和相同的方法在Java中是:
Using Mono for Android I had to use display metrics as shown here:
Where f.DrawingFont is an Androdid.Text.TextPaint GetDisplay is:
And the same method in Java is: