Aexi(4)-字體

已經好久都沒有更新博客了,確實最近本大二狗學校裏面的事情比較多,終於處理完了,下面更新博客的速度也會加快的.而且這個項目確實拖了比較長的時間了,我也給自己設置一個DeadLine吧.下月10號將PC平臺上的Aexi完成,下月20號之前將其移植到Android平臺上,並抽象出主要部分,封裝成一個庫發到Github上面.

    下面就開始這次博客的內容,這次博客的主要想寫一個開發過程中的小問題—字體.下面先簡單介紹一下目前的項目主要類結構.


UML簡圖一張(本人沒有系統的學過UML,各位看官不要深究細節哈).

可以看到,每個繼承自GlyphImpl的對象都有一個frame屬性,frame屬性(命名來自iOS),記錄了該Glyph的位置以及寬高信息.這個frame的值由compositor對象中的compose方法中進行賦值.然後在compose方法執行完畢排版結束之後,調用每個Glyph的drawme()方法繪製自身.其中,drawMe()方法中就會使用賦值過的frame中存儲的信息進行繪製.

    主要的過程都介紹完了,在實際開發過程中,我們遇到了一個非常令人費解的現象.請看圖:


可以清楚的看到,我們的Caret對象跑到了文字的下面.

爲什麼會出現這種問題呢?是我們的參數傳遞的有問題嗎?爲了驗證,我又新建了一個項目,繪製了幾個圖形,請看圖.


在Y值傳入的參數相同的情況下,drawString方法繪製的文字和其他圖形繪製方法繪製的圖形的位置就是不一樣.

    根據圖上顯示的位置,其實很容易就認爲其實文字繪製的起始點座標在文字的左下角,因爲圖上很明顯,傳入相同的Y 值,而文字繪製在上,圖形繪製在下面.但是實際上這樣想很接近了,但是還是不對.我們將圖片放大了看,請看圖:


放大了看,其實還是有幾個像素伸下來的,所以並不是整個文字的左下角.

    那麼這到底是怎麼回事呢?

    遇到這樣的問題,我們就要去查找萬能的API文檔了.首先我們想到的是Font類.在搜索遍了font類後,筆者找到了關鍵所在,那就是fontMetrics類.


    實際上,Graphics的DrawString()方法中給出的x參數和Y參數就是字體文件的baseLine的左頂點的座標.


看不清楚baseLine看上面這張圖就可以了.

    那麼在代碼中如何獲取到asent和desent的數據呢?廢話不多說上代碼.

.

通過sun.font.FontDesignMetrics這個類的getMetrics方法,可以獲取到一個現成的font類的fontmetrics對象,這個對象就封裝了該font的這些信息.調用相應的方法就可以獲取到了

    最後一個問題,我們在排版時,顯然不希望對frame賦值時需要計算相應的數值而對character區別對待,並且每個文字的大小顯然不能由外部來決定,而應該由該character的字體的大小來決定.爲了能對外提供統一訪問的對待,我們仍然把frame的x,y當成該字體的左上角來對待,而在字符的繪製方法時,將其轉換爲基線座標.代碼如下.


這樣我們就可以實現文字和圖形的統一排版了

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章