您的位置:首页 > 移动开发 > Android开发

Android字体属性Paint.FontMetrics

2015-07-30 18:11 423 查看

(一) 字体的几个参数 ,以Android API文档定义为准,见下图



要点如下:

1. 基准点是baseline

2. Ascent是baseline之上至字符最高处的距离

3. Descent是baseline之下至字符最低处的距离

4. Leading文档说的很含糊,这个我还不清楚,但有人说是上一行字符的descent到下一行的ascent之间的距离,也有人说不是

5. Top指的是指的是最高字符到baseline的值,即ascent的最大值

6. 同上,bottom指的是最下字符到baseline的值,即descent的最大值


(二)贴几张图看看:

pic_1



pic_2



pic_3

字体为斜体状态下(你没有看错,中文只设置mPaint.setTypeface(Typeface.create("", Typeface.ITALIC))是斜体不了的):



pic-4





上验证代码:

public class MyView extends View {

private Paint mPaint = new Paint();

public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
mPaint.reset();
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(80);
//设置字体为斜体
mPaint.setTypeface(Typeface.create("", Typeface.ITALIC));
// FontMetrics对象
FontMetrics fontMetrics = mPaint.getFontMetrics();
String text = "中国话fgiqÃÇŸŒú";
// 计算每一个坐标
float textWidth = mPaint.measureText(text);
float baseX = 30;
float baseY = 700;
float topY = baseY + fontMetrics.top;
float ascentY = baseY + fontMetrics.ascent;
float descentY = baseY + fontMetrics.descent;
float bottomY = baseY + fontMetrics.bottom;
// 绘制文本
canvas.drawText(text, baseX, baseY, mPaint);
// BaseLine描画
mPaint.setColor(Color.RED);
canvas.drawLine(baseX, baseY, baseX + textWidth, baseY, mPaint);
mPaint.setTextSize(20);
canvas.drawText("base", baseX + textWidth, baseY, mPaint);
// Base描画
canvas.drawCircle(baseX, baseY, 5, mPaint);
// TopLine描画
mPaint.setColor(Color.LTGRAY);
canvas.drawLine(baseX, topY, baseX + textWidth, topY, mPaint);
canvas.drawText("top", baseX + textWidth, topY, mPaint);
// AscentLine描画
mPaint.setColor(Color.GREEN);
canvas.drawLine(baseX, ascentY, baseX + textWidth, ascentY, mPaint);
canvas.drawText("ascent", baseX + textWidth, ascentY + 10, mPaint);
// DescentLine描画
mPaint.setColor(Color.YELLOW);
canvas.drawLine(baseX, descentY, baseX + textWidth, descentY, mPaint);
canvas.drawText("descent", baseX + textWidth, descentY, mPaint);
// ButtomLine描画
mPaint.setColor(Color.MAGENTA);
canvas.drawLine(baseX, bottomY, baseX + textWidth, bottomY, mPaint);
canvas.drawText("buttom", baseX + textWidth, bottomY + 10, mPaint);
super.onDraw(canvas);
}
}


(三)将字画在矩形背景的正中位置

FontMetrics.top的数值是个负数,其绝对值就是字体绘制边界到baseline的距离。

所以如果是把文字画在 FontMetrics高度的矩形中, drawText就应该传入 -FontMetrics.top。

要画在targetRect的居中位置,baseline的计算公式就是(本人抄的原博主的,也不知道怎么计算的):

targetRect.top + (targetRect.bottom - targetRect.top) / 2 - (FontMetrics.bottom - FontMetrics.top) / 2 - FontMetrics.top


代码应该改成(顺便加入水平居中):

[java] view
plaincopy





@Override

public void onDraw (Canvas canvas) {

Rect targetRect = new Rect(50, 50, 1000, 200);

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

paint.setStrokeWidth(3);

paint.setTextSize(80);

String testString = "测试:ijkJQKA:1234";

paint.setColor(Color.CYAN);

canvas.drawRect(targetRect, paint);

paint.setColor(Color.RED);

FontMetricsInt fontMetrics = paint.getFontMetricsInt();

// 转载请注明出处:http://blog.csdn.net/hursing

int baseline = targetRect.top + (targetRect.bottom - targetRect.top - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;

// 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX()

paint.setTextAlign(Paint.Align.CENTER);

canvas.drawText(testString, targetRect.centerX(), baseline, paint);

}

效果:






(四)注意:

A:一个字符f得到的测试结果与上边的代码得到的fontmetrics值相同。

B:如果pain设置的textSize均为55,或者textView设置字体大小为55,且为相同的字符串,但是两个获得的FontMetrics属性值并不相同。但是,我们发现,做除法之后,均为1.5倍关系。做出猜测,即Paint下,为mdpi对应的size,而TextView的size已经关联到了显示屏幕本身的320dip。所以获得属性值均为整1.5倍数

C:各种情况下,均未获得leading值。

D:好似还可以直接让CPU来渲染字体,出门右转http://blog.jobbole.com/70468/点击打开链接

参考:http://blog.csdn.net/hursing/article/details/18703599

参考:http://blog.jobbole.com/70468/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: