diff options
author | Martin Hosken <martin_hosken@sil.org> | 2011-02-25 16:10:55 +0700 |
---|---|---|
committer | Martin Hosken <martin_hosken@sil.org> | 2011-03-10 22:40:13 +0700 |
commit | df3c7e76cca60d246277731d0c525d5f7e6f6597 (patch) | |
tree | 3526bbe9a0eb2ca6e6373a75697fc5d9bcefac63 /vcl/win | |
parent | e2c95099c8946ab051de02c28d98d18b2c3037e7 (diff) |
graphite2 consolidated patch
Diffstat (limited to 'vcl/win')
-rw-r--r-- | vcl/win/inc/salgdi.h | 29 | ||||
-rw-r--r-- | vcl/win/source/gdi/salgdi.cxx | 3 | ||||
-rw-r--r-- | vcl/win/source/gdi/salgdi3.cxx | 202 | ||||
-rw-r--r-- | vcl/win/source/gdi/winlayout.cxx | 116 |
4 files changed, 264 insertions, 86 deletions
diff --git a/vcl/win/inc/salgdi.h b/vcl/win/inc/salgdi.h index 637a759b0b46..951e0c8d7690 100644 --- a/vcl/win/inc/salgdi.h +++ b/vcl/win/inc/salgdi.h @@ -39,6 +39,10 @@ #include "boost/scoped_ptr.hpp" #include <boost/unordered_set.hpp> +#ifdef ENABLE_GRAPHITE +#include <graphite2/Font.h> +#endif + class ImplFontSelectData; class ImplWinFontEntry; class ImplFontAttrCache; @@ -55,6 +59,26 @@ class ImplFontAttrCache; #define GCP_KERN_HACK #define GNG_VERT_HACK +#ifdef ENABLE_GRAPHITE +class RawFontData; +class GrFontData +{ +public: + GrFontData(HDC hDC); + ~GrFontData(); + const void * getTable(unsigned int name, size_t *len) const; + const gr_face * getFace() const { return mpFace; } + void AddReference() { ++mnRefCount; } + void DeReference() { if (--mnRefCount == 0) delete this; } +private: + GrFontData(GrFontData &) {}; + HDC mhDC; + mutable std::vector<RawFontData*> mvData; + gr_face * mpFace; + unsigned int mnRefCount; +}; +#endif + // win32 specific physically available font face class ImplWinFontData : public ImplFontData { @@ -82,6 +106,7 @@ public: bool AliasSymbolsLow() const { return mbAliasSymbolsLow; } #ifdef ENABLE_GRAPHITE bool SupportsGraphite() const { return mbHasGraphiteSupport; } + const gr_face* GraphiteFace() const; #endif ImplFontCharMap* GetImplFontCharMap() const; @@ -101,6 +126,7 @@ private: mutable bool mbHasKoreanRange; mutable bool mbHasCJKSupport; #ifdef ENABLE_GRAPHITE + mutable GrFontData* mpGraphiteData; mutable bool mbHasGraphiteSupport; #endif mutable bool mbHasArabicSupport; @@ -144,7 +170,8 @@ public: HFONT mhFonts[ MAX_FALLBACK ]; // Font + Fallbacks const ImplWinFontData* mpWinFontData[ MAX_FALLBACK ]; // pointer to the most recent font face ImplWinFontEntry* mpWinFontEntry[ MAX_FALLBACK ]; // pointer to the most recent font instance - float mfFontScale; // allows metrics emulation of huge font sizes + float mfFontScale[ MAX_FALLBACK ]; // allows metrics emulation of huge font sizes + float mfCurrentFontScale; HPEN mhPen; // Pen HBRUSH mhBrush; // Brush HRGN mhRegion; // Region Handle diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index f06108393716..cac65c8c229b 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -722,9 +722,10 @@ WinSalGraphics::WinSalGraphics() mhFonts[ i ] = 0; mpWinFontData[ i ] = NULL; mpWinFontEntry[ i ] = NULL; + mfFontScale[ i ] = 1.0; } - mfFontScale = 1.0; + mfCurrentFontScale = 1.0; mhDC = 0; mhPen = 0; diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index 5b744f599815..da7b42807acf 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -78,8 +78,7 @@ #endif #ifdef ENABLE_GRAPHITE -#include <graphite/GrClient.h> -#include <graphite/WinFont.h> +#include <graphite2/Font.h> #endif #include <vector> @@ -1091,6 +1090,106 @@ void ImplSalLogFontToFontW( HDC hDC, const LOGFONTW& rLogFont, Font& rFont ) } // ======================================================================= +#ifdef ENABLE_GRAPHITE + +#ifdef DEBUG +static FILE * grLogFile = NULL; +static FILE * grLog() +{ +#ifdef WNT + std::string logFileName(getenv("TEMP")); + logFileName.append("\\grface.log"); + if (grLogFile == NULL) grLogFile = fopen(logFileName.c_str(),"w"); + else fflush(grLogFile); + return grLogFile; +#else + fflush(stdout); + return stdout; +#endif +} +#undef NDEBUG +#endif + +const void * getGrTable(const void* appFaceHandle, unsigned int name, size_t *len) +{ + const GrFontData * fontTables = reinterpret_cast<const GrFontData*>(appFaceHandle); + return fontTables->getTable(name, len); +} + +GrFontData::GrFontData(HDC hDC) : + mhDC(hDC), mpFace(NULL), mnRefCount(1) +{ + // The face options ensure that the tables are all read at construction + // time so there is no need to keep the hDC uptodate + static const char* pGraphiteCacheStr = getenv( "SAL_GRAPHITE_CACHE_SIZE" ); + unsigned long graphiteSegCacheSize = pGraphiteCacheStr ? (atoi(pGraphiteCacheStr)) : 0; + if (graphiteSegCacheSize > 500) + mpFace = gr_make_face_with_seg_cache(this, getGrTable, + graphiteSegCacheSize, gr_face_preloadGlyphs | gr_face_cacheCmap); + else + mpFace = gr_make_face(this, getGrTable, + gr_face_preloadGlyphs | gr_face_cacheCmap); +#ifdef DEBUG + fprintf(grLog(), "gr_make_face %lx for WinFontData %lx\n", (unsigned long)mpFace, + (unsigned long)this); +#endif + mhDC = NULL; +} + +GrFontData::~GrFontData() +{ + if (mpFace) + { +#ifdef DEBUG + fprintf(grLog(), "gr_face_destroy %lx for WinFontData %lx\n", (unsigned long)mpFace, + (unsigned long)this); +#endif + gr_face_destroy(mpFace); + mpFace = NULL; + } + std::vector<RawFontData*>::iterator i = mvData.begin(); + while (i != mvData.end()) + { + delete *i; + ++i; + } + mvData.clear(); +} + +const void * GrFontData::getTable(unsigned int name, size_t *len) const +{ +#ifdef DEBUG +#undef NDEBUG +#endif + assert(mhDC); + // swap the bytes + union TtfTag { + unsigned int i; + unsigned char c[4]; + }; + TtfTag littleEndianTag; + littleEndianTag.i = name; + TtfTag bigEndianTag; + bigEndianTag.c[0] = littleEndianTag.c[3]; + bigEndianTag.c[1] = littleEndianTag.c[2]; + bigEndianTag.c[2] = littleEndianTag.c[1]; + bigEndianTag.c[3] = littleEndianTag.c[0]; + mvData.push_back(new RawFontData(mhDC, bigEndianTag.i)); + const RawFontData * data = mvData[mvData.size()-1]; + if (data && (data->size() > 0)) + { + if (len) + *len = data->size(); + return reinterpret_cast<const void *>(data->get()); + } + else + { + if (len) + *len = 0; + return NULL; + } +} +#endif ImplWinFontData::ImplWinFontData( const ImplDevFontAttributes& rDFS, int nHeight, WIN_BYTE eWinCharSet, WIN_BYTE nPitchAndFamily ) @@ -1112,6 +1211,9 @@ ImplWinFontData::ImplWinFontData( const ImplDevFontAttributes& rDFS, mbAliasSymbolsHigh( false ), mnId( 0 ), mpEncodingVector( NULL ) +#ifdef ENABLE_GRAPHITE + ,mpGraphiteData(NULL) +#endif { SetBitmapSize( 0, nHeight ); @@ -1135,6 +1237,9 @@ ImplWinFontData::ImplWinFontData( const ImplDevFontAttributes& rDFS, mbAliasSymbolsHigh = true; } } +#ifdef DEBUG + fprintf(grLog(), "ImplWinFontData::ImplWinFontData() %lx\n", (unsigned long)this); +#endif } // ----------------------------------------------------------------------- @@ -1145,6 +1250,13 @@ ImplWinFontData::~ImplWinFontData() if( mpUnicodeMap ) mpUnicodeMap->DeReference(); +#ifdef ENABLE_GRAPHITE + if (mpGraphiteData) + mpGraphiteData->DeReference(); +#ifdef DEBUG + fprintf(grLog(), "ImplWinFontData::~ImplWinFontData %lx\n", (unsigned long)this); +#endif +#endif // ENABLE_GRAPHITE delete mpEncodingVector; } @@ -1157,6 +1269,11 @@ sal_IntPtr ImplWinFontData::GetFontId() const // ----------------------------------------------------------------------- +static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);} +static unsigned GetUShort( const unsigned char* p ){ return((p[0]<<8)+p[1]);} +//static signed GetSShort( const unsigned char* p ){ return((short)((p[0]<<8)+p[1]));} +static inline DWORD CalcTag( const char p[4]) { return (p[0]+(p[1]<<8)+(p[2]<<16)+(p[3]<<24)); } + void ImplWinFontData::UpdateFromHDC( HDC hDC ) const { // short circuit if already initialized @@ -1169,7 +1286,26 @@ void ImplWinFontData::UpdateFromHDC( HDC hDC ) const static const char* pDisableGraphiteText = getenv( "SAL_DISABLE_GRAPHITE" ); if( !pDisableGraphiteText || (pDisableGraphiteText[0] == '0') ) { - mbHasGraphiteSupport = gr::WinFont::FontHasGraphiteTables(hDC); + const DWORD nSilfTag = CalcTag("Silf"); + const RawFontData aRawFontData( hDC, nSilfTag ); + mbHasGraphiteSupport = (aRawFontData.size() > 0); + if (mbHasGraphiteSupport) + { +#ifdef DEBUG + fprintf(grLog(), "ImplWinFontData::UpdateFromHDC %lx\n", + (unsigned long)this); +#endif + if (mpGraphiteData == NULL) + { + mpGraphiteData = new GrFontData(hDC); + if (!mpGraphiteData->getFace()) + { + mbHasGraphiteSupport = false; + delete mpGraphiteData; + mpGraphiteData = NULL; + } + } + } } #endif @@ -1183,6 +1319,17 @@ void ImplWinFontData::UpdateFromHDC( HDC hDC ) const } +#ifdef ENABLE_GRAPHITE +const gr_face* ImplWinFontData::GraphiteFace() const +{ +#ifdef DEBUG + fprintf(grLog(), "ImplWinFontData::GraphiteFace %lx has face %lx\n", + (unsigned long)this, mpGraphiteData? mpGraphiteData->getFace(): 0); +#endif + assert((mpGraphiteData == NULL) || (mpGraphiteData->getFontData() == this)); + return (mpGraphiteData)? mpGraphiteData->getFace() : NULL; +} +#endif // ----------------------------------------------------------------------- bool ImplWinFontData::HasGSUBstitutions( HDC hDC ) const @@ -1222,6 +1369,31 @@ static unsigned GetUShort( const unsigned char* p ){ return((p[0]<<8)+p[1]);} //static signed GetSShort( const unsigned char* p ){ return((short)((p[0]<<8)+p[1]));} static inline DWORD CalcTag( const char p[4]) { return (p[0]+(p[1]<<8)+(p[2]<<16)+(p[3]<<24)); } +void ImplWinFontData::ReadOs2Table( HDC hDC ) const +{ + const DWORD Os2Tag = CalcTag( "OS/2" ); + DWORD nLength = ::GetFontData( hDC, Os2Tag, 0, NULL, 0 ); + if( (nLength == GDI_ERROR) || !nLength ) + return; + std::vector<unsigned char> aOS2map( nLength ); + unsigned char* pOS2map = &aOS2map[0]; + ::GetFontData( hDC, Os2Tag, 0, pOS2map, nLength ); + sal_uInt32 nVersion = GetUShort( pOS2map ); + if ( nVersion >= 0x0001 && nLength >= 58 ) + { + // We need at least version 0x0001 (TrueType rev 1.66) + // to have access to the needed struct members. + sal_uInt32 ulUnicodeRange1 = GetUInt( pOS2map + 42 ); + sal_uInt32 ulUnicodeRange2 = GetUInt( pOS2map + 46 ); + + // Check for CJK capabilities of the current font + mbHasCJKSupport = (ulUnicodeRange2 & 0x2DF00000); + mbHasKoreanRange= (ulUnicodeRange1 & 0x10000000) + | (ulUnicodeRange2 & 0x01100000); + mbHasArabicSupport = (ulUnicodeRange1 & 0x00002000); + } +} + // ----------------------------------------------------------------------- void ImplWinFontData::ReadGsubTable( HDC hDC ) const @@ -1545,6 +1717,7 @@ USHORT WinSalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLevel ) // deselect still active font if( mhDefFont ) ::SelectFont( mhDC, mhDefFont ); + mfCurrentFontScale = mfFontScale[nFallbackLevel]; // release no longer referenced font handles for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) { @@ -1561,7 +1734,8 @@ USHORT WinSalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLevel ) mpWinFontData[ nFallbackLevel ] = static_cast<const ImplWinFontData*>( pFont->mpFontData ); HFONT hOldFont = 0; - HFONT hNewFont = ImplDoSetFont( pFont, mfFontScale, hOldFont ); + HFONT hNewFont = ImplDoSetFont( pFont, mfFontScale[ nFallbackLevel ], hOldFont ); + mfCurrentFontScale = mfFontScale[nFallbackLevel]; if( !mhDefFont ) { @@ -1655,11 +1829,11 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLe } // transformation dependend font metrics - pMetric->mnWidth = static_cast<int>( mfFontScale * aWinMetric.tmAveCharWidth ); - pMetric->mnIntLeading = static_cast<int>( mfFontScale * aWinMetric.tmInternalLeading ); - pMetric->mnExtLeading = static_cast<int>( mfFontScale * aWinMetric.tmExternalLeading ); - pMetric->mnAscent = static_cast<int>( mfFontScale * aWinMetric.tmAscent ); - pMetric->mnDescent = static_cast<int>( mfFontScale * aWinMetric.tmDescent ); + pMetric->mnWidth = static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmAveCharWidth ); + pMetric->mnIntLeading = static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmInternalLeading ); + pMetric->mnExtLeading = static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmExternalLeading ); + pMetric->mnAscent = static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmAscent ); + pMetric->mnDescent = static_cast<int>( mfFontScale[nFallbackLevel] * aWinMetric.tmDescent ); // #107888# improved metric compatibility for Asian fonts... // TODO: assess workaround below for CWS >= extleading @@ -2386,10 +2560,10 @@ BOOL WinSalGraphics::GetGlyphBoundRect( long nIndex, Rectangle& rRect ) rRect = Rectangle( Point( +aGM.gmptGlyphOrigin.x, -aGM.gmptGlyphOrigin.y ), Size( aGM.gmBlackBoxX, aGM.gmBlackBoxY ) ); - rRect.Left() = static_cast<int>( mfFontScale * rRect.Left() ); - rRect.Right() = static_cast<int>( mfFontScale * rRect.Right() ); - rRect.Top() = static_cast<int>( mfFontScale * rRect.Top() ); - rRect.Bottom() = static_cast<int>( mfFontScale * rRect.Bottom() ); + rRect.Left() = static_cast<int>( mfCurrentFontScale * rRect.Left() ); + rRect.Right() = static_cast<int>( mfCurrentFontScale * rRect.Right() ); + rRect.Top() = static_cast<int>( mfCurrentFontScale * rRect.Top() ); + rRect.Bottom() = static_cast<int>( mfCurrentFontScale * rRect.Bottom() ); return true; } @@ -2575,7 +2749,7 @@ BOOL WinSalGraphics::GetGlyphOutline( long nIndex, // rescaling needed for the PolyPolygon conversion if( rB2DPolyPoly.count() ) { - const double fFactor(mfFontScale/256); + const double fFactor(mfCurrentFontScale/256); rB2DPolyPoly.transform(basegfx::tools::createScaleB2DHomMatrix(fFactor, fFactor)); } diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 1114de6f098b..a340ab512a57 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -74,11 +74,7 @@ typedef std::set<int> IntSet; // Graphite headers #ifdef ENABLE_GRAPHITE #include <i18npool/mslangid.hxx> -#include <graphite/GrClient.h> -#include <graphite/WinFont.h> -#include <graphite/Segment.h> #include <vcl/graphite_layout.hxx> -#include <vcl/graphite_cache.hxx> #include <vcl/graphite_features.hxx> #endif @@ -1951,11 +1947,11 @@ int UniscribeLayout::GetNextGlyphs( int nLen, sal_GlyphId* pGlyphs, Point& rPos, } else { - nExtraOfs += nToFillWidth; // at right of cell - nSubIter = 0; // done with glyph injection + nExtraOfs += nToFillWidth; // at right of cell + nSubIter = 0; // done with glyph injection } if( !bManualCellAlign ) - nExtraOfs -= nExtraWidth; // adjust for right-aligned cells + nExtraOfs -= nExtraWidth; // adjust for right-aligned cells // adjust the draw position for the injected-glyphs case if( nExtraOfs ) @@ -2561,8 +2557,8 @@ void UniscribeLayout::KashidaItemFix( int nMinGlyphPos, int nEndGlyphPos ) { // check for vowels if( (i > nMinGlyphPos && !mpGlyphAdvances[ i-1 ]) - && (1U << mpVisualAttrs[i].uJustification) & 0xFF83 ) // all Arabic justifiction types - { // including SCRIPT_JUSTIFY_NONE + && (1U << mpVisualAttrs[i].uJustification) & 0xFF83 ) // all Arabic justifiction types + { // including SCRIPT_JUSTIFY_NONE // vowel, we do it like ScriptJustify does // the vowel gets the extra width long nSpaceAdded = mpJustifications[ i ] - mpGlyphAdvances[ i ]; @@ -2695,7 +2691,7 @@ void UniscribeLayout::Justify( long nNewWidth ) if( nOldWidth <= 0 ) return; - nNewWidth *= mnUnitsPerPixel; // convert into font units + nNewWidth *= mnUnitsPerPixel; // convert into font units if( nNewWidth == nOldWidth ) return; // prepare to distribute the extra width evenly among the visual items @@ -2757,8 +2753,8 @@ bool UniscribeLayout::IsKashidaPosValid ( int nCharPos ) const if ( nMinGlyphIndex == -1 || !mpLogClusters[ nCharPos ] ) return false; -// This test didn't give the expected results -/* if( mpLogClusters[ nCharPos+1 ] == mpLogClusters[ nCharPos ]) +// This test didn't give the expected results +/* if( mpLogClusters[ nCharPos+1 ] == mpLogClusters[ nCharPos ]) // two chars, one glyph return false;*/ @@ -2782,9 +2778,9 @@ bool UniscribeLayout::IsKashidaPosValid ( int nCharPos ) const class GraphiteLayoutWinImpl : public GraphiteLayout { public: - GraphiteLayoutWinImpl(const gr::Font & font, ImplWinFontEntry & rFont) + GraphiteLayoutWinImpl(const gr_face * pFace, ImplWinFontEntry & rFont) throw() - : GraphiteLayout(font), mrFont(rFont) {}; + : GraphiteLayout(pFace), mrFont(rFont) {}; virtual ~GraphiteLayoutWinImpl() throw() {}; virtual sal_GlyphId getKashidaGlyph(int & rWidth); private: @@ -2803,18 +2799,15 @@ sal_GlyphId GraphiteLayoutWinImpl::getKashidaGlyph(int & rWidth) class GraphiteWinLayout : public WinLayout { private: - mutable GraphiteWinFont mpFont; + gr_font * mpFont; grutils::GrFeatureParser * mpFeatures; mutable GraphiteLayoutWinImpl maImpl; public: GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplWinFontEntry& rWFE); - static bool IsGraphiteEnabledFont(HDC hDC) throw(); - // used by upper layers virtual bool LayoutText( ImplLayoutArgs& ); // first step of layout virtual void AdjustLayout( ImplLayoutArgs& ); // adjusting after fallback etc. - // virtual void InitFont() const; virtual void DrawText( SalGraphics& ) const; // methods using string indexing @@ -2832,20 +2825,31 @@ public: virtual void DropGlyph( int nStart ); virtual void Simplify( bool bIsBase ); ~GraphiteWinLayout() { delete mpFeatures; mpFeatures = NULL; }; -protected: - virtual void ReplaceDC(gr::Segment & segment) const; - virtual void RestoreDC(gr::Segment & segment) const; }; -bool GraphiteWinLayout::IsGraphiteEnabledFont(HDC hDC) throw() +float gr_fontAdvance(const void* appFontHandle, gr_uint16 glyphId) { - return gr::WinFont::FontHasGraphiteTables(hDC); + HDC hDC = reinterpret_cast<HDC>(const_cast<void*>(appFontHandle)); + GLYPHMETRICS gm; + const MAT2 mat2 = {{0,1}, {0,0}, {0,0}, {0,1}}; + if (GDI_ERROR == ::GetGlyphOutlineW(hDC, glyphId, GGO_GLYPH_INDEX | GGO_METRICS, + &gm, 0, NULL, &mat2)) + { + return .0f; + } + return gm.gmCellIncX; } GraphiteWinLayout::GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplWinFontEntry& rWFE) throw() - : WinLayout(hDC, rWFD, rWFE), mpFont(hDC), - maImpl(mpFont, rWFE) + : WinLayout(hDC, rWFD, rWFE), mpFont(NULL), + maImpl(rWFD.GraphiteFace(), rWFE) { + // the log font size may differ from the font entry size if scaling is used for large fonts + LOGFONTW aLogFont; + ::GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont); + mpFont = gr_make_font_with_advance_fn(static_cast<float>(-aLogFont.lfHeight), + hDC, gr_fontAdvance, rWFD.GraphiteFace()); + maImpl.TakeFont(mpFont); const rtl::OString aLang = MsLangId::convertLanguageToIsoByteString( rWFE.maFontSelData.meLanguage ); rtl::OString name = rtl::OUStringToOString( rWFE.maFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); @@ -2853,27 +2857,15 @@ GraphiteWinLayout::GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplW if (nFeat > 0) { rtl::OString aFeat = name.copy(nFeat, name.getLength() - nFeat); - mpFeatures = new grutils::GrFeatureParser(mpFont, aFeat.getStr(), aLang.getStr()); + mpFeatures = new grutils::GrFeatureParser(rWFD.GraphiteFace(), aFeat.getStr(), aLang.getStr()); } else { - mpFeatures = new grutils::GrFeatureParser(mpFont, aLang.getStr()); + mpFeatures = new grutils::GrFeatureParser(rWFD.GraphiteFace(), aLang.getStr()); } maImpl.SetFeatures(mpFeatures); } -void GraphiteWinLayout::ReplaceDC(gr::Segment & segment) const -{ - COLORREF color = GetTextColor(mhDC); - dynamic_cast<gr::WinFont&>(segment.getFont()).replaceDC(mhDC); - SetTextColor(mhDC, color); -} - -void GraphiteWinLayout::RestoreDC(gr::Segment & segment) const -{ - dynamic_cast<gr::WinFont&>(segment.getFont()).restoreDC(); -} - bool GraphiteWinLayout::LayoutText( ImplLayoutArgs & args) { if (args.mnMinCharPos >= args.mnEndCharPos) @@ -2881,7 +2873,7 @@ bool GraphiteWinLayout::LayoutText( ImplLayoutArgs & args) maImpl.clear(); return true; } - HFONT hUnRotatedFont; + HFONT hUnRotatedFont = 0; if (args.mnOrientation) { // Graphite gets very confused if the font is rotated @@ -2893,36 +2885,16 @@ bool GraphiteWinLayout::LayoutText( ImplLayoutArgs & args) ::SelectFont(mhDC, hUnRotatedFont); } WinLayout::AdjustLayout(args); - mpFont.replaceDC(mhDC); maImpl.SetFontScale(WinLayout::mfFontScale); - //bool succeeded = maImpl.LayoutText(args); -#ifdef GRCACHE - GrSegRecord * pSegRecord = NULL; - gr::Segment * pSegment = maImpl.CreateSegment(args, &pSegRecord); -#else - gr::Segment * pSegment = maImpl.CreateSegment(args); -#endif + gr_segment * pSegment = maImpl.CreateSegment(args); bool bSucceeded = false; if (pSegment) { // replace the DC on the font within the segment - ReplaceDC(*pSegment); // create glyph vectors -#ifdef GRCACHE - bSucceeded = maImpl.LayoutGlyphs(args, pSegment, pSegRecord); -#else bSucceeded = maImpl.LayoutGlyphs(args, pSegment); -#endif - // restore original DC - RestoreDC(*pSegment); -#ifdef GRCACHE - if (pSegRecord) pSegRecord->unlock(); - else delete pSegment; -#else - delete pSegment; -#endif + gr_seg_destroy(pSegment); } - mpFont.restoreDC(); if (args.mnOrientation) { // restore the rotated font @@ -2971,9 +2943,7 @@ void GraphiteWinLayout::DrawText(SalGraphics &sal_graphics) const int GraphiteWinLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const { - mpFont.replaceDC(mhDC); int nBreak = maImpl.GetTextBreak(nMaxWidth, nCharExtra, nFactor); - mpFont.restoreDC(); return nBreak; } @@ -3027,7 +2997,9 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe { #ifdef ENABLE_GRAPHITE if (rFontFace.SupportsGraphite()) + { pWinLayout = new GraphiteWinLayout(mhDC, rFontFace, rFontInstance); + } else #endif // ENABLE_GRAPHITE // script complexity is determined in upper layers @@ -3060,20 +3032,20 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe pWinLayout = new SimpleWinLayout( mhDC, eCharSet, rFontFace, rFontInstance ); } - if( mfFontScale != 1.0 ) - pWinLayout->SetFontScale( mfFontScale ); + if( mfFontScale[nFallbackLevel] != 1.0 ) + pWinLayout->SetFontScale( mfFontScale[nFallbackLevel] ); return pWinLayout; } // ----------------------------------------------------------------------- -int WinSalGraphics::GetMinKashidaWidth() +int WinSalGraphics::GetMinKashidaWidth() { if( !mpWinFontEntry[0] ) return 0; mpWinFontEntry[0]->InitKashidaHandling( mhDC ); - int nMinKashida = static_cast<int>(mfFontScale * mpWinFontEntry[0]->GetMinKashidaWidth()); + int nMinKashida = static_cast<int>(mfFontScale[0] * mpWinFontEntry[0]->GetMinKashidaWidth()); return nMinKashida; } @@ -3084,8 +3056,8 @@ ImplWinFontEntry::ImplWinFontEntry( ImplFontSelectData& rFSD ) , maWidthMap( 512 ) , mpKerningPairs( NULL ) , mnKerningPairs( -1 ) -, mnMinKashidaWidth( -1 ) -, mnMinKashidaGlyph( -1 ) +, mnMinKashidaWidth( -1 ) +, mnMinKashidaGlyph( -1 ) { #ifdef USE_UNISCRIBE maScriptCache = NULL; @@ -3175,6 +3147,10 @@ ImplFontData* ImplWinFontData::Clone() const { if( mpUnicodeMap ) mpUnicodeMap->AddReference(); +#ifdef ENABLE_GRAPHITE + if ( mpGraphiteData ) + mpGraphiteData->AddReference(); +#endif ImplFontData* pClone = new ImplWinFontData( *this ); return pClone; } |