diff -u -r vcl.old/inc/vcl/outdev.h vcl/inc/vcl/outdev.h --- vcl.old/inc/vcl/outdev.h 2009-06-12 10:10:41.000000000 +0800 +++ vcl/inc/vcl/outdev.h 2009-06-12 10:10:00.000000000 +0800 @@ -91,6 +91,7 @@ private: friend class ImplDevFontList; // TODO: remove soon + friend class WinGlyphFallbackSubstititution; //access mpFirst ImplFontData* mpFirst; // linked list of physical font faces String maName; // Fontname (original font family name) String maSearchName; // normalized font family name diff -u -r vcl.old/win/inc/salgdi.h vcl/win/inc/salgdi.h --- vcl.old/win/inc/salgdi.h 2009-06-12 10:10:44.000000000 +0800 +++ vcl/win/inc/salgdi.h 2009-06-12 10:10:03.000000000 +0800 @@ -81,6 +81,7 @@ bool SupportsArabic() const { return mbHasArabicSupport; } bool AliasSymbolsHigh() const { return mbAliasSymbolsHigh; } bool AliasSymbolsLow() const { return mbAliasSymbolsLow; } + void ReadCmapTable( HDC ) const; ImplFontCharMap* GetImplFontCharMap() const; const Ucs2SIntMap* GetEncodingVector() const { return mpEncodingVector; } @@ -109,7 +110,6 @@ bool mbAliasSymbolsHigh; bool mbAliasSymbolsLow; private: - void ReadCmapTable( HDC ) const; void ReadOs2Table( HDC ) const; #ifdef GNG_VERT_HACK diff -u -r vcl.old/win/source/gdi/salgdi3.cxx vcl/win/source/gdi/salgdi3.cxx --- vcl.old/win/source/gdi/salgdi3.cxx 2009-06-12 10:10:44.000000000 +0800 +++ vcl/win/source/gdi/salgdi3.cxx 2009-06-12 10:10:03.000000000 +0800 @@ -53,6 +53,10 @@ #include #include #include + +//enable ImplPreMatchFontSubstitution and ImplGlyphFallbackFontSubstitution declaration. +#include + #include #include #include @@ -311,6 +315,102 @@ } } + +// =========================================================================== +// platform specific font substitution hooks +//glyph fallback enhancement + +class ImplWinFontData; +void ImplGetLogFontFromFontSelect( HDC hDC, + const ImplFontSelectData* pFont, + LOGFONTW& rLogFont, + bool /*bTestVerticalAvail*/ ); + +class WinPreMatchSubstititution +: public ImplPreMatchFontSubstitution +{ +public: + bool FindFontSubstitute( ImplFontSelectData& ) const; +}; + +class WinGlyphFallbackSubstititution +: public ImplGlyphFallbackFontSubstitution +{ + // TODO: add a cache + HDC mhDC; + ImplDevFontList* mpFontList; +public: + WinGlyphFallbackSubstititution(HDC hdc, ImplDevFontList* pFontList) { + mhDC = hdc; + mpFontList = pFontList; + } + + void SetHDC(HDC hdc) {mhDC = hdc;} + void SetFontList(ImplDevFontList* pFontList) { mpFontList = pFontList; } + bool FindFontSubstitute( ImplFontSelectData&, rtl::OUString& rMissingCodes ) const; +}; + +bool WinPreMatchSubstititution::FindFontSubstitute(ImplFontSelectData& rFontSelData) const{ + return true; +} + +//get fallback font for missing character +bool WinGlyphFallbackSubstititution::FindFontSubstitute(ImplFontSelectData& rFontSelData, rtl::OUString& rMissingCodes) const{ + ImplDevFontList::DevFontList::const_iterator it = mpFontList->maDevFontList.begin(); + + //traverse font list and determine if certain font contain the missing characters + for(; it != mpFontList->maDevFontList.end(); ++it ) { + const ImplDevFontListData* pDevFontListData = (*it).second; + for( ImplFontData* pFontFace = pDevFontListData->mpFirst; pFontFace; pFontFace = pFontFace->GetNextFace() ) { + const ImplWinFontData* pWinFontData = static_cast(pFontFace); + //if CMAP is not available, get it + if(!pWinFontData->GetImplFontCharMap()) { + //construct a Size structure as the parameter of constructor of class ImplFontSelectData + const Size aSize(pFontFace->GetWidth(), pFontFace->GetHeight()); + //new a ImplFontSelectData object for creating LOGFONT + const ImplFontSelectData* pFontSelectData = new ImplFontSelectData(*pFontFace, aSize, 16, 0, false); + //construct log font + LOGFONTW aLogFont; + ImplGetLogFontFromFontSelect( mhDC, pFontSelectData, aLogFont, true ); + + HFONT hNewFont = 0, hOldFont = 0; + //create HFONT from log font + hNewFont = ::CreateFontIndirectW( &aLogFont ); + //select the new font into device + hOldFont = ::SelectFont( mhDC, hNewFont ); + + // read CMAP table + pWinFontData->ReadCmapTable( mhDC );; + + ::SelectFont( mhDC, hOldFont ); + ::DeleteFont( hNewFont ); + delete pFontSelectData; + } + sal_UCS4 cChar = 0; + sal_Int32 nStrIndex = 0; + sal_Int32 nStrlength = rMissingCodes.getLength(); + bool ismatch = true; + + //look if the fontface contain the missing characters + while( nStrIndex < nStrlength) { + cChar = rMissingCodes.iterateCodePoints( &nStrIndex ); + if(!(pWinFontData->HasChar(cChar))) { + ismatch = false; + break; + } + } + + //if the fontface meet the missing characters, set the rFontSelData's maSearchName with pFontData->maName + //and return true + if(ismatch) { + rFontSelData.maSearchName = pFontFace->maName; + return true; + } + } + } + return false; +} + // ======================================================================= struct ImplEnumInfo @@ -903,6 +1003,8 @@ ImplFontCharMap* ImplWinFontData::GetImplFontCharMap() const { + if(!mpUnicodeMap) + return 0; mpUnicodeMap->AddReference(); return mpUnicodeMap; } @@ -2243,6 +2345,11 @@ bImplSalCourierScalable = aInfo.mbImplSalCourierScalable; bImplSalCourierNew = aInfo.mbImplSalCourierNew; } + + //set font fallback hook + static WinGlyphFallbackSubstititution aSubstFallback(mhDC, pFontList); + //aSubstFallback.SetHDC(mhDC); + pFontList->SetFallbackHook( &aSubstFallback ); } // ----------------------------------------------------------------------------