include/vcl/outdev.hxx | 9 +++ sd/qa/unit/data/odp/pass/test-embedded-dejavu.odp |binary vcl/inc/outdev.h | 2 vcl/source/filter/graphicfilter.cxx | 28 ++++++---- vcl/source/gdi/embeddedfontshelper.cxx | 3 - vcl/source/outdev/font.cxx | 58 +++++++++++++++++++--- 6 files changed, 79 insertions(+), 21 deletions(-)
New commits: commit 6cf58a33676cebc9f2c1d26163793ba7dce46262 Author: Caolán McNamara <caol...@redhat.com> Date: Tue Jan 20 13:21:36 2015 +0000 accidentally ran make with VALGRIND set and walked away... and found this bug triggered by CppunitTest_filter_eps_test when I got back Change-Id: I20943e5bd0fbf8aed923699dd5f1e88fada43e81 diff --git a/vcl/source/filter/graphicfilter.cxx b/vcl/source/filter/graphicfilter.cxx index 0ca4698..ebcb074 100644 --- a/vcl/source/filter/graphicfilter.cxx +++ b/vcl/source/filter/graphicfilter.cxx @@ -255,9 +255,8 @@ bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen) static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, bool bTest ) { - sal_uInt16 i; sal_uInt8 sFirstBytes[ 256 ]; - sal_uLong nFirstLong,nSecondLong; + sal_uLong nFirstLong(0), nSecondLong(0); sal_uLong nStreamPos = rStream.Tell(); rStream.Seek( STREAM_SEEK_TO_END ); @@ -274,28 +273,33 @@ static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, nStreamLen = rStream.Tell() - nStreamPos; rStream.Seek( nStreamPos ); } + if (!nStreamLen) { return false; // this prevents at least a STL assertion } else if (nStreamLen >= 256) - { // load first 256 bytes into a buffer - rStream.Read( sFirstBytes, 256 ); + { + // load first 256 bytes into a buffer + sal_uLong nRead = rStream.Read(sFirstBytes, 256); + if (nRead < 256) + nStreamLen = nRead; } else { - rStream.Read( sFirstBytes, nStreamLen ); - - for( i = (sal_uInt16) nStreamLen; i < 256; i++ ) - sFirstBytes[ i ]=0; + nStreamLen = rStream.Read(sFirstBytes, nStreamLen); } - if( rStream.GetError() ) + + if (rStream.GetError()) return false; + for (sal_uLong i = nStreamLen; i < 256; ++i) + sFirstBytes[i] = 0; + // Accommodate the first 8 bytes in nFirstLong, nSecondLong // Big-Endian: - for( i = 0, nFirstLong = 0L, nSecondLong = 0L; i < 4; i++ ) + for (int i = 0; i < 4; ++i) { nFirstLong=(nFirstLong<<8)|(sal_uLong)sFirstBytes[i]; nSecondLong=(nSecondLong<<8)|(sal_uLong)sFirstBytes[i+4]; @@ -324,7 +328,7 @@ static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, sal_uInt8 nMagic; bool bOK=true; rStream.ReadUInt16( nFieldSize ).ReadUChar( nMagic ); - for (i=0; i<3; i++) { + for (int i=0; i<3; i++) { if (nFieldSize<6) { bOK=false; break; } if (nStreamLen < rStream.Tell() + nFieldSize ) { bOK=false; break; } rStream.SeekRel(nFieldSize-3); @@ -525,7 +529,7 @@ static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, } // ASCII DXF File Format - i=0; + int i=0; while (i<256 && sFirstBytes[i]<=32) ++i; commit 40809ce46999e9cedb2fe5db8e9d53ebb6c182bf Author: Caolán McNamara <caol...@redhat.com> Date: Tue Jan 20 11:29:37 2015 +0000 move OutputDevice:: Clear/Refresh inside AddTempDevFont and drop now redundant ImplClearFontData(true); mpFontCache->Invalidate(); which is done on entry Change-Id: I217c203980e5fd6a54b85f1b1376ecc2b92181db diff --git a/vcl/source/gdi/embeddedfontshelper.cxx b/vcl/source/gdi/embeddedfontshelper.cxx index cd3e43d..037cfcf 100644 --- a/vcl/source/gdi/embeddedfontshelper.cxx +++ b/vcl/source/gdi/embeddedfontshelper.cxx @@ -181,9 +181,7 @@ OUString EmbeddedFontsHelper::fileUrlForTemporaryFont( const OUString& fontName, void EmbeddedFontsHelper::activateFont( const OUString& fontName, const OUString& fileUrl ) { OutputDevice *pDevice = Application::GetDefaultDevice(); - OutputDevice::ImplClearAllFontData(true); pDevice->AddTempDevFont(fileUrl, fontName); - OutputDevice::ImplRefreshAllFontData(true); } // Check if it's (legally) allowed to embed the font file into a document diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index 769eca7..62dcfc5 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -140,8 +140,26 @@ Size OutputDevice::GetDevFontSize( const vcl::Font& rFont, int nSizeIndex ) cons return aSize; } +namespace +{ + struct UpdateFontsGuard + { + UpdateFontsGuard() + { + OutputDevice::ImplClearAllFontData(true); + } + + ~UpdateFontsGuard() + { + OutputDevice::ImplRefreshAllFontData(true); + } + }; +} + bool OutputDevice::AddTempDevFont( const OUString& rFileURL, const OUString& rFontName ) { + UpdateFontsGuard aUpdateFontsGuard; + ImplInitFontList(); if( !mpGraphics && !AcquireGraphics() ) @@ -154,8 +172,7 @@ bool OutputDevice::AddTempDevFont( const OUString& rFileURL, const OUString& rFo if( mpAlphaVDev ) mpAlphaVDev->AddTempDevFont( rFileURL, rFontName ); - ImplClearFontData(true); - mpFontCache->Invalidate(); + OutputDevice::ImplRefreshAllFontData(true); return true; } commit 20142afafc809890d5e8dcfd4103c46319a488df Author: Caolán McNamara <caol...@redhat.com> Date: Tue Jan 20 11:24:26 2015 +0000 font cache gets broken on adding an embedded font Change-Id: I665cde5d4c89443238efb283c86277dedf621197 diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx index f8fd837..c7a2ade 100644 --- a/include/vcl/outdev.hxx +++ b/include/vcl/outdev.hxx @@ -1177,6 +1177,15 @@ public: SAL_DLLPRIVATE void ImplInitFontList() const; SAL_DLLPRIVATE void ImplUpdateFontData( bool bNewFontLists ); + + //drop font data for all outputdevices. + //If bNewFontLists is true then empty lists of system fonts + SAL_DLLPRIVATE static void ImplClearAllFontData( bool bNewFontLists ); + //fetch font data for all outputdevices + //If bNewFontLists is true then fetch lists of system fonts + SAL_DLLPRIVATE static void ImplRefreshAllFontData( bool bNewFontLists ); + //drop and fetch font data for all outputdevices + //If bNewFontLists is true then drop and refetch lists of system fonts SAL_DLLPRIVATE static void ImplUpdateAllFontData( bool bNewFontLists ); protected: diff --git a/sd/qa/unit/data/odp/pass/test-embedded-dejavu.odp b/sd/qa/unit/data/odp/pass/test-embedded-dejavu.odp new file mode 100644 index 0000000..d539e8c Binary files /dev/null and b/sd/qa/unit/data/odp/pass/test-embedded-dejavu.odp differ diff --git a/vcl/inc/outdev.h b/vcl/inc/outdev.h index bcb64f2..a1e1b85 100644 --- a/vcl/inc/outdev.h +++ b/vcl/inc/outdev.h @@ -143,6 +143,8 @@ private: typedef std::unordered_map<FontSelectPattern,ImplFontEntry*,IFSD_Hash,IFSD_Equal > FontInstanceList; FontInstanceList maFontInstanceList; + int CountUnreferencedEntries() const; + public: ImplFontCache(); ~ImplFontCache(); diff --git a/vcl/source/gdi/embeddedfontshelper.cxx b/vcl/source/gdi/embeddedfontshelper.cxx index 43485d7..cd3e43d 100644 --- a/vcl/source/gdi/embeddedfontshelper.cxx +++ b/vcl/source/gdi/embeddedfontshelper.cxx @@ -181,8 +181,9 @@ OUString EmbeddedFontsHelper::fileUrlForTemporaryFont( const OUString& fontName, void EmbeddedFontsHelper::activateFont( const OUString& fontName, const OUString& fileUrl ) { OutputDevice *pDevice = Application::GetDefaultDevice(); - pDevice->AddTempDevFont( fileUrl, fontName ); - OutputDevice::ImplUpdateAllFontData( true ); + OutputDevice::ImplClearAllFontData(true); + pDevice->AddTempDevFont(fileUrl, fontName); + OutputDevice::ImplRefreshAllFontData(true); } // Check if it's (legally) allowed to embed the font file into a document diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx index d25a533..769eca7 100644 --- a/vcl/source/outdev/font.cxx +++ b/vcl/source/outdev/font.cxx @@ -154,6 +154,7 @@ bool OutputDevice::AddTempDevFont( const OUString& rFileURL, const OUString& rFo if( mpAlphaVDev ) mpAlphaVDev->AddTempDevFont( rFileURL, rFontName ); + ImplClearFontData(true); mpFontCache->Invalidate(); return true; } @@ -571,7 +572,7 @@ void OutputDevice::ImplUpdateFontData( bool bNewFontLists ) ImplRefreshFontData( bNewFontLists ); } -void OutputDevice::ImplUpdateAllFontData( bool bNewFontLists ) +void OutputDevice::ImplClearAllFontData(bool bNewFontLists) { ImplSVData* pSVData = ImplGetSVData(); @@ -594,10 +595,19 @@ void OutputDevice::ImplUpdateAllFontData( bool bNewFontLists ) } } } +} +void OutputDevice::ImplRefreshAllFontData(bool bNewFontLists) +{ ImplUpdateFontDataForAllFrames( &OutputDevice::ImplRefreshFontData, bNewFontLists ); } +void OutputDevice::ImplUpdateAllFontData(bool bNewFontLists) +{ + OutputDevice::ImplClearAllFontData(bNewFontLists); + OutputDevice::ImplRefreshAllFontData(bNewFontLists); +} + void OutputDevice::ImplUpdateFontDataForAllFrames( const FontUpdateHandler_t pHdl, const bool bNewFontLists ) { ImplSVData* const pSVData = ImplGetSVData(); @@ -1360,11 +1370,11 @@ void ImplFontCache::Release( ImplFontEntry* pEntry ) { static const int FONTCACHE_MAX = 50; - DBG_ASSERT( (pEntry->mnRefCount > 0), "ImplFontCache::Release() - font refcount underflow" ); + assert(pEntry->mnRefCount > 0 && "ImplFontCache::Release() - font refcount underflow"); if( --pEntry->mnRefCount > 0 ) return; - if( ++mnRef0Count < FONTCACHE_MAX ) + if (++mnRef0Count < FONTCACHE_MAX) return; // remove unused entries from font instance cache @@ -1379,17 +1389,34 @@ void ImplFontCache::Release( ImplFontEntry* pEntry ) maFontInstanceList.erase( it ); delete pFontEntry; --mnRef0Count; - DBG_ASSERT( (mnRef0Count>=0), "ImplFontCache::Release() - refcount0 underflow" ); + assert(mnRef0Count>=0 && "ImplFontCache::Release() - refcount0 underflow"); if( mpFirstEntry == pFontEntry ) mpFirstEntry = NULL; } - DBG_ASSERT( (mnRef0Count==0), "ImplFontCache::Release() - refcount0 mismatch" ); + assert(mnRef0Count==0 && "ImplFontCache::Release() - refcount0 mismatch"); +} + +int ImplFontCache::CountUnreferencedEntries() const +{ + size_t nCount = 0; + // count unreferenced entries + for (FontInstanceList::const_iterator it = maFontInstanceList.begin(); + it != maFontInstanceList.end(); ++it) + { + const ImplFontEntry* pFontEntry = it->second; + if (pFontEntry->mnRefCount > 0) + continue; + ++nCount; + } + return nCount; } void ImplFontCache::Invalidate() { + assert(CountUnreferencedEntries() == mnRef0Count); + // delete unreferenced entries FontInstanceList::iterator it = maFontInstanceList.begin(); for(; it != maFontInstanceList.end(); ++it ) @@ -1406,7 +1433,7 @@ void ImplFontCache::Invalidate() mpFirstEntry = NULL; maFontInstanceList.clear(); - DBG_ASSERT( (mnRef0Count==0), "ImplFontCache::Invalidate() - mnRef0Count non-zero" ); + assert(mnRef0Count==0 && "ImplFontCache::Invalidate() - mnRef0Count non-zero"); } void OutputDevice::ImplInitFontList() const
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits