Fontconfig 2.5.0
Cairo依赖Fontconfig部分,但未见其起初的时候调用fontconfig的初始化函数,诸如FcInit().
Fontconfig代码有WIN32条件编译的宏,且预定义了DllMain()入口,但也未调用FcInit()
Fontconfig要移植到wince,必须处理内部诸多的单字节与宽字符转换问题
Fontconfig将字体文件cached的过程就是将字体文件映射到内存地址空间
FontConfig 设有字体目录(font-dir),缓冲目录(cache-dir),配置目录(font-dir)
Cache-dir目录存放字体缓冲文件 ?????-x86- cache2,缓冲文件被mmap进内存
每个font目录都将创建一个cache文件,存放于cache-dir下
Cache文件内存放一个字体目录下(font-dir)所有字体的pattern信息集合和基本的FcCache对象的控制信息,系统扫描完字体之后的信息存于FcSerialize对象,之后绑定到FcCache对象,之后将FcCache对象及其关联的数据全部写入本地文件cache-file。
之后在加载cache-file时通过FcDirCacheMapHelper()->FcDirCacheMapFd()将cache-file进行mmap映射到虚拟地址空间,采用mmap方式可以允许多个进程同时访问这些字体信息。
系统初始化时FcInit()检测cache文件是否存在(文件锁控制),不存在则扫描字体目录创建缓冲文件(一个字体目录对应一个缓冲文件);否则打开缓冲文件并映射进入本地进程的地址空间(mmap),其起始地址被转换为FcCache*对象返回
如果字体目录下存在子目录,在生成的信息存放在FcCache::dirs处
FcSerialize过程
将不同类型的Fcxxxx对象序列化转储时,先将对象结构信息专储,对象内的指针指向的对象也进行转储到对象头信息之后,其位置由对象头结构内的intptr_t变量指定。
例如:
struct _FcCache {
int magic; /* FC_CACHE_MAGIC_MMAP or FC_CACHE_ALLOC */
int version; /* FC_CACHE_CONTENT_VERSION */
intptr_t size; /* size of file */
intptr_t dir; /* offset to dir name */
intptr_t dirs; /* offset to subdirs */
int dirs_count; /* number of subdir strings */
intptr_t set; /* offset to font set */
int mtime; /* low bits of directory mtime */
};
FcCache对象结构信息先被serialize, intptr_t变量指向的附属数据所在位置(本对象的当前偏移量)
struct _FcPattern {
int num;
int size;
intptr_t elts_offset;
int ref;
};
typedef struct _FcPatternElt {
FcObject object;
FcValueList *values;
} FcPatternElt;
每个FcPattern由若干个FcPatternElt组成FcPatternElt的数组的首地址与FcPattern对象地址的差值作为偏移量存储在FcPattern::elts_offset中
Fonts.conf
可以禁用部分字体或者启用字体(字体目录)
{ "acceptfont", FcElementAcceptfont },
{ "rejectfont", FcElementRejectfont },
如果没有定义acceptfont和rejectfont,则默认都是acceptfont的,所以<dir>font-dir</dir>默认是允许的
每个字体文件通过freetype进行访问,当在font目录下扫描字体文件是,将读取若干个patterns
FcSerialize 的FcSerializeBucket存储
SystemFont or ApplicationFont
不同字体被登记在不同类别的字体集合中管理
FcSerializebucket不能超过 8k个,字体文件也不能过8k个,每个字体文件名置入bucket
/**
* container_of - cast a member of a structure out to the containing structure
*
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
Example:
struct user_struct *user;
user = list_entry(up, struct user_struct, uidhash_list);
取成员变量偏移量:
struct testcls{
int a;
int b;
};
testcls *cls= new testcls;
UINT offset = (UINT)&((testcls*)0)->b;
编译
Fontconfig部分头文件需要在makefile时产生,比如fc-lang.h,fc-case.h,将其在linux下编译fontconfig.tgz,产生这几个头文件再拷贝出来
FONTCONFIG 的WINCE/WIN32移植
WinX版本去除了以下内容:
FcCache
FcSerialize 不支持对象的序列化存储
不支持多字体目录
不支持多cache目录
所以不支持多进程共用fontconfig 的cache内容,也就是不能用mmap进行map到自己的空间。这样每个进程必须消耗一系列的Pattern及其相关对象所占据的内存空间。
因为在嵌入式环境配置的字体可能只有1,2种,这种内存的消耗应该不会是很大
WINCE:
字体存储和配置信息储存在wince.h文件
#define FONTS_DIR "/nandflashpartition/fonts"
#define FONTS_CACHE_DIR "/nandflashpartition/fonts-cache"
#define FONTCONFIG_FILE FONTS_DIR##"/fonts.conf"
Fonts.conf
<fontconfig>
<dir>/nandflashpartition/fonts</dir>
<cachedir>/nandflashpartition</cachedir>
<font-file>simhei.ttf</font-file>
</fontconfig>
CMakefile的配置
#去除_WIN32 _WINDOWS定义
ADD_DEFINITIONS(-D_WINCE -D_WIN32_WCE=0x500 -DUNDER_CE -DWINCE -DARM -D_ARM_ -D_UNICODE -DUNICODE)
INCLUDE_DIRECTORIES("../" "C:/temp9/papyrus_dependencies/include" )
add_library (fontconfig
# fcatomic.c
fcblanks.c
# fccache.c
fccfg.c
fccharset.c
fcdbg.c
fcdefault.c
fcdir.c
fcfreetype.c
fcfs.c
fcinit.c
fclang.c
fclist.c
fcmatch.c
fcmatrix.c
fcname.c
fcpat.c
# fcserialize.c
fcstr.c
fcxml.c
ftglue.h
ftglue.c
wince.h
wince_imp.c
)
Fontconfig目前作为静态库生成并被使用,因为dll生成必须定义fontconfig.def(此操作费时)