[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - vcl/inc vcl/win

2016-06-14 Thread Michael Stahl
 vcl/inc/win/saldata.hxx |2 ++
 vcl/inc/win/salinst.h   |1 +
 vcl/win/source/app/salinst.cxx  |4 
 vcl/win/source/app/saltimer.cxx |   38 --
 4 files changed, 31 insertions(+), 14 deletions(-)

New commits:
commit 25ba37abcc8ad381be6038ddb332dd60d3dcf4b1
Author: Michael Stahl 
Date:   Mon Apr 11 23:49:12 2016 +0200

tdf#96887 vcl: stop using periodic timers on WNT

Every time the periodic timer fires, it does a PostMessage() to the
main thread.  The main thread will only process the first message and
discard the rest anyway, but with a short enough timer and other
threads hogging the SolarMutex it's possible that the message queue
overflows and other PostMessage calls fail with ERROR_NOT_ENOUGH_QUOTA.

Try to avoid the problem by having the WinSalTimer always be a one-shot
timer; when it fires and the main thread processes the posted message,
it is restarted with the new due time.

This requires creating a new TimerQueueTimer because
ChangeTimerQueueTimer only works on periodic timers.

Change-Id: I816bd3fa5fbfbea4f26be8ff680a1c916618d3f9
Reviewed-on: https://gerrit.libreoffice.org/24024
Tested-by: Jenkins 
Reviewed-by: Jan Holesovsky 
Reviewed-by: Michael Stahl 
Reviewed-on: https://gerrit.libreoffice.org/26257
Reviewed-by: Tor Lillqvist 
Tested-by: Tor Lillqvist 

diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx
index 66b8a7f..83e853f 100644
--- a/vcl/inc/win/saldata.hxx
+++ b/vcl/inc/win/saldata.hxx
@@ -277,6 +277,8 @@ int ImplSalWICompareAscii( const wchar_t* pStr1, const 
char* pStr2 );
 
 // Call the Timer's callback from the main thread
 #define SAL_MSG_TIMER_CALLBACK  (WM_USER+162)
+// Stop the timer from the main thread; wParam = 0, lParam = 0
+#define SAL_MSG_STOPTIMER   (WM_USER+163)
 
 inline void SetWindowPtr( HWND hWnd, WinSalFrame* pThis )
 {
diff --git a/vcl/inc/win/salinst.h b/vcl/inc/win/salinst.h
index fe2c341..43c0313 100644
--- a/vcl/inc/win/salinst.h
+++ b/vcl/inc/win/salinst.h
@@ -83,6 +83,7 @@ SalFrame* ImplSalCreateFrame( WinSalInstance* pInst, HWND 
hWndParent, SalFrameSt
 SalObject* ImplSalCreateObject( WinSalInstance* pInst, WinSalFrame* pParent );
 HWND ImplSalReCreateHWND( HWND hWndParent, HWND oldhWnd, bool bAsChild );
 void ImplSalStartTimer( sal_uIntPtr nMS, bool bMutex = false );
+void ImplSalStopTimer();
 
 #endif // INCLUDED_VCL_INC_WIN_SALINST_H
 
diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx
index c76fa44..b229d46 100644
--- a/vcl/win/source/app/salinst.cxx
+++ b/vcl/win/source/app/salinst.cxx
@@ -689,6 +689,10 @@ LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM 
wParam, LPARAM lParam, i
 ImplSalStartTimer( (sal_uLong) lParam, FALSE );
 rDef = FALSE;
 break;
+case SAL_MSG_STOPTIMER:
+ImplSalStopTimer();
+rDef = FALSE;
+break;
 case SAL_MSG_CREATEFRAME:
 nRet = (LRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, 
(HWND)lParam, (SalFrameStyleFlags)wParam );
 rDef = FALSE;
diff --git a/vcl/win/source/app/saltimer.cxx b/vcl/win/source/app/saltimer.cxx
index c6f04be..641d2eb 100644
--- a/vcl/win/source/app/saltimer.cxx
+++ b/vcl/win/source/app/saltimer.cxx
@@ -34,12 +34,22 @@ void CALLBACK SalTimerProc(PVOID pParameter, BOOLEAN 
bTimerOrWaitFired);
 // See 
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687003%28v=vs.85%29.aspx
 // (and related pages) for details about the Timer Queues.
 
-void ImplSalStopTimer(SalData* pSalData)
+// in order to prevent concurrent execution of ImplSalStartTimer and double
+// deletion of timer (which is extremely likely, given that
+// INVALID_HANDLE_VALUE waits for the callback to run on the main thread),
+// this must run on the main thread too
+void ImplSalStopTimer()
 {
+SalData *const pSalData = GetSalData();
 HANDLE hTimer = pSalData->mnTimerId;
-pSalData->mnTimerId = 0;
-DeleteTimerQueueTimer(NULL, hTimer, INVALID_HANDLE_VALUE);
+if (hTimer)
+{
+pSalData->mnTimerId = 0; // reset so it doesn't restart
+DeleteTimerQueueTimer(NULL, hTimer, INVALID_HANDLE_VALUE);
+pSalData->mnNextTimerTime = 0;
+}
 MSG aMsg;
+// this needs to run on the main thread
 while (PeekMessageW(, 0, SAL_MSG_TIMER_CALLBACK, 
SAL_MSG_TIMER_CALLBACK, PM_REMOVE))
 {
 // just remove all the SAL_MSG_TIMER_CALLBACKs
@@ -61,11 +71,13 @@ void ImplSalStartTimer( sal_uLong nMS, bool bMutex )
 if (nMS > MAX_SYSPERIOD)
 nMS = MAX_SYSPERIOD;
 
-// change if it exists, create if not
+// cannot change a one-shot timer, so delete it and create new one
 if (pSalData->mnTimerId)
-ChangeTimerQueueTimer(NULL, 

[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - vcl/inc vcl/win

2016-06-14 Thread Armin Le Grand
 vcl/inc/win/saldata.hxx|2 
 vcl/inc/win/salinst.h  |8 --
 vcl/win/source/app/salinst.cxx |  117 +++--
 3 files changed, 34 insertions(+), 93 deletions(-)

New commits:
commit 69fa1e78febb4991e8e8b8b53ddf5b2d4f7e9f00
Author: Armin Le Grand 
Date:   Fri Apr 8 15:14:43 2016 +0200

tdf#96887 enhance SolarMutex AcquireWithWait for Windows

Currently the Windows-specific method ImplSalYieldMutexAcquireWithWait()
uses a messaging mechanism to learn about the SolarMutex being free again.
This is not reliable when the MessageQueue overflows (MS allows 1
messages per queue). It is more safe to use MsgWaitForMultipleObjects.
This also allows to not only wait for the SolarMutex to be freed, but
also to detect when SendMessage() is used which needs to lead to a
reschedule to not block current Window handling.

Change-Id: Id317dda62aaa1fe7677d8d28929e6936e5a22705
Reviewed-on: https://gerrit.libreoffice.org/23921
Tested-by: Jenkins 
Reviewed-by: Armin Le Grand 
Reviewed-on: https://gerrit.libreoffice.org/26256
Reviewed-by: Tor Lillqvist 
Tested-by: Tor Lillqvist 
Reviewed-by: Michael Stahl 

diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx
index ed8a2fd..66b8a7f 100644
--- a/vcl/inc/win/saldata.hxx
+++ b/vcl/inc/win/saldata.hxx
@@ -214,8 +214,6 @@ int ImplSalWICompareAscii( const wchar_t* pStr1, const 
char* pStr2 );
 
 // wParam == bWait; lParam == 0
 #define SAL_MSG_THREADYIELD (WM_USER+111)
-// wParam == 0; lParam == 0
-#define SAL_MSG_RELEASEWAITYIELD(WM_USER+112)
 // wParam == 0; lParam == nMS
 #define SAL_MSG_STARTTIMER  (WM_USER+113)
 // wParam == nFrameStyle; lParam == pParent; lResult == pFrame
diff --git a/vcl/inc/win/salinst.h b/vcl/inc/win/salinst.h
index b6408ea..fe2c341 100644
--- a/vcl/inc/win/salinst.h
+++ b/vcl/inc/win/salinst.h
@@ -33,14 +33,6 @@ public:
 HWNDmhComWnd;
 /// The Yield mutex ensures that only one thread calls into VCL
 SalYieldMutex*  mpSalYieldMutex;
-/// The Wait mutex ensures increment of mnYieldWaitCount and acquisition
-/// or release of mpSalYieldMutex is atomic
-osl::Mutex* mpSalWaitMutex;
-/// count main thread's pending ImplSalYieldMutexAcquireWithWait() calls
-/// (it's not clear to me if this will be > 1 in practice; it would be
-/// possible if main thread's handling of SAL_MSG_* sent by other threads
-/// via SendMessage() ends up calling ImplSalYieldMutexAcquireWithWait())
-sal_uInt16  mnYieldWaitCount;
 
 public:
 WinSalInstance();
diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx
index 40e44d2..c76fa44 100644
--- a/vcl/win/source/app/salinst.cxx
+++ b/vcl/win/source/app/salinst.cxx
@@ -111,9 +111,9 @@ LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, 
WPARAM wParam, LPARAM lPa
 
 class SalYieldMutex : public comphelper::SolarMutex
 {
-osl::Mutex m_mutex;
-
-public: // for ImplSalYield()
+public: // for ImplSalYield() and ImplSalYieldMutexAcquireWithWait()
+osl::Mutex  m_mutex;
+osl::Condition  m_condition; /// for 
MsgWaitForMultipleObjects()
 WinSalInstance* mpInstData;
 sal_uLong   mnCount;
 DWORD   mnThreadId;
@@ -149,10 +149,11 @@ void SalYieldMutex::release()
 m_mutex.release();
 else
 {
-SalData* pSalData = GetSalData();
-if ( pSalData->mnAppThreadId != nThreadId )
+bool isRelease(1 == mnCount);
+if ( isRelease )
 {
-if ( mnCount == 1 )
+SalData* pSalData = GetSalData();
+if ( pSalData->mnAppThreadId != nThreadId )
 {
 OpenGLContext::prepareForYield();
 
@@ -160,31 +161,21 @@ void SalYieldMutex::release()
 // Java clients doesn't come in the right order
 GdiFlush();
 
-// lock here to ensure that the test of mnYieldWaitCount and
-// m_mutex.release() is atomic
-mpInstData->mpSalWaitMutex->acquire();
-if ( mpInstData->mnYieldWaitCount )
-PostMessageW( mpInstData->mhComWnd, 
SAL_MSG_RELEASEWAITYIELD, 0, 0 );
 mnThreadId = 0;
-mnCount--;
-m_mutex.release();
-mpInstData->mpSalWaitMutex->release();
 }
 else
 {
-mnCount--;
-m_mutex.release();
-}
-}
-else
-{
-if ( mnCount == 1 )
-{
 mnThreadId = 0;
 OpenGLContext::prepareForYield();
 }
-mnCount--;
-m_mutex.release();
+}
+
+  

[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - vcl/inc vcl/win

2016-03-30 Thread Michael Stahl
 vcl/inc/win/salgdi.h |2 ++
 vcl/win/source/gdi/salgdi3.cxx   |   12 
 vcl/win/source/gdi/winlayout.cxx |6 ++
 3 files changed, 20 insertions(+)

New commits:
commit 4ae7ec8c8d22e751b868459e1f51fcecc37dd6b1
Author: Michael Stahl 
Date:   Thu Mar 24 22:20:06 2016 +0100

vcl: tdf#98812: acquire reference count of WinFontInstances

... when they are inserted in WinSalGraphics::mpWinFontEntry.

Not sure why one of these drops to 0 but is not removed from the
WinSalGraphics when formatting this particular bugdoc.

Acquiring the instances when retaining pointers to them should make
the life cycle a little less insane.

(cherry picked from commit 99207a26df0083851ba8e23be72d5c6974f98a3b)

Change-Id: If1404f46a13736b2a226e198bdf0c3ca8e09bb38
Reviewed-on: https://gerrit.libreoffice.org/23504
Tested-by: Jenkins 
Reviewed-by: Miklos Vajna 

diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 3d0046e..085f77e 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -220,6 +220,8 @@ private:
 sal_uIntPtr mnFontKernPairCount;// Number of Kerning Pairs of 
the current Font
 int mnPenWidth; // Linienbreite
 
+ImplFontEntry* GetWinFontEntry(int nFallbackLevel);
+
 public:
 HDC getHDC() const { return mhLocalDC; }
 void setHDC(HDC aNew) { mhLocalDC = aNew; }
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
index 499c0e5..b1f865d 100644
--- a/vcl/win/source/gdi/salgdi3.cxx
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -1532,12 +1532,23 @@ sal_uInt16 WinSalGraphics::SetFont( FontSelectPattern* 
pFont, int nFallbackLevel
 if( mhFonts[i] )
 ::DeleteFont( mhFonts[i] );
 mhFonts[ i ] = 0;
+if (mpWinFontEntry[i])
+{
+GetWinFontEntry(i)->m_pFontCache->Release(GetWinFontEntry(i));
+}
+mpWinFontEntry[i] = nullptr;
+mpWinFontData[i] = nullptr;
 }
 mhDefFont = 0;
 return 0;
 }
 
 DBG_ASSERT( pFont->mpFontData, "WinSalGraphics mpFontData==NULL");
+if (mpWinFontEntry[nFallbackLevel])
+{
+
GetWinFontEntry(nFallbackLevel)->m_pFontCache->Release(GetWinFontEntry(nFallbackLevel));
+}
+pFont->mpFontEntry->m_pFontCache->Acquire(pFont->mpFontEntry);
 mpWinFontEntry[ nFallbackLevel ] = reinterpret_cast( 
pFont->mpFontEntry );
 mpWinFontData[ nFallbackLevel ] = static_cast( 
pFont->mpFontData );
 
@@ -1560,6 +1571,7 @@ sal_uInt16 WinSalGraphics::SetFont( FontSelectPattern* 
pFont, int nFallbackLevel
 ::DeleteFont( mhFonts[i] );
 mhFonts[i] = 0;
 }
+// note: removing mpWinFontEntry[i] here has obviously bad effects
 }
 }
 
diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx
index 3b1f081..d8073fd 100644
--- a/vcl/win/source/gdi/winlayout.cxx
+++ b/vcl/win/source/gdi/winlayout.cxx
@@ -1347,6 +1347,7 @@ WinLayout::WinLayout(HDC hDC, const ImplWinFontData& 
rWFD, ImplWinFontEntry& rWF
 mrWinFontEntry(rWFE),
 mbUseOpenGL(bUseOpenGL)
 {
+assert(mrWinFontEntry.mnRefCount > 0);
 // keep mrWinFontEntry alive
 mrWinFontEntry.m_pFontCache->Acquire();
 }
@@ -4263,6 +4264,11 @@ intWinSalGraphics::GetMinKashidaWidth()
 return nMinKashida;
 }
 
+ImplFontEntry * WinSalGraphics::GetWinFontEntry(int const nFallbackLevel)
+{
+return mpWinFontEntry[nFallbackLevel];
+}
+
 ImplWinFontEntry::ImplWinFontEntry( FontSelectPattern& rFSD )
 :   ImplFontEntry( rFSD )
 ,mpGLyphyAtlas( nullptr )
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - vcl/inc vcl/win

2016-03-21 Thread Marco Cecchetti
 vcl/inc/opengl/salbmp.hxx  |1 +
 vcl/win/source/gdi/salgdi2.cxx |   12 +---
 2 files changed, 10 insertions(+), 3 deletions(-)

New commits:
commit d0cfcb6f1afe4022b322988627d8dccc9e05acc3
Author: Marco Cecchetti 
Date:   Sun Mar 20 12:23:41 2016 +0100

tdf#98324 - PNG prints as black block with OpenGL - fixed

Now the correct color palette is used.

Change-Id: Ice532091713788c7c6b380550c65e26bc4b76c74
Reviewed-on: https://gerrit.libreoffice.org/23377
Tested-by: Jenkins 
Reviewed-by: Michael Meeks 

diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index 8917a5a..15c0832 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -87,6 +87,7 @@ public:
 boolCreate( const OpenGLTexture& rTex, long nX, long nY, long 
nWidth, long nHeight );
 OpenGLTexture&  GetTexture() const;
 static rtl::Reference GetBitmapContext();
+const BitmapPalette& GetBitmapPalette() const { return maPalette; }
 
 private:
 
diff --git a/vcl/win/source/gdi/salgdi2.cxx b/vcl/win/source/gdi/salgdi2.cxx
index 6f0e5d4..6433921 100644
--- a/vcl/win/source/gdi/salgdi2.cxx
+++ b/vcl/win/source/gdi/salgdi2.cxx
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vcl/salbtype.hxx"
 #include "vcl/bmpacc.hxx"
@@ -36,7 +37,6 @@
 #include "salgdiimpl.hxx"
 #include "opengl/win/gdiimpl.hxx"
 
-
 bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const
 {
 static bool bAllowForTest(true);
@@ -76,9 +76,15 @@ namespace
 
 void convertToWinSalBitmap(SalBitmap& rSalBitmap, WinSalBitmap& rWinSalBitmap)
 {
-BitmapBuffer* pRead = rSalBitmap.AcquireBuffer(BITMAP_READ_ACCESS);
+BitmapPalette aBitmapPalette;
+OpenGLSalBitmap* pGLSalBitmap = 
dynamic_cast();
+if (pGLSalBitmap != nullptr)
+{
+aBitmapPalette = pGLSalBitmap->GetBitmapPalette();
+}
 
-rWinSalBitmap.Create(rSalBitmap.GetSize(), rSalBitmap.GetBitCount(), 
BitmapPalette());
+BitmapBuffer* pRead = rSalBitmap.AcquireBuffer(BITMAP_READ_ACCESS);
+rWinSalBitmap.Create(rSalBitmap.GetSize(), rSalBitmap.GetBitCount(), 
aBitmapPalette);
 BitmapBuffer* pWrite = 
rWinSalBitmap.AcquireBuffer(BITMAP_WRITE_ACCESS);
 
 sal_uInt8* pSource(pRead->mpBits);
___
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits


[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - vcl/inc vcl/win

2016-01-22 Thread Tor Lillqvist
 vcl/inc/win/salgdi.h |   12 
 vcl/win/source/gdi/salgdi.cxx|5 
 vcl/win/source/gdi/salgdi3.cxx   |   40 +
 vcl/win/source/gdi/winlayout.cxx |  944 +--
 vcl/win/source/gdi/winlayout.hxx |   45 +
 5 files changed, 1020 insertions(+), 26 deletions(-)

New commits:
commit bf417a38c401868bb246e846d4c697cf840771e1
Author: Tor Lillqvist 
Date:   Thu Jan 7 15:05:58 2016 +0200

tdf#96420: Re-introduce SimpleWinLayout

Fixes lots of problems with glyph layout. For instance the Cambria
case in tdf#95648. The UniscribeLayout class turned out to be much
less correct than one might have hoped.

Use OpenGL glyph caching also for SimpleWinLayout to avoid performance
decrease.

Corresponding commit in master is 4622689fad7ddff72cd08da9611ccfacdb0aa7bd

Change-Id: Ie3c00304ce58f84c7f54051f4c230b32bfc47d9f
Reviewed-on: https://gerrit.libreoffice.org/21653
Reviewed-by: Miklos Vajna 
Tested-by: Miklos Vajna 

diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index 4ff01fa..3d0046e 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -187,6 +187,7 @@ class WinSalGraphics : public SalGraphics
 friend class ScopedFont;
 friend class OpenGLCompatibleDC;
 friend class WinLayout;
+friend class SimpleWinLayout;
 friend class UniscribeLayout;
 
 protected:
@@ -214,6 +215,9 @@ private:
 RGNDATA*mpClipRgnData;  // ClipRegion-Data
 RGNDATA*mpStdClipRgnData;   // Cache 
Standard-ClipRegion-Data
 ImplFontAttrCache*  mpFontAttrCache;// Cache font attributes from 
files in so/share/fonts
+boolmbFontKernInit; // FALSE: FontKerns must be 
queried
+KERNINGPAIR*mpFontKernPairs;// Kerning Pairs of the 
current Font
+sal_uIntPtr mnFontKernPairCount;// Number of Kerning Pairs of 
the current Font
 int mnPenWidth; // Linienbreite
 
 public:
@@ -330,6 +334,12 @@ protected:
const SalBitmap* pAlphaBitmap) override;
 virtual bool   drawAlphaRect( long nX, long nY, long nWidth, long 
nHeight, sal_uInt8 nTransparency ) override;
 
+private:
+// local helpers
+
+// get kernign pairs of the current font
+sal_uLong   GetKernPairs();
+
 public:
 // public SalGraphics methods, the interface to the independent vcl part
 
@@ -451,7 +461,7 @@ voidImplGetLogFontFromFontSelect( HDC, const 
FontSelectPattern*,
 #define MAX_64KSALPOINTSsal_uInt16)0x)-8)/sizeof(POINTS))
 
 // #102411# Win's GCP mishandles kerning => we need to do it ourselves
-// kerning pairs is sorted by
+// SalGraphicsData::mpFontKernPairs is sorted by
 inline bool ImplCmpKernData( const KERNINGPAIR& a, const KERNINGPAIR& b )
 {
 if( a.wFirst < b.wFirst )
diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx
index 5f29820..42ab90e 100644
--- a/vcl/win/source/gdi/salgdi.cxx
+++ b/vcl/win/source/gdi/salgdi.cxx
@@ -631,6 +631,9 @@ WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, 
bool bScreen, HWND hW
 mhDefPal(0),
 mpStdClipRgnData(NULL),
 mpFontAttrCache(NULL),
+mpFontKernPairs(NULL),
+mnFontKernPairCount(0),
+mbFontKernInit(false),
 mnPenWidth(GSL_PEN_WIDTH)
 {
 if (OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter)
@@ -660,6 +663,8 @@ WinSalGraphics::~WinSalGraphics()
 
 // delete cache data
 delete [] (BYTE*)mpStdClipRgnData;
+
+delete [] mpFontKernPairs;
 }
 
 SalGraphicsImpl* WinSalGraphics::GetImpl() const
diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx
index 9412799..4de6530 100644
--- a/vcl/win/source/gdi/salgdi3.cxx
+++ b/vcl/win/source/gdi/salgdi3.cxx
@@ -1559,6 +1559,17 @@ sal_uInt16 WinSalGraphics::SetFont( FontSelectPattern* 
pFont, int nFallbackLevel
 if( mpWinFontData[ nFallbackLevel ] )
 mpWinFontData[ nFallbackLevel ]->UpdateFromHDC( getHDC() );
 
+if( !nFallbackLevel )
+{
+mbFontKernInit = TRUE;
+if ( mpFontKernPairs )
+{
+delete[] mpFontKernPairs;
+mpFontKernPairs = NULL;
+}
+mnFontKernPairCount = 0;
+}
+
 // some printers have higher internal resolution, so their
 // text output would be different from what we calculated
 // => suggest DrawTextArray to workaround this problem
@@ -1645,6 +1656,35 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricData* 
pMetric, int nFallbackLe
 pMetric->mnMinKashida = GetMinKashidaWidth();
 }
 
+sal_uLong WinSalGraphics::GetKernPairs()
+{
+if ( mbFontKernInit )
+{
+if( mpFontKernPairs )
+{
+delete[] mpFontKernPairs;
+mpFontKernPairs = NULL;
+}
+mnFontKernPairCount = 0;
+
+KERNINGPAIR* pPairs = NULL;
+int