我一直在努力学习文本测量和缩放的画布.
当画布未缩放时,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,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传送的rect,使用measureText传送的宽度呈现虚线青色rect.
如您所见,缩放= 0.5的文本小于测量的尺寸,缩放= 0.51,绘制的文本大于测量的尺寸.
任何帮助表示赞赏!
解决方法
好的,刚刚发现如何绕过这个问题.
问题是Paint不知道Canvas缩放.因此,measureText和getTextBounds提供未缩放的结果.但由于字体大小不能线性缩放(但是,绘制的矩形确实如此),您必须手动补偿该效果.
所以解决方案是:
// paint the text as usual Paint paint = new Paint(); paint.setTypeface(font); paint.setTextSize(fontSize); canvas.drawText(text,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;