diff -uNrp OOB680_m5.orig/vcl/inc/outdev.h OOB680_m5/vcl/inc/outdev.h --- OOB680_m5.orig/vcl/inc/outdev.h 2005-09-09 19:12:26.000000000 +0800 +++ OOB680_m5/vcl/inc/outdev.h 2006-02-28 16:16:23.000000000 +0800 @@ -96,6 +96,10 @@ public: void UpdateDevFontList( ImplGetDevFontList& ) const; void UpdateCloneFontList( ImplDevFontList&, bool bScalable, bool bEmbeddable ) const; + // Add by Firefly(firefly@ossii.com.tw) + // 所屬的字體群組(參考 ImplDevFontList::maGroupFontList) + void SetGroupID(const int nID) { mnGroupID=nID; } + int GetGroupID() const { return mnGroupID; }; private: friend class ImplDevFontList; // TODO: remove soon @@ -111,6 +115,10 @@ friend class ImplDevFontList; // TODO: r FontFamily meFamily; FontPitch mePitch; int mnMinQuality; // quality of the worst font face + // Add by Firefly(firefly@ossii.com.tw) + // 所屬的字體群組(參考 ImplDevFontList::maGroupFontList) + // -1 表示沒有所屬群組 + int mnGroupID; }; diff -uNrp OOB680_m5.orig/vcl/inc/outfont.hxx OOB680_m5/vcl/inc/outfont.hxx --- OOB680_m5.orig/vcl/inc/outfont.hxx 2005-10-17 22:49:15.000000000 +0800 +++ OOB680_m5/vcl/inc/outfont.hxx 2006-02-28 16:16:23.000000000 +0800 @@ -230,6 +230,11 @@ public: bool HasFallbacks() const; void SetFallbacks( ImplDevFontListData**, int nCount ); ImplDevFontListData* GetFallback( int nIndex ) const; + // Add by Firefly(firefly@ossii.com.tw) + int GetFallbackCount() const {return mnFallbackCount;} + int ImplCheckGroupID( const String&, const String& ) const; + bool SetFallbackByGroupID( const int nGroupID ); + //---------------------------------------------------------------- ImplDevFontList* Clone( bool bScalable, bool bEmbeddable ) const; ImplGetDevFontList* GetDevFontList() const; @@ -245,10 +250,19 @@ protected: ImplDevFontListData* ImplFindByAttributes( ULONG nSearchType, FontWeight, FontWidth, FontFamily, FontItalic, const String& rSearchFamily ) const; ImplDevFontListData* FindDefaultFont() const; + // Add by Firefly(firefly@ossii.com.tw) + void AddFontGroup(const String); + ImplDevFontListData* ImplFindByGroupName( const String& ) const; + //---------------------------------------------------------------- private: ImplDevFontListData** mpFallbackList; int mnFallbackCount; + // Add by Firefly(firefly@ossii.com.tw) + typedef std::vector GroupFontList; + GroupFontList maGroupFontList; + int mnLastSortID; + //---------------------------------------- }; diff -uNrp OOB680_m5.orig/vcl/inc/sallayout.hxx OOB680_m5/vcl/inc/sallayout.hxx --- OOB680_m5.orig/vcl/inc/sallayout.hxx 2005-11-02 21:28:34.000000000 +0800 +++ OOB680_m5/vcl/inc/sallayout.hxx 2006-03-02 10:45:01.000000000 +0800 @@ -269,6 +269,10 @@ public: virtual bool GetBoundRect( SalGraphics&, Rectangle& ) const; // used only by OutputDevice::ImplLayout, TODO: make friend + // Add by Firefly(firefly@ossii.com.tw) + // OK. I have been defined. + friend class OutputDevice; + //-------------------------------------------- MultiSalLayout( SalLayout& rBaseLayout ); // transfer ownership virtual bool AddFallback( SalLayout& rFallback, // transfer ownership ImplLayoutRuns& rRuns, ImplFontData* pFallbackFont ); --- OOB680_m5.orig/vcl/source/gdi/outdev3.cxx 2006-01-27 02:08:42.000000000 +0800 +++ OOB680_m5/vcl/source/gdi/outdev3.cxx 2006-03-17 14:46:08.000000000 +0800 @@ -376,6 +376,33 @@ void OutputDevice::ImplUpdateAllFontData // ======================================================================= +// Add by Firefly(firefly@ossii.com.tw) +static char *aDefaultGroup = \ +"仿|" \ +"明;宋;Ming;Sung;Song|" \ +"楷;Kai|" \ +"隸;隶|" \ +"黑;Hei|" \ +"圓;圆|" \ +"行書;行书|勘亭流|古印|魏碑|" \ +"鋼筆;钢笔|" \ +"新藝;新艺|綜藝;综艺|海報;海报|空疊;空叠|疊圓;叠圆|廣告;广告|POP|" \ +"手寫;手写|注音|" \ +"symbol;Symbol;Webdings;Dingbats"; +/* +"超明|特明|粗明;粗宋|中明;中宋|粗仿|中仿|仿宋|明;宋;Ming;Sung;Song|" \ +"粗隸;粗隶|中隸;中隶|隸;隶|" \ +"超黑|特黑|粗黑|中黑|黑;Hei|" \ +"超圓;超圆|特圓;特圆|粗圓;粗圆|中圓;中圆|圓;圆|" \ +"行書;行书|勘亭流|古印|魏碑|顏楷;颜楷|毛楷|行楷|粗楷|中楷|楷;Kai|" \ +"粗鋼筆;粗钢笔|中鋼筆;中钢笔|鋼筆;钢笔|" \ +"新藝;新艺|綜藝;综艺|海報;海报|空疊;空叠|疊圓;叠圆|廣告;广告|POP|" \ +"手寫;手写|注音|" \ +"Symbol;Webdings;Dingbats"; +*/ +// Disable by Firefly(firefly@ossii.com.tw) +// 我看不出來有何理由要轉換 localized name. +#if 0 struct ImplLocalizedFontName { const char* mpEnglishName; @@ -647,6 +674,7 @@ static ImplLocalizedFontName aImplLocali { "hgmarugothicmpro", aHGMaruGothicMPRO }, { NULL, NULL }, }; +#endif // ----------------------------------------------------------------------- @@ -736,6 +764,9 @@ void ImplGetEnglishSearchFontName( Strin i++; } +// Disable by Firefly(firefly@ossii.com.tw) +// 我看不出來有何理由要轉換 localized name. +#if 0 // translate normalized localized name to its normalized English ASCII name if( bNeedTranslation ) { @@ -754,6 +785,7 @@ void ImplGetEnglishSearchFontName( Strin if( it != aDictionary.end() ) rName.AssignAscii( it->second ); } +#endif } // ----------------------------------------------------------------------- @@ -1567,6 +1599,9 @@ ImplDevFontListData::ImplDevFontListData meMatchWidth( WIDTH_DONTKNOW ), mnTypeFaces( 0 ), mnMatchType( 0 ), + // Add by Firefly(firefly@ossii.com.tw) + // 預設沒有所屬群組 + mnGroupID( -1 ), mnMinQuality( -1 ) {} @@ -1614,9 +1649,24 @@ bool ImplDevFontListData::AddFontFace( I mnTypeFaces |= IMPL_DEVFONT_SCALABLE; if( pNewData->IsSymbolFont() ) + { mnTypeFaces |= IMPL_DEVFONT_SYMBOL; + } else + { mnTypeFaces |= IMPL_DEVFONT_NONESYMBOL; + // Add by Firefly(firefly@ossii.com.tw) + // 中日韓字體優先 + // Check is CJK font? + String aCheckName = pNewData->maName; + if (pNewData->maMapNames.Len()) + aCheckName.Append(pNewData->maMapNames); + + const unsigned nIsCJK = ImplIsCJKFont(aCheckName); + if (nIsCJK & IMPL_FONT_ATTR_CJK) + mnMinQuality += 100000000; + //------------------------------------------------- + } if( pNewData->meWeight != WEIGHT_DONTKNOW ) { @@ -1780,6 +1830,18 @@ ImplDevFontList::ImplDevFontList() mbMapNames = false; mpFallbackList = NULL; mnFallbackCount = -1; + // Add by Firefly(firefly@ossii.com.tw) + mnLastSortID = -99; + const char *pEnv = getenv("OOO_FONT_GROUP_LIST"); + // 使用者定義優先處理 + if (pEnv) + { + String aGroupName(pEnv, RTL_TEXTENCODING_UTF8); + AddFontGroup(aGroupName); + } + String aDefault(aDefaultGroup, RTL_TEXTENCODING_UTF8); + AddFontGroup(aDefault); + //----------------------------------------------------- } // ----------------------------------------------------------------------- @@ -1808,6 +1870,10 @@ void ImplDevFontList::Clear() maDevFontList.clear(); + // Add by Firefly(firefly@ossii.com.tw) + maGroupFontList.clear(); + mnLastSortID = -99; + // match data must be recalculated too mbMatchData = false; } @@ -1866,7 +1932,12 @@ void ImplDevFontList::Add( ImplFontData* { int nAliasQuality = pNewData->mnQuality - 100; String aMapNames = pNewData->maMapNames; - pNewData->maMapNames = String(); + // Modify by Firefly(firefly@firefly.idv.tw) + // Don't clean maMapNames. + // Because some Asian Document have use alias font name. + //pNewData->maMapNames = String(); + if (pNewData->maMapNames.Len()) + mbMapNames = true; bool bKeepNewData = false; for( xub_StrLen nMapNameIndex = 0; nMapNameIndex != STRING_NOTFOUND; ) @@ -1883,6 +1954,10 @@ void ImplDevFontList::Add( ImplFontData* { pFoundData = new ImplDevFontListData( aSearchName ); maDevFontList[ aSearchName ] = pFoundData; + // Add by Firefly(firefly@ossii.com.tw) + // Check and set the font group ID. + // If not match any group, the return ID is -1. + pFoundData->SetGroupID(ImplCheckGroupID(aSearchName, pNewData->maMapNames)); } bKeepNewData = pFoundData->AddFontFace( pNewData ); @@ -1903,6 +1978,196 @@ void ImplDevFontList::Add( ImplFontData* } // ----------------------------------------------------------------------- +// Add by Firefly(firefly@ossii.com.tw) +// 切割字體屬性群組字串 +void ImplDevFontList::AddFontGroup(const String rGroupName) +{ + if (rGroupName.Len()) + { + xub_StrLen nTokens = rGroupName.GetTokenCount('|'); + for (xub_StrLen nIndex = 0; nIndex < nTokens; nIndex++) + { + String aGroup = rGroupName.GetToken(nIndex, '|'); + if (aGroup.Len()) + { + ImplGetEnglishSearchFontName(aGroup); + maGroupFontList.push_back(aGroup); + } + } + } +} + +// Add by Firefly(firefly@ossii.com.tw) +// 檢查並傳回字型名稱所屬 ID +int ImplDevFontList::ImplCheckGroupID(const String& rName, const String& rAliasName) const +{ + String aFullNames = rName; + if (rAliasName.Len()) + { + aFullNames.Append(';'); + aFullNames.Append(rAliasName); + } + ImplGetEnglishSearchFontName(aFullNames); + + // 依序取出各個群組做比對 + for (int i = 0 ; i < maGroupFontList.size(); i++) + { + String aGroupNames = maGroupFontList.at(i); + // 再分解群組成員與字型名稱做比對 + String aTempName; + xub_StrLen nIndex = 0; + do + { + aTempName = GetNextFontToken(aGroupNames, nIndex); // 群組成員名稱 + if (aTempName.Len() && + aFullNames.Search(aTempName) != STRING_NOTFOUND) + { +#if defined(HDU_DEBUG) + ByteString aName(aFullNames, RTL_TEXTENCODING_UTF8); + ByteString aGname(aTempName, RTL_TEXTENCODING_UTF8); + printf("ID=%2d, Check Name=%s, Match Group=%s\n", i, aName.GetBuffer(), aGname.GetBuffer()); +#endif + return i; + } + } + while (nIndex != STRING_NOTFOUND); + } + return -1; +} + +bool ImplDevFontList::SetFallbackByGroupID(int nGroupID) +{ + // 字型列表是空的!?不做任何事 + if (maDevFontList.empty()) + return false; + + // 跟上次一樣的排序? 就不必再做一次 + if (nGroupID == mnLastSortID) + return true; + + if (mpFallbackList) + delete[] mpFallbackList; + + // 事先取得系統自訂字型 + ImplDevFontListData* pDefaultFont = FindDefaultFont(); + + // 如果沒有字體群組或是預設字型就是指定的字體群組 + // 就把預設字型放在第一位 + bool bDefaultFontFirst = (nGroupID < 0 || ImplCheckGroupID(pDefaultFont->maName, pDefaultFont->maMapNames) == nGroupID); + int nSortStart = 0; + + mpFallbackList = new ImplDevFontListData*[maDevFontList.size()]; + mnFallbackCount = 0; + + DevFontList::iterator it = maDevFontList.begin(); + for(; it != maDevFontList.end(); ++it ) + { + mpFallbackList[mnFallbackCount++] = (*it).second; + if (bDefaultFontFirst && (*it).second == pDefaultFont) + { + ImplDevFontListData* pTmpData = mpFallbackList[0]; + mpFallbackList[mnFallbackCount - 1] = pTmpData; + mpFallbackList[0] = (*it).second; + nSortStart = 1; + } + } + + bool bHaveGroupID = false; + for(int i = nSortStart, j; i < mnFallbackCount ; ++i) + { + ImplDevFontListData* pTestFont = mpFallbackList[i]; + int nTestID = pTestFont->GetGroupID(); + int nTestQuality = pTestFont->GetMinQuality(); + if (nTestID == nGroupID) + bHaveGroupID = true; + + for(j = i ; --j >= nSortStart ;) + { + if(nTestQuality > mpFallbackList[j]->GetMinQuality()) + mpFallbackList[j+1] = mpFallbackList[j]; + else + break; + } + mpFallbackList[j+1] = pTestFont; + } + + // 需要依照字體性質排列嗎? + if (bHaveGroupID && nGroupID >= 0) + { + int nFontGroupID; + for(int i = nSortStart ; i < mnFallbackCount ; ++i) + { + if ((nFontGroupID = mpFallbackList[i]->GetGroupID()) == nGroupID) + continue; + for (int j = i+1 ; j < mnFallbackCount ; j++) + { + if (mpFallbackList[j]->GetGroupID() == nGroupID) + { + ImplDevFontListData* pTestFont = mpFallbackList[i]; + mpFallbackList[i] = mpFallbackList[j]; + mpFallbackList[j] = pTestFont; + } + } + } + } + +#if defined(HDU_DEBUG) + if (nGroupID >= 0) + { + ByteString aGroupName(maGroupFontList.at(nGroupID), RTL_TEXTENCODING_UTF8); + printf("SetFallbackByGroupID(%d) %s\n", nGroupID, aGroupName.GetBuffer()); + } + else + { + printf("nGroupID = %d. Use Orig lists sort by Quality.\n", nGroupID); + } + for (int i=0 ; i < mnFallbackCount ; ++i) + { + ByteString aName(mpFallbackList[i]->GetFamilyName(), RTL_TEXTENCODING_UTF8); + printf("#%02d - %s(%02d)\n", i, aName.GetBuffer(), mpFallbackList[i]->GetGroupID()); + } +#endif + + mnLastSortID = nGroupID; + return true; +} + +ImplDevFontListData* ImplDevFontList::ImplFindByGroupName(const String& rName) const +{ + ImplDevFontListData* pFoundData = NULL; + int nGroupID = ImplCheckGroupID(rName, String()); + // 取得系統字型的群組 ID + ImplDevFontListData* pDefaultData = FindDefaultFont(); + int nDefaultGroupID = ImplCheckGroupID(pDefaultData->maName, pDefaultData->maMapNames); + + // 如果系統字型有群組,而且也跟要求的字型群組一樣的話,就傳回系統字型 + if (nDefaultGroupID >= 0 && nDefaultGroupID == nGroupID) + return pDefaultData; + + // 有找到字體群組的話, 取出該字體群組中 Quality 最大的那個 + int nQuality = 0; + if (nGroupID >= 0) + { + DevFontList::const_iterator it = maDevFontList.begin(); + for(; it != maDevFontList.end(); ++it) + { + ImplDevFontListData* pData = (*it).second; + // 忽略不是該群組的字體 + if (pData->GetGroupID() != nGroupID) + continue; + // 取得群組中最佳字體 + if (pData->GetMinQuality() > nQuality) + { + pFoundData = pData; + nQuality = pData->GetMinQuality(); + } + } + } + + return pFoundData; +} + +// ----------------------------------------------------------------------- // find the font from the normalized font family name ImplDevFontListData* ImplDevFontList::ImplFindBySearchName( const String& rSearchName ) const @@ -1914,10 +2179,13 @@ ImplDevFontListData* ImplDevFontList::Im #endif DevFontList::const_iterator it = maDevFontList.find( rSearchName ); - if( it == maDevFontList.end() ) - return NULL; - - ImplDevFontListData* pFoundData = (*it).second; + // Modify By Firefly(firefly@ossii.com.tw) + ImplDevFontListData* pFoundData = NULL; + if( it != maDevFontList.end() ) + pFoundData = (*it).second; + // because CJK fonts maybe have alias name + if (mbMapNames && !pFoundData) + pFoundData = ImplFindByAliasName(rSearchName, String()); return pFoundData; } @@ -1936,18 +2204,22 @@ ImplDevFontListData* ImplDevFontList::Im // use the font's alias names to find the font // TODO: get rid of linear search DevFontList::const_iterator it = maDevFontList.begin(); - while( it != maDevFontList.end() ) + // Modify by Firefly(firefly@firefly.idv.tw) + // BUG! endless loop. + for( ; it != maDevFontList.end() ; ++it) { ImplDevFontListData* pData = (*it).second; if( !pData->maMapNames.Len() ) continue; // if one alias name matches we found a matching font + String aMapNames = pData->maMapNames; String aTempName; xub_StrLen nIndex = 0; do { - aTempName = GetNextFontToken( pData->maMapNames, nIndex ); + ImplGetEnglishSearchFontName(aMapNames); + aTempName = GetNextFontToken(aMapNames, nIndex); // Test, if the Font name match with one of the mapping names if ( (aTempName == rSearchName) || (aTempName == rShortName) ) return pData; @@ -2035,6 +2307,9 @@ void ImplDevFontList::InitMatchData() co // ----------------------------------------------------------------------- +// Disable by Firefly(firefly@ossii.com.tw) +// 已經不需要了 +#if 1 ImplDevFontListData* ImplDevFontList::ImplFindByAttributes( ULONG nSearchType, FontWeight eSearchWeight, FontWidth eSearchWidth, FontFamily eSearchFamily, FontItalic eSearchItalic, const String& rSearchFamilyName ) const @@ -2393,6 +2668,7 @@ ImplDevFontListData* ImplDevFontList::Im return pFoundData; } +#endif // ----------------------------------------------------------------------- @@ -2401,6 +2677,41 @@ ImplDevFontListData* ImplDevFontList::Fi // try to find one of the default fonts of the // UNICODE, SANSSERIF, SERIF or FIXED default font lists const DefaultFontConfigItem& rDefaults = *DefaultFontConfigItem::get(); +// Add by Firefly(firefly@ossii.com.tw) +// 依據國家地區別,取出預設字型才對,否則都以英文為主,取出的字型就不對 +#if 1 + com::sun::star::lang::Locale aLocale = Application::GetSettings().GetLocale(); + OUString aLanguage = aLocale.Language.toAsciiLowerCase(); + OUString aCountry = aLocale.Country.toAsciiLowerCase(); + USHORT nType[4]; + if (aLanguage.equalsAscii("zh") || + aLanguage.equalsAscii("ja") || + aLanguage.equalsAscii("ko")) + { + nType[0] = DEFAULTFONT_CJK_TEXT; + nType[1] = DEFAULTFONT_CJK_DISPLAY; + nType[2] = DEFAULTFONT_UI_SANS; + nType[3] = DEFAULTFONT_UI_FIXED; + } + else + { + nType[0] = DEFAULTFONT_SANS_UNICODE; + nType[1] = DEFAULTFONT_SANS; + nType[2] = DEFAULTFONT_SERIF; + nType[3] = DEFAULTFONT_FIXED; + } + + String aFontname; + ImplDevFontListData* pFoundData = NULL; + + for (int i = 0 ; i < sizeof(nType) ; i++) + { + aFontname = rDefaults.getDefaultFont(aLocale, nType[i]); + pFoundData = ImplFindByTokenNames(aFontname); + if (pFoundData) + return pFoundData; + } +#else com::sun::star::lang::Locale aLocale( OUString( RTL_CONSTASCII_USTRINGPARAM("en") ), OUString(), OUString() ); String aFontname = rDefaults.getDefaultFont( aLocale, DEFAULTFONT_SANS_UNICODE ); ImplDevFontListData* pFoundData = ImplFindByTokenNames( aFontname ); @@ -2421,6 +2732,7 @@ ImplDevFontListData* ImplDevFontList::Fi pFoundData = ImplFindByTokenNames( aFontname ); if( pFoundData ) return pFoundData; +#endif // now try to find a reasonable non-symbol font @@ -2767,6 +3079,8 @@ ImplDevFontListData* ImplDevFontList::Im aSearchName = rFSD.maTargetName; ImplGetEnglishSearchFontName( aSearchName ); ImplFontSubstitute( aSearchName, nSubstFlags, pDevSpecific ); +// Disable by Firefly(firefly@ossii.com.tw) +#if 0 // #114999# special emboldening for Ricoh fonts // workaround until all platforms support artificial styles // TODO: smarter check for special cases @@ -2790,6 +3104,7 @@ ImplDevFontListData* ImplDevFontList::Im else // restore font weight rFSD.meWeight = eWeight; } +#endif ImplDevFontListData* pFoundData = ImplFindBySearchName( aSearchName ); if( pFoundData ) return pFoundData; @@ -2847,6 +3162,8 @@ ImplDevFontListData* ImplDevFontList::Im ImplDevFontListData* pFoundData = ImplFindBySearchName( aSearchShortName ); if( pFoundData ) { +// Disable by Firefly(firefly@ossii.com.tw) +#if 0 #ifdef UNX /* #96738# don't use mincho as an replacement for "MS Mincho" on X11: Mincho is a korean bitmap font that is not suitable here. Use the font replacement table, @@ -2857,6 +3174,7 @@ ImplDevFontListData* ImplDevFontList::Im if ((aSearchName != aMS_Mincho) && (aSearchName != aMS_Gothic)) // TODO: add heuristic to only throw out the fake ms* fonts #endif +#endif { return pFoundData; } @@ -2895,6 +3213,8 @@ ImplDevFontListData* ImplDevFontList::Im return pFoundData; } +// Disable by Firefly(firefly@ossii.com.tw) +#if 0 // now try the other font name tokens while( nTokenPos != STRING_NOTFOUND ) { @@ -2950,7 +3270,19 @@ ImplDevFontListData* ImplDevFontList::Im if( pFoundData ) return pFoundData; } +#endif + // Add by Firefly(firefly@ossii.com.tw) + // 看看有無同性質的字體 + if (maGroupFontList.size()) + { + ImplDevFontListData* pGroupData = ImplFindByGroupName(rFSD.maName); + if (pGroupData) + return pGroupData; + } +#if 1 + return FindDefaultFont(); +#else // if still needed use the font request's attributes to find a good match switch( rFSD.meLanguage ) { @@ -3007,10 +3339,12 @@ ImplDevFontListData* ImplDevFontList::Im } return pFoundData; +#endif } // ----------------------------------------------------------------------- +#if 0 ImplFontEntry* ImplFontCache::GetFallback( ImplDevFontList* pFontList, const Font& rOrigFont, const Size& rSize, int nFallbackLevel ) { @@ -3132,6 +3466,7 @@ ImplFontEntry* ImplFontCache::GetFallbac return pFallbackFont; } +#endif // ----------------------------------------------------------------------- @@ -6151,6 +6486,89 @@ SalLayout* OutputDevice::ImplGlyphFallba if( mpOutDevData && mpOutDevData->mpFirstFontSubstEntry ) nDevSpecificFallback = 1; + // Add by Firefly(firefly@firefly.idv.tw) + // 取得這個字體的群組 ID + int nGroupID = mpFontList->ImplCheckGroupID(maFont.GetName(), String()); + bool bSuccess = mpFontList->SetFallbackByGroupID(nGroupID); + ByteString aSelectName(maFont.GetName(), RTL_TEXTENCODING_UTF8); + + int nFallbackLevel = 1 - nDevSpecificFallback; + int nIndex = 0; + // try if fallback fonts support the missing unicodes + while (nIndex < mpFontList->GetFallbackCount()) + { + Font aFallbackFont = maFont; + if (nFallbackLevel > 0) + { + ImplDevFontListData* pFallbackData = mpFontList->GetFallback(nIndex); + if (!pFallbackData) + break; + aFallbackFont.SetName(pFallbackData->GetSearchName()); + } + + ImplFontEntry* pFallbackFont = mpFontCache->Get(mpFontList, aFallbackFont, aFontSize, NULL ); + + if( pFallbackFont && !pFallbackFont->mbInit ) + { + pFallbackFont->maMetric.maName = + pFallbackFont->maMetric.maStyleName = String(); + } + aFontSelData.mpFontEntry = pFallbackFont; + aFontSelData.mpFontData = pFallbackFont->maFontSelData.mpFontData; + if(mpFontEntry) + { + if( mpFontEntry->maFontSelData.mpFontData == aFontSelData.mpFontData ) + { + mpFontCache->Release( pFallbackFont ); + nIndex ++; + continue; + } + } + + pFallbackFont->mnSetFontFlags = mpGraphics->SetFont( &aFontSelData, nFallbackLevel ); + + // create and add glyph fallback layout to multilayout + rLayoutArgs.ResetPos(); + SalLayout* pFallback = mpGraphics->GetTextLayout( rLayoutArgs, nFallbackLevel ); + + if( pFallback ) + { + if( pFallback->LayoutText( rLayoutArgs ) ) + { + if( !pMultiSalLayout ) + pMultiSalLayout = new MultiSalLayout( *pSalLayout ); + pMultiSalLayout->AddFallback( *pFallback, + rLayoutArgs.maRuns, aFontSelData.mpFontData ); + } + else + pFallback->Release(); + } + + mpFontCache->Release( pFallbackFont ); + + if( !rLayoutArgs.PrepareFallback() ) + break; + + if (nFallbackLevel > 0) + nIndex ++; + + nFallbackLevel ++; + // 到此為止,沒有任何符合的字型,那就清除 Fallback list + // 重頭再來 + if (nFallbackLevel >= MAX_FALLBACK) + { + nFallbackLevel = 1; + + if (pMultiSalLayout) + { + for( int i = 1; i < pMultiSalLayout->mnLevel; ++i ) + pMultiSalLayout->mpLayouts[i]->Release(); + pMultiSalLayout->mnLevel = 1; + } + } + } + +#if 0 // try if fallback fonts support the missing unicodes for( int nFallbackLevel = 1; nFallbackLevel < MAX_FALLBACK; ++nFallbackLevel ) { @@ -6207,6 +6625,7 @@ SalLayout* OutputDevice::ImplGlyphFallba if( !rLayoutArgs.PrepareFallback() ) break; } +#endif if( pMultiSalLayout && pMultiSalLayout->LayoutText( rLayoutArgs ) ) pSalLayout = pMultiSalLayout;