折腾记录

Android 字体高度的研究

2022-12-02 11:29:51 michael007js 412
  • Android自定义View绘制的时候,会有很多情况下要与字体打交道,涉及到字体宽度、高度的时候要特别注意一下几个概念,见图:


    img

    image.png

    baseLine:一行文字的底线。

    Ascent: 字符顶部到baseLine的距离。

    Descent: 字符底部到baseLine的距离。

    Leading: 字符行间距。


    public class TestOnDraw extends Activity {   
     
       @Override  
       protected void onCreate(Bundle savedInstanceState) {  
           // TODO Auto-generated method stub  
           super.onCreate(savedInstanceState);  
           MyView v = new MyView(this);  
           this.setContentView(v);  
     }  
    }  
     
    class MyView extends View  
    {  
     
       public MyView(Context context) {  
           super(context);  
     }  
       @Override  
       protected void onDraw(Canvas canvas) {  
           super.onDraw(canvas);  
             
           Paint p = new Paint();  
           p.setColor(Color.WHITE);  
           p.setTextSize(50);  
           p.setAntiAlias(true);  
           FontMetrics fm = p.getFontMetrics();  
             
           System.out.println("top = "+ fm.top);  
           System.out.println("ascent = "+ fm.ascent);  
           System.out.println("descent = "+ fm.descent);  
           System.out.println("bottom = "+ fm.bottom);  
           System.out.println("leading = "+ fm.leading);  
             
           int textHeight = (int) (Math.ceil(fm.descent - fm.ascent) + 2);  
           System.out.println("textHeight = "  + textHeight);  
             
           float width =500;  
           float baseline = 100f;  
           float offsetAscent = baseline + fm.ascent;  
           float offsetDescent = baseline +fm.descent;  
           float offsetTop = baseline + fm.top;  
           float offsetBottom = baseline + fm.bottom;  
             
           canvas.drawText("中国 bp Android", 0, baseline, p);  
             
           canvas.drawLine(0, baseline, width, baseline, p);//baseline  
           canvas.drawLine(0, offsetAscent, width, offsetAscent, p);//ascent  
           canvas.drawLine(0, offsetDescent, width, offsetDescent, p);//descent  
           canvas.drawLine(0, offsetTop, width, offsetTop, p);//top  
           canvas.drawLine(0, offsetBotton, width, offsetBottom, p);//bottom  
     }  
    }  


    public class TestOnDraw extends Activity {  
     
       @Override  
       protected void onCreate(Bundle savedInstanceState) {  
           // TODO Auto-generated method stub  
           super.onCreate(savedInstanceState);  
           MyView v = new MyView(this);  
           this.setContentView(v);  
     }  
    }  
     
    class MyView extends View  
    {  
     
       public MyView(Context context) {  
           super(context);  
     }  
       @Override  
       protected void onDraw(Canvas canvas) {  
           super.onDraw(canvas);  
             
           Paint p = new Paint();  
           p.setColor(Color.WHITE);  
           p.setTextSize(50);  
           p.setAntiAlias(true);  
           FontMetrics fm = p.getFontMetrics();  
             
           System.out.println("top = "+ fm.top);  
           System.out.println("ascent = "+ fm.ascent);  
           System.out.println("descent = "+ fm.descent);  
           System.out.println("bottom = "+ fm.bottom);  
           System.out.println("leading = "+ fm.leading);  
             
           int textHeight = (int) (Math.ceil(fm.descent - fm.ascent) + 2);  
           System.out.println("textHeight = "  + textHeight);  
             
           float width =500;  
           float baseline = 100f;  
           float offsetAscent = baseline + fm.ascent;  
           float offsetDescent = baseline +fm.descent;  
           float offsetTop = baseline + fm.top;  
           float offsetBottom = baseline + fm.bottom;  
             
           canvas.drawText("中国 bp Android", 0, baseline, p);  
             
           canvas.drawLine(0, baseline, width, baseline, p);//baseline  
           canvas.drawLine(0, offsetAscent, width, offsetAscent, p);//ascent  
           canvas.drawLine(0, offsetDescent, width, offsetDescent, p);//descent  
           canvas.drawLine(0, offsetTop, width, offsetTop, p);//top  
           canvas.drawLine(0, offsetBotton, width, offsetBottom, p);//bottom  
     }  
    }  

    运行效果:


    img

    image.png

    这是程序的输出结果:


    img

    image.png

    得出结论: canvas drawText() 的startX是从左下角的baseline的底线开始绘画的,如果我们要得到字体的高度需要关注descent - ascent (ascent线在baseline上面,所以是负数)


首页
关于博主
我的博客
搜索