summaryrefslogtreecommitdiff
path: root/vcl/win
diff options
context:
space:
mode:
authorMartin Hosken <martin_hosken@sil.org>2011-02-25 16:10:55 +0700
committerMartin Hosken <martin_hosken@sil.org>2011-03-10 22:40:13 +0700
commitdf3c7e76cca60d246277731d0c525d5f7e6f6597 (patch)
tree3526bbe9a0eb2ca6e6373a75697fc5d9bcefac63 /vcl/win
parente2c95099c8946ab051de02c28d98d18b2c3037e7 (diff)
graphite2 consolidated patch
Diffstat (limited to 'vcl/win')
-rw-r--r--vcl/win/inc/salgdi.h29
-rw-r--r--vcl/win/source/gdi/salgdi.cxx3
-rw-r--r--vcl/win/source/gdi/salgdi3.cxx202
-rw-r--r--vcl/win/source/gdi/winlayout.cxx116
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;
}