Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android手機字體庫相關問題深入剖析

android手機字體庫相關問題深入剖析

編輯:關於Android編程

問題一、android系統支持什麼字體庫?

1、Android系統默認支持三類字體家族,分別為:“serif”,“sans-serif”,“monospace",那如何證明?具體論證與定義詳見下面的知識點。

這三類字體家族,每一類都包括若干個*.ttf的字體文件。除此之外,每個設備廠商在此基礎上,都會額外增加一些自己定義的字體文件*.ttf,以兼容更多的語言及字體風格。

以三星手機(SM-N7508V)為例:這些字體文件總計84個(如下圖)。

\

問題二、不同設備手機默認獲取的字體是什麼?(以三星(SM-N7508V)手機為例)

在/system/etc/system_fonts.xml文件中有如下描述

\

也就是說,在沒有指定具體的字體名字的情況下,系統默認使用的字體家族是第一標簽中顯示的字體家族。

一個xml文件中有多個字體家族,而多個字體家族會形成一個鏈表,如果整個鏈表中都沒有某個字體,那麼就在system/ect/fallback_fonts.xml配置文件中去找其他字體的描述。

如果我們想要額外增加或修改字體,則需要在vendor/etc/fallback_fonts.xml文件中進行配置。

代表該font family的名字,一般第一個標簽代表字體家族的名字。表示該font family所對應的*.ttf文件.每個字體家族都可以有normal,

粗體,斜體字,粗斜體等四種樣式。但並不都是必須要有的。從上圖中可以看出,三星(SM-N7508V)這個手機,(結論)優先使用的字體庫為"Roboto-Regular.ttf"、"bold.ttf"、

"italic.ttf"、"Roboto- BoldItalic.ttf"。分別代表正常,粗體,斜體字,粗斜體等四種樣式。三星手機字體庫文件請見附件。

在 system/ect/fallback_fonts.xml文件中有如下描述:

\

這個文件中再次說明了,如果這個字體家族中沒有某個字體,那麼可以在system/ect/fallback_fonts.xml配置文件中找到其他字體的描述。

思考:那麼這些XML文件是如何解析,字體庫又是如何被初始化的。(請見第三部分<其他相關知識擴充>)。

3、不同手機設備,配置文件是不同的。也就是說,不同的手機,用的字體庫也是不同的。

如VIVO手機(型號X5M): 用的完全是自己的字體庫,如下圖:

\

4、 我們的H5頁面使用的樣式字體為:SimHei

當手機浏覽器在手機系統中能找到SimHei,則使用SimHei;找不到這個SimHei時,默認會選擇手機系統中默認字體。

相關知識點:

a、Serif的意思是,在字的筆劃開始及結束的地方有額外的裝飾,而且筆劃的粗細會因直橫的不同而有不同。相反的,SansSerif則沒有這些額外的裝飾,筆劃粗細大致差不多

Serif和SansSerif的一般比較

1)Serif的字體容易辨認,因此易讀性較高。反之SansSerif則較醒目,但在行文閱讀的情況下,SansSerif容易造成字母辨認的困擾,常會有來回重讀及上下行錯亂的情形。

2)Serif強調了字母筆劃的開始及結束,因此較易前後連續性的辨識。

3)Serif強調一個word,而非單一的字母,反之SansSerif則強調個別字母。

4)在小字體的場合,通常SansSerif比Serif更清晰。

5)可以看出,我們平時所用的Georgia、TimesNewRoman等就屬於Serif字體,而Arial、Tahoma、Verdana等則屬於SansSerif字體。

對中文而言,同樣存在這兩大種類,很明顯,宋體、細明體(繁體中常用)等就屬於Serif,而黑體、幼圓等則屬於SansSerif。

b、Monospace:等寬字體,它是指每個字符寬度都一致的字體。一個著名的例子就是CourierNew字體。因為字符寬度一致,所以這種字體特別容易對齊,

能快速精確的定位到某行某列,因此經常用來顯示代碼

二、問題二:關於全角半角的問題?

1、漢字:不管全角還是半角,漢字要占用兩個字節。

2、數字與字母:半角與全角都是一個字節

3、標點符號:半角情況下(一個字節),全角情況下(兩個字節)

三、相關知識擴充

1、通過試驗,三星手機的字體編碼使用的是ISO8859-1。在這種編碼下,中文占二個字節。其他手機(已測試的VIVO,華為,小米)使用的是utf-8編碼,

這種編碼是動態的,1-4個字節不等。中文一般占三個字節。

2、如果需要自定義字體的話,android.graphics.Typeface提供了3個API供應用程序創建特定字體:

a、 Typeface createFromAsset(AssetManager mgr, String path);

b、Typeface createFromFile(File path);

c、Typeface createFromFile(String path);

以及如下3個API來創建系統字體:

a、Typeface create(String familyName, int style);

b、Typeface create(Typeface family, int style);

c、Typeface defaultFromStyle(int style);

3、如何證明android默認包括這三類字體呢?system/ect/fallback_fonts.xml和/system/etc/system_fonts.xml文件是如何被解析的,字體庫又是如何被初始化的?

往framework層去看,在如下路徑下frameworks/base/core/java/com/android/internal/os/ZygoteInit.java。這個ZygoteInit類中的preloadClasses方法是加載字體庫的入口

具體過程如下:

Zygote preloadClasses() -> Class.forName("android.graphics.Typeface")–> 執行Typeface.javastatic塊 -> Typeface.cpp Typeface_create–> SkTypeface.cpp CreateFromName() -> SkFontHost.cpp load_system_fonts()

我們先看android.graphics.Typeface這個類

static {

DEFAULT = create((String)null,0);

DEFAULT_BOLD = create((String)null, Typeface.BOLD);

SANS_SERIF = create("sans-serif", 0);

SERIF =create("serif", 0);

MONOSPACE= create("monospace", 0);//從這裡可以看出JAVA層面默認創建三類字體

sDefaults = newTypeface[] {

DEFAULT,

DEFAULT_BOLD,

create((String)null, Typeface.ITALIC),

create((String)null, Typeface.BOLD_ITALIC),

};

public static Typeface create(String familyName, int style) {

return newTypeface(nativeCreate(familyName, style));

}

nativeCreate()是jni方法,調用C++層的Typeface.cpp方法,在這個方法中,有一種數據結構(如下),它對應著/system/etc/system_fonts.xml文件中的每個family標簽

struct FontFamily {

SkTDArray fNames;//保存標簽對應的名字

SkTDArrayfFileNames;//保存了標簽對應的文件名

int order;//每個字體家族的加載順序

};

還有其他的一些的數據結構,就不在這列舉啦!

........................省略中間的代碼......................................

最終會調用到C++層的SkFontHost.cpp中的load_system_fonts()方法完成字體加載。

4、(注意)字庫大部分都是有版權的,所以你看到Android手機中很少有字體選擇功能,即使有的話,那麼一般都是鏈接到自己定義的字體庫上。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved