在缩放画布测量文本画布、缩放、测量、文本

2023-09-05 23:48:59 作者:何必打扰

我一直挣扎着文字的测量和缩放画布。

I've been struggling with text measuring and scaled canvases.

在画布缩放的,getTextBounds和measureText提供准确的结果。然而,当画布缩放两种方法也不能提供匹配的印刷文本的实际大小的结果。

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.

有关测试我创建视图的子类,下面的OnDraw方法:

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

缩放= 0.5我得到以下的输出:

for scaling = 0.5 I get the following output:

缩放= 0.51以下结果所示:

for scaling = 0.51 the following result is shown:

黄色固体边界标志着getTextBounds交付的矩形,虚线青色RECT使用从measureText交付的宽度渲染。

The yellow solid border marks the rect delivered from getTextBounds, the dashed cyan rect is rendered using the width delivered from measureText.

正如你所看到的,与缩放文本= 0.5比测量的尺寸和比例较小= 0.51绘制的文本比测量维度的方式做大。

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.

任何帮助是AP preciated!

Any help is appreciated!

推荐答案

好吧,就发现了如何绕过这个问题。

Ok, just found out how to circumvent the issue.

问题在于:油漆不知道关于画布缩放。因此measureText和getTextBounds提供非标度的结果。但由于字体大小不线性扩展(但是,绘制矩形一样),你必须弥补人工这种效果。

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.

所以,解决办法是:

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