Symbian 字体 Panic CTypeFaceStore -14

通过调用 CWsScreenDevice::GetNearestFontToDesignHeightInTwips( CFont*& aFont, const TFontSpec& aFontSpec ) 获取字体之后,应当用 CWsScreenDevice::ReleaseFont( CFont* aFont ) 将此屏幕设备对字体资源所增加的 referent count 还原。(我猜测是如此,因为按照文档中的描述,字体是保留在内存中,由不同的应用程序所共享,除非这个字体为某一个屏幕设备所排他性地独享;另外,内存作 为一种系统资源,也是以共享的方式使用字体的情形居多。)
 
所以,我采用如下方式来使用字体:
class MyUiUtils
    {
    public:
        static TTypeface FindTypeface( const TDesC& aTypefaceName );
        static TInt FontHeightInTwips( const TInt aHeightInPixels );
        static TInt RequestFontFromScreenDevice( CFont*& aFont, const TFontSpec& aFontSpec );
        static void ReturnFontToScreenDevice( CFont* aFont );
    };
 
TTypeface MyUiUtils::FindTypeface( const TDesC& aTypefaceName )
    {
    CWsScreenDevice* scrDev = CCoeEnv::Static()->ScreenDevice();
    TInt tfCnt( scrDev->NumTypefaces() );
    TTypeface tf;
    TTypefaceSupport tfSupport;
    for ( TInt i = 0; i < tfCnt; i++ )
        {
        scrDev->TypefaceSupport( tfSupport, i );
        if ( !aTypefaceName.Compare( tfSupport.iTypeface.iName ) )
            {
            tf = tfSupport.iTypeface;
            break;
            }
        else
            {
            }
        }
    return tf;
    }
 
TInt MyUiUtils::FontHeightInTwips( const TInt aHeightInPixels )
    {
    CWsScreenDevice* scrDev = CCoeEnv::Static()->ScreenDevice();
    TInt heightInTwips( scrDev->VerticalPixelsToTwips( aHeightInPixels ) );
    return heightInTwips;
    }
 
TInt MyUiUtils::RequestFontFromScreenDevice( CFont*& aFont, const TFontSpec& aFontSpec )
    {
    CWsScreenDevice* scrDev = CCoeEnv::Static()->ScreenDevice();
    TInt error ( scrDev->GetNearestFontToDesignHeightInTwips( aFont, aFontSpec ) );
    return error;
    }
 
void MyUiUtils::ReturnFontToScreenDevice( CFont* aFont )
    {
    CWsScreenDevice* scrDev = CCoeEnv::Static()->ScreenDevice();
    scrDev->ReleaseFont( aFont );
    }
 
由此可见,字体的申请和归还应当成对使用。如下,
 
void CMyClass::ConstructL()
    {
    RBuf tfName;
    tfName.CleanupClosePushL();
    tfName.Assign( StringLoader::LoadL( R_MY_TYPEFACE ) );
    TTypeface tf;
    tf = MyUiUtils::FindTypeface( tfName );
    if ( !tf.iName.Length() )
        {
        tf.iName = tfName;
        }
    else
        {
        }
    TInt heightInTwips( MyUiUtils::FontHeightInTwips( KMmMapDefaultFontHeight ) );
    TFontSpec tfs( tf.iName, heightInTwips );
    TInt error( MyUiUtils::RequestFontByFontSpec( iFont, tfs ) );
    CleanupStack::PopAndDestroy( &tfName );    
   }
 
void CMyClass::~CMyClass()
    {
    if ( iFont )
        {
        MyUiUtils::ReturnFontToScreenDevice( iFont );
        }
    else
        {
        }
    }
否则容易出现 CTypefaceStore 14 的 Panic。
 
但是,如果你是使用系统提供的封装全局方法的话,就不用如此小心。例如,在 S60 中,如果使用 AknUtils
 
iFont = const_cast<CFont*>( ApacPlain16() ); 或者
iFont = AknLayoutUtils::FontFromId( EAknLogicalFontPrimaryFont ) );
 
那么 AknUtils 已经帮你完成了字体资源归还的任务,所以你可以粗心一点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值