Kaydet (Commit) babf6d5e authored tarafından Khaled Hosny's avatar Khaled Hosny

Drop font cache on UNX

On my system reading the ~400 fonts I have takes ~0.07 seconds, which
does not really justify all this complexity. We don’t have such cache on
other platforms as well.

It might have been slower in the past with all PFB and AFM parsing, but
this is gone already.

Killing this ugly fontmanager over engineering one piece at a time.

Change-Id: I41fe3db48dc3de0cf8939c2120403f7d243d6096
Reviewed-on: https://gerrit.libreoffice.org/31511Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarKhaled Hosny <khaledhosny@eglug.org>
üst 33f5bc54
...@@ -540,7 +540,6 @@ vcl_headless_freetype_code=\ ...@@ -540,7 +540,6 @@ vcl_headless_freetype_code=\
vcl/unx/generic/glyphs/freetype_glyphcache \ vcl/unx/generic/glyphs/freetype_glyphcache \
vcl/unx/generic/glyphs/glyphcache \ vcl/unx/generic/glyphs/glyphcache \
vcl/unx/generic/fontmanager/fontsubst \ vcl/unx/generic/fontmanager/fontsubst \
vcl/unx/generic/fontmanager/fontcache \
vcl/unx/generic/fontmanager/fontconfig \ vcl/unx/generic/fontmanager/fontconfig \
vcl/unx/generic/fontmanager/fontmanager \ vcl/unx/generic/fontmanager/fontmanager \
vcl/unx/generic/fontmanager/helper \ vcl/unx/generic/fontmanager/helper \
......
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_VCL_INC_UNX_FONTCACHE_HXX
#define INCLUDED_VCL_INC_UNX_FONTCACHE_HXX
#include <rtl/ustring.hxx>
#include <vcl/dllapi.h>
#include <unordered_map>
#include "unx/fontmanager.hxx"
namespace psp
{
class VCL_PLUGIN_PUBLIC FontCache
{
struct FontDir;
friend struct FontDir;
struct FontFile;
friend struct FontFile;
struct FontFile
{
std::list< PrintFontManager::PrintFont* > m_aEntry;
};
typedef std::unordered_map< OString, FontFile, OStringHash > FontDirMap;
struct FontDir
{
sal_Int64 m_nTimestamp;
bool m_bNoFiles;
bool m_bUserOverrideOnly;
FontDirMap m_aEntries;
FontDir() : m_nTimestamp(0), m_bNoFiles(false), m_bUserOverrideOnly( false ) {}
};
typedef std::unordered_map< int, FontDir > FontCacheData;
FontCacheData m_aCache;
OUString m_aCacheFile;
bool m_bDoFlush;
void read();
void clearCache();
static void copyPrintFont( const PrintFontManager::PrintFont* pFrom, PrintFontManager::PrintFont* pTo );
static bool equalsPrintFont( const PrintFontManager::PrintFont* pLeft, PrintFontManager::PrintFont* pRight );
static PrintFontManager::PrintFont* clonePrintFont( const PrintFontManager::PrintFont* pFont );
void createCacheDir( int nDirID );
public:
FontCache();
~FontCache();
bool getFontCacheFile( int nDirID, const OString& rFile, std::list< PrintFontManager::PrintFont* >& rNewFonts ) const;
void updateFontCacheEntry( const PrintFontManager::PrintFont*, bool bFlush );
// returns false for non cached directory
// a cached but empty directory will return true but not append anything
bool listDirectory( const OString& rDir, std::list< PrintFontManager::PrintFont* >& rNewFonts ) const;
// returns true for directories that contain only user overridden fonts
bool scanAdditionalFiles( const OString& rDir );
void flush();
};
} // namespace psp
#endif // INCLUDED_VCL_INC_UNX_FONTCACHE_HXX
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -118,17 +118,12 @@ struct CharacterMetric ...@@ -118,17 +118,12 @@ struct CharacterMetric
{ return rOther.width != width || rOther.height != height; } { return rOther.width != width || rOther.height != height; }
}; };
class FontCache;
// a class to manage printable fonts // a class to manage printable fonts
class FontCache;
class VCL_PLUGIN_PUBLIC PrintFontManager class VCL_PLUGIN_PUBLIC PrintFontManager
{ {
struct PrintFont; struct PrintFont;
friend struct PrintFont; friend struct PrintFont;
friend class FontCache;
struct PrintFont struct PrintFont
{ {
...@@ -176,8 +171,6 @@ class VCL_PLUGIN_PUBLIC PrintFontManager ...@@ -176,8 +171,6 @@ class VCL_PLUGIN_PUBLIC PrintFontManager
std::unordered_map< int, OString > m_aAtomToDir; std::unordered_map< int, OString > m_aAtomToDir;
int m_nNextDirAtom; int m_nNextDirAtom;
mutable FontCache* m_pFontCache;
OString getFontFile( PrintFont* pFont ) const; OString getFontFile( PrintFont* pFont ) const;
bool analyzeFontFile( int nDirID, const OString& rFileName, std::list< PrintFont* >& rNewFonts, const char *pFormat=nullptr ) const; bool analyzeFontFile( int nDirID, const OString& rFileName, std::list< PrintFont* >& rNewFonts, const char *pFormat=nullptr ) const;
......
This diff is collapsed.
...@@ -17,9 +17,8 @@ ...@@ -17,9 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ */
#include "unx/fontcache.hxx"
#include "impfont.hxx"
#include "unx/fontmanager.hxx" #include "unx/fontmanager.hxx"
#include "impfont.hxx"
#include <vcl/svapp.hxx> #include <vcl/svapp.hxx>
#include <vcl/sysdata.hxx> #include <vcl/sysdata.hxx>
#include <vcl/vclenum.hxx> #include <vcl/vclenum.hxx>
...@@ -555,21 +554,19 @@ void PrintFontManager::countFontconfigFonts( std::unordered_map<OString, int, OS ...@@ -555,21 +554,19 @@ void PrintFontManager::countFontconfigFonts( std::unordered_map<OString, int, OS
o_rVisitedPaths[aDir] = 1; o_rVisitedPaths[aDir] = 1;
int nDirID = getDirectoryAtom( aDir, true ); int nDirID = getDirectoryAtom( aDir, true );
if( ! m_pFontCache->getFontCacheFile( nDirID, aBase, aFonts ) )
{
#if OSL_DEBUG_LEVEL > 2 #if OSL_DEBUG_LEVEL > 2
fprintf( stderr, "file %s not cached\n", aBase.getStr() ); fprintf( stderr, "file %s not cached\n", aBase.getStr() );
#endif #endif
// not known, analyze font file to get attributes // not known, analyze font file to get attributes
// not described by fontconfig (e.g. alias names, PSName) // not described by fontconfig (e.g. alias names, PSName)
if (eFormatRes != FcResultMatch) if (eFormatRes != FcResultMatch)
format = nullptr; format = nullptr;
analyzeFontFile( nDirID, aBase, aFonts, reinterpret_cast<char*>(format) ); analyzeFontFile( nDirID, aBase, aFonts, reinterpret_cast<char*>(format) );
#if OSL_DEBUG_LEVEL > 1 #if OSL_DEBUG_LEVEL > 1
if( aFonts.empty() ) if( aFonts.empty() )
fprintf( stderr, "Warning: file \"%s\" is unusable to psprint\n", aOrgPath.getStr() ); fprintf( stderr, "Warning: file \"%s\" is unusable to psprint\n", aOrgPath.getStr() );
#endif #endif
}
if( aFonts.empty() ) if( aFonts.empty() )
{ {
//remove font, reuse index //remove font, reuse index
...@@ -636,8 +633,6 @@ void PrintFontManager::countFontconfigFonts( std::unordered_map<OString, int, OS ...@@ -636,8 +633,6 @@ void PrintFontManager::countFontconfigFonts( std::unordered_map<OString, int, OS
pUpdate->m_aStyleName = OStringToOUString( OString( reinterpret_cast<char*>(style) ), RTL_TEXTENCODING_UTF8 ); pUpdate->m_aStyleName = OStringToOUString( OString( reinterpret_cast<char*>(style) ), RTL_TEXTENCODING_UTF8 );
} }
// update font cache
m_pFontCache->updateFontCacheEntry( pUpdate, false );
// sort into known fonts // sort into known fonts
fontID aFont = m_nNextFontID++; fontID aFont = m_nNextFontID++;
m_aFonts[ aFont ] = pUpdate; m_aFonts[ aFont ] = pUpdate;
...@@ -649,15 +644,6 @@ void PrintFontManager::countFontconfigFonts( std::unordered_map<OString, int, OS ...@@ -649,15 +644,6 @@ void PrintFontManager::countFontconfigFonts( std::unordered_map<OString, int, OS
fprintf( stderr, "inserted font %s as fontID %d\n", family, aFont ); fprintf( stderr, "inserted font %s as fontID %d\n", family, aFont );
#endif #endif
} }
// clean up the fonts we did not put into the list
for( std::list< PrintFont* >::iterator it = aFonts.begin(); it != aFonts.end(); ++it )
{
if( *it != pUpdate )
{
m_pFontCache->updateFontCacheEntry( *it, false ); // prepare a cache entry for a collection item
delete *it;
}
}
} }
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "unotools/atom.hxx" #include "unotools/atom.hxx"
#include "unx/fontcache.hxx" #include "unx/fontmanager.hxx"
#include "fontsubset.hxx" #include "fontsubset.hxx"
#include "impfontcharmap.hxx" #include "impfontcharmap.hxx"
#include "svdata.hxx" #include "svdata.hxx"
...@@ -139,7 +139,6 @@ PrintFontManager::PrintFontManager() ...@@ -139,7 +139,6 @@ PrintFontManager::PrintFontManager()
: m_nNextFontID( 1 ) : m_nNextFontID( 1 )
, m_pAtoms( new MultiAtomProvider() ) , m_pAtoms( new MultiAtomProvider() )
, m_nNextDirAtom( 1 ) , m_nNextDirAtom( 1 )
, m_pFontCache( nullptr )
{ {
#if ENABLE_DBUS #if ENABLE_DBUS
m_aFontInstallerTimer.SetTimeoutHdl(LINK(this, PrintFontManager, autoInstallFontLangSupport)); m_aFontInstallerTimer.SetTimeoutHdl(LINK(this, PrintFontManager, autoInstallFontLangSupport));
...@@ -154,7 +153,6 @@ PrintFontManager::~PrintFontManager() ...@@ -154,7 +153,6 @@ PrintFontManager::~PrintFontManager()
for( std::unordered_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it ) for( std::unordered_map< fontID, PrintFont* >::const_iterator it = m_aFonts.begin(); it != m_aFonts.end(); ++it )
delete (*it).second; delete (*it).second;
delete m_pAtoms; delete m_pAtoms;
delete m_pFontCache;
} }
OString PrintFontManager::getDirectory( int nAtom ) const OString PrintFontManager::getDirectory( int nAtom ) const
...@@ -200,7 +198,6 @@ std::vector<fontID> PrintFontManager::addFontFile( const OString& rFileName ) ...@@ -200,7 +198,6 @@ std::vector<fontID> PrintFontManager::addFontFile( const OString& rFileName )
fontID nFontId = m_nNextFontID++; fontID nFontId = m_nNextFontID++;
m_aFonts[nFontId] = *it; m_aFonts[nFontId] = *it;
m_aFontFileToFontID[ aName ].insert( nFontId ); m_aFontFileToFontID[ aName ].insert( nFontId );
m_pFontCache->updateFontCacheEntry( *it, true );
aFontIds.push_back(nFontId); aFontIds.push_back(nFontId);
} }
} }
...@@ -737,21 +734,6 @@ void PrintFontManager::initialize() ...@@ -737,21 +734,6 @@ void PrintFontManager::initialize()
CALLGRIND_ZERO_STATS(); CALLGRIND_ZERO_STATS();
#endif #endif
if( ! m_pFontCache )
{
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr, "creating font cache ... " );
clock_t aStart;
struct tms tms;
aStart = times( &tms );
#endif
m_pFontCache = new FontCache();
#if OSL_DEBUG_LEVEL > 1
clock_t aStop = times( &tms );
fprintf( stderr, "done in %lf s\n", (double)(aStop - aStart)/(double)sysconf( _SC_CLK_TCK ) );
#endif
}
// initialize can be called more than once, e.g. // initialize can be called more than once, e.g.
// gtk-fontconfig-timestamp changes to reflect new font installed and // gtk-fontconfig-timestamp changes to reflect new font installed and
// PrintFontManager::initialize called again // PrintFontManager::initialize called again
...@@ -813,42 +795,6 @@ void PrintFontManager::initialize() ...@@ -813,42 +795,6 @@ void PrintFontManager::initialize()
// Don't search directories that fontconfig already did // Don't search directories that fontconfig already did
countFontconfigFonts( visited_dirs ); countFontconfigFonts( visited_dirs );
// search for font files in each path
std::list< OString >::iterator dir_it;
for( dir_it = m_aFontDirectories.begin(); dir_it != m_aFontDirectories.end(); ++dir_it )
{
OString aPath( *dir_it );
// see if we were here already
if( visited_dirs.find( aPath ) != visited_dirs.end() )
continue;
visited_dirs[ aPath ] = 1;
// there may be ":unscaled" directories (see XFree86)
// it should be safe to ignore them since they should not
// contain any of our recognizeable fonts
// ask the font cache whether it handles this directory
std::list< PrintFont* > aCacheFonts;
if( m_pFontCache->listDirectory( aPath, aCacheFonts ) )
{
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr, "adding cache directory: %s\n", aPath.getStr() );
#endif
for( ::std::list< PrintFont* >::iterator it = aCacheFonts.begin(); it != aCacheFonts.end(); ++it )
{
fontID aFont = m_nNextFontID++;
m_aFonts[ aFont ] = *it;
m_aFontFileToFontID[(*it)->m_aFontFile].insert(aFont);
#if OSL_DEBUG_LEVEL > 2
fprintf( stderr, "adding cached font %d: %s\n", aFont, getFontFileSysPath( aFont ).getStr() );
#endif
}
if( ! m_pFontCache->scanAdditionalFiles( aPath ) )
continue;
}
}
#if OSL_DEBUG_LEVEL > 1 #if OSL_DEBUG_LEVEL > 1
aStep1 = times( &tms ); aStep1 = times( &tms );
#endif #endif
...@@ -875,8 +821,6 @@ void PrintFontManager::initialize() ...@@ -875,8 +821,6 @@ void PrintFontManager::initialize()
fprintf( stderr, "Step 2 took %lf seconds\n", (double)(aStep2 - aStep1)/fTick ); fprintf( stderr, "Step 2 took %lf seconds\n", (double)(aStep2 - aStep1)/fTick );
#endif #endif
m_pFontCache->flush();
#ifdef CALLGRIND_COMPILE #ifdef CALLGRIND_COMPILE
CALLGRIND_DUMP_STATS(); CALLGRIND_DUMP_STATS();
CALLGRIND_TOGGLE_COLLECT(); CALLGRIND_TOGGLE_COLLECT();
......
...@@ -219,8 +219,6 @@ OUString const & psp::getFontPath() ...@@ -219,8 +219,6 @@ OUString const & psp::getFontPath()
{ {
aPathBuffer.append( aInstallationRootPath ); aPathBuffer.append( aInstallationRootPath );
aPathBuffer.append( "/" LIBO_SHARE_FOLDER "/fonts/truetype;"); aPathBuffer.append( "/" LIBO_SHARE_FOLDER "/fonts/truetype;");
aPathBuffer.append( aInstallationRootPath );
aPathBuffer.append( "/" LIBO_SHARE_FOLDER "/fonts/type1;" );
} }
if( !aUserPath.isEmpty() ) if( !aUserPath.isEmpty() )
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment