Symbian程序动态加载TTF字体使用小结Word格式文档下载.docx
- 文档编号:22823589
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:14
- 大小:187.38KB
Symbian程序动态加载TTF字体使用小结Word格式文档下载.docx
《Symbian程序动态加载TTF字体使用小结Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《Symbian程序动态加载TTF字体使用小结Word格式文档下载.docx(14页珍藏版)》请在冰豆网上搜索。
在Draw()函数中加载并使用这个字体文件
具体代码如下:
CFont*myNewFont=NULL;
TFileNameiFileName;
iFileName.Copy(_L("
e:
\\Data\\Fonts\\abc.ttf"
));
TIntstaticfontID=0;
iCoeEnv->
ScreenDevice()->
AddFile(iFontFile,fontID);
TBuf<
KMaxTypefaceNameLength>
aTypefaceName;
TTypefaceSupportmyTypefaceSupport;
TypefaceSupport(myTypefaceSupport,0);
//通常是新增加的在序列里面是第一个
aTypefaceName.Copy(myTypefaceSupport.iTypeface.iName.Des());
TFontSpecmyFontSpec;
myFontSpec.iTypeface.iName=aTypefaceName;
TPointpixelPoint(16,16);
//字体大小模式
myFontSpec.iHeight=iCoeEnv->
PixelsToTwips(pixelPoint).iY;
GetNearestFontToDesignHeightInTwips(myNewFont,myFontSpec);
gc.UseFont(myNewFont);
gc.SetPenColor(KRgbBlack);
gc.DrawText(_L("
hello"
),TPoint(5,20));
步骤4:
卸载这个字体
卸载代码如下:
ReleaseFont(myFont);
RemoveFile(aid);
字体动态加载的问题讨论
虽然整个操作步骤如上述简单流程,但是实际实现时你会发现很多意想不到的问题,我在具体操作时曾一度不相信通过上述方法真能实现所谓的动态加载,下面就对实际使用中遇到的几个问题进行阐释。
如何正确获得要用的字体
通常情况下,通过AddFile或者InstallFile加载的字体,位于字体表的首项,所以可以通过以下代码获取新加载的字体
但是有时候也并非都是在首项(存在偶然因素),特别是当选中的这个ttf字体已经有加载的情况下,想继续加载另一个非同文件名的ttf字体时,系统会报错(-11,KErrAlreadyExists),这个就使得需要使用的字体不位于字体表的首项成为必然了,这个时候用户选择的仅仅是ttf字体文件,而ttf字体文件的文件名是可以任意修改的,所以程序无法靠字体文件名来识别,那该如何正确获得要用的字体呢?
庆幸ttf字体文件有一个唯一识别的字体名(fontname),通过这个特性就可以通过字体名来选择需要使用的字体。
至于如何去获取这个唯一识别的字体名,就要去了解下ttf字体文件的结构信息,庆幸网络上有Windows平台上的实现代码,具体详见
#defineMAKEWORD(a,b)((TText16)(((TText8)(a))|((TText16)((TText8)(b)))<
<
8))
#defineMAKELONG(a,b)((TInt32)(((TText16)(a))|((TUint32)((TText16)(b)))<
16))
#defineLOBYTE(w)((TText8)(w))
#defineHIBYTE(w)((TText8)(((TText16)(w)>
>
8)&
0xFF))
#defineLOWORD(l)((TText16)(l))
#defineHIWORD(l)((TText16)(((TUint32)(l)>
16)&
0xFFFF))
#defineSWAPWORD(x)MAKEWORD(HIBYTE(x),LOBYTE(x))
#defineSWAPLONG(x)MAKELONG(SWAPWORD(HIWORD(x)),SWAPWORD(LOWORD(x)))
typedefstruct_tagTT_OFFSET_TABLE
{
TText16uMajorVersion;
TText16uMinorVersion;
TText16uNumOfTables;
TText16uSearchRange;
TText16uEntrySelector;
TText16uRangeShift;
}TT_OFFSET_TABLE;
typedefstruct_tagTT_TABLE_DIRECTORY
charszTag[4];
//tablename
TUint32uCheckSum;
//Checksum
TUint32uOffset;
//Offsetfrombeginningoffile
TUint32uLength;
//lengthofthetableinbytes
}TT_TABLE_DIRECTORY;
typedefstruct_tagTT_NAME_TABLE_HEADER
TText16uFSelector;
//formatselector.Always0
TText16uNRCount;
//NameRecordscount
TText16uStorageOffset;
//Offsetforstringsstorage,fromstartofthetable
}TT_NAME_TABLE_HEADER;
typedefstruct_tagTT_NAME_RECORD
TText16uPlatformID;
TText16uEncodingID;
TText16uLanguageID;
TText16uNameID;
TText16uStringLength;
TText16uStringOffset;
//fromstartofstoragearea
}TT_NAME_RECORD;
TIntGetFontNameFromFile(constTDesC16&
aFontFile,TDes16&
aFontName)
RFsvFs;
RFilevFile;
TFileNamevFileTemp;
TBuf8<
56>
vBufTemp;
TIntvErr=vFs.Connect();
if(KErrNone!
=vErr)
{
return-1;
}
vErr=vFile.Open(vFs,aFontFile,EFileRead|EFileShareAny);
vFs.Close();
}
else
TT_OFFSET_TABLEttOffsetTable;
TPtr8vPtrttOffsetTable((TUint8*)&
ttOffsetTable,sizeof(TT_OFFSET_TABLE));
vErr=vFile.Read(vPtrttOffsetTable,sizeof(TT_OFFSET_TABLE));
vFile.Close();
ttOffsetTable.uNumOfTables=SWAPWORD(ttOffsetTable.uNumOfTables);
ttOffsetTable.uMajorVersion=SWAPWORD(ttOffsetTable.uMajorVersion);
ttOffsetTable.uMinorVersion=SWAPWORD(ttOffsetTable.uMinorVersion);
//checkisthisisatruetypefontandtheversionis1.0
if(ttOffsetTable.uMajorVersion!
=1||ttOffsetTable.uMinorVersion!
=0)
TT_TABLE_DIRECTORYtblDir;
TPtr8vPtr8tblDir((TUint8*)&
tblDir,sizeof(TT_TABLE_DIRECTORY));
TBoolbFound=EFalse;
for(TInti=0;
i<
ttOffsetTable.uNumOfTables;
i++)
vErr=vFile.Read(vPtr8tblDir,sizeof(TT_TABLE_DIRECTORY));
vBufTemp.Copy((TUint8*)tblDir.szTag,4);
if(vBufTemp.Compare(_L8("
name"
))==0)
bFound=ETrue;
tblDir.uLength=SWAPLONG(tblDir.uLength);
tblDir.uOffset=SWAPLONG(tblDir.uOffset);
break;
if(bFound)
TIntvDataTemp=tblDir.uOffset;
vErr=vFile.Seek(ESeekStart,vDataTemp);
TT_NAME_TABLE_HEADERttNTHeader;
TPtr8vPtr8ttNTHeader((TUint8*)&
ttNTHeader,sizeof(TT_NAME_TABLE_HEADER));
vErr=vFile.Read(vPtr8ttNTHeader,sizeof(TT_NAME_TABLE_HEADER));
ttNTHeader.uNRCount=SWAPWORD(ttNTHeader.uNRCount);
ttNTHeader.uStorageOffset=SWAPWORD(ttNTHeader.uStorageOffset);
TT_NAME_RECORDttRecord;
TPtr8vPtr8ttRecord((TUint8*)&
ttRecord,sizeof(TT_NAME_RECORD));
bFound=EFalse;
for(TIntj=0;
j<
ttNTHeader.uNRCount;
j++)
vErr=vFile.Read(vPtr8ttRecord,sizeof(TT_NAME_RECORD));
ttRecord.uNameID=SWAPWORD(ttRecord.uNameID);
if(ttRecord.uNameID==1)
ttRecord.uStringLength=SWAPWORD(ttRecord.uStringLength);
ttRecord.uStringOffset=SWAPWORD(ttRecord.uStringOffset);
TIntnPos=0;
vErr=vFile.Seek(ESeekCurrent,nPos);
vDataTemp=tblDir.uOffset+ttRecord.uStringOffset+ttNTHeader.uStorageOffset;
//bugfix:
seethepostbySimonSaystoreadmoreaboutit
HBufC8*vNameTemp=HBufC8:
:
New(ttRecord.uStringLength+1);
TPtr8vPtrFontName(vNameTemp->
Des());
vErr=vFile.Read(vPtrFontName,ttRecord.uStringLength);
deletevNameTemp;
vNameTemp=NULL;
if(vPtrFontName.Length()>
0)
aFontName.Copy(vPtrFontName);
vErr=vFile.Seek(ESeekStart,nPos);
return0;
}
通过上述实现,获取了字体文件的字体名之后,我们就可以不用TypefaceSupport这种枚举的方法了,直接设定TFontSpec的属性然后通过调用GetNearestFont…相关函数来获取需要的字体。
目前发现的还有一个问题,就是存在一种很特殊的情况,有时候调用了RemoveFile卸载了字体文件,但是字体文件却还是处于打开或者在用的状态,这个时候,通过上述的GetFontNameFromFile是无法取到字体名的,这种情况下,有时候就只能通过重启手机,来将字体文件从内存中解绑。
正确加载并使用了字体却显示不出来
字体正确的加载并选择使用了,但是通过这个选择的字体,在UI上DrawText的时候居然没有绘制出来,不得不让人怀疑这种方法是否可行。
最后经过试验发现,假如在一个局部函数内对同一字体分别调用AddFile或者InstallFile方法,然后绘制结束后调用RemoveFile方法,那么就是显示不出绘制的东西。
所以在A函数内加载字体(AddFile或者InstallFile),甚至在A函数内使用字体,但是就是不能在A函数内卸载刚刚添加的字体。
那既然加载的字体卸载起来这么麻烦,我干脆就不卸载了可以吗,就好比程序在堆栈上申请的内容在程序退出的时候,系统会将程序所拥有的堆栈上申请的内容释放掉,但是字体文件就是个特例,因为SymbianOS是通过C/S架构来实现的,程序加载只是通知OS内核中的CFbsServer去加载字体,假如不人为卸载,那么CFbsServer不会自己去卸载字体,而且程序一旦退出,就只有通过手机重启的方法来卸载字体了。
所以起初设计Demo代码采用了加载一个字体,将对应的fontID放到一个CArray队列里,最后程序退出的时候,在类的析构函数中再一一卸载已经加载的字体。
这种方法适合在一个程序中同时加载多个ttf字体。
假如用户的程序中始终只需要加载一个ttf字体,那么就可以通过在A函数中,进行加载新字体之前,先把已加载的字体卸载掉,然后再加载新的字体并使用。
这样的情况下,就不会造成用加载的字体绘制文本内容时显示空白的问题。
其它还有一些问题,目前就不做整理了。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Symbian 程序 动态 加载 TTF 字体 使用 小结