[Libreoffice-commits] core.git: 2 commits - vcl/inc vcl/Library_vcl.mk vcl/source
Chris Sherlock
chris.sherlock79 at gmail.com
Thu Jan 7 03:24:04 PST 2016
vcl/Library_vcl.mk | 3
vcl/inc/fontentry.hxx | 4
vcl/source/font/fontattributes.cxx | 348 ++++++++++++++++++++
vcl/source/font/fontcache.cxx | 366 +++++++++++++++++++++
vcl/source/font/fontentry.cxx | 134 +++++++
vcl/source/outdev/font.cxx | 641 -------------------------------------
6 files changed, 852 insertions(+), 644 deletions(-)
New commits:
commit f952a9f7139b079deb0aa8a31d1d5e2437846216
Author: Chris Sherlock <chris.sherlock79 at gmail.com>
Date: Thu Jan 7 22:09:33 2016 +1100
vcl: migrate font functions from outdev/font.cxx to own files
I have moved all ImplFontAttributes and ImplFontCache functions from
vcl/source/outdev/font.cxx to vcl/source/font/fontattributes.cxx and
vcl/source/font/fontcache.cxx accordingly.
Change-Id: I12ca80799828a772482424da171cc76bffaac43d
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 89132a5..6f24942 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -393,8 +393,10 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/font/PhysicalFontCollection \
vcl/source/font/PhysicalFontFace \
vcl/source/font/PhysicalFontFamily \
+ vcl/source/font/fontattributes \
vcl/source/font/fontselect \
vcl/source/font/fontentry \
+ vcl/source/font/fontcache \
vcl/source/fontsubset/cff \
vcl/source/fontsubset/fontsubset \
vcl/source/fontsubset/gsub \
diff --git a/vcl/source/font/fontattributes.cxx b/vcl/source/font/fontattributes.cxx
new file mode 100644
index 0000000..c27be5b
--- /dev/null
+++ b/vcl/source/font/fontattributes.cxx
@@ -0,0 +1,348 @@
+/* -*- 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 .
+ */
+
+#include "i18nlangtag/mslangid.hxx"
+
+#include <unotools/configmgr.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/print.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/sysdata.hxx>
+#include <vcl/fontcharmap.hxx>
+
+#include "sallayout.hxx"
+#include "svdata.hxx"
+
+#include "impfont.hxx"
+#include "outdata.hxx"
+#include "fontentry.hxx"
+#include "fontattributes.hxx"
+
+#include "outdev.h"
+#include "window.h"
+
+#include "PhysicalFontCollection.hxx"
+#include "PhysicalFontFace.hxx"
+#include "PhysicalFontFamily.hxx"
+
+#include "svids.hrc"
+
+#include <config_graphite.h>
+#if ENABLE_GRAPHITE
+#include "graphite_features.hxx"
+#endif
+
+#include "../gdi/pdfwriter_impl.hxx"
+
+#include <boost/functional/hash.hpp>
+#include <cmath>
+#include <cstring>
+#include <memory>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+using namespace ::utl;
+
+bool ImplFontAttributes::CompareDeviceIndependentFontAttributes(const ImplFontAttributes& rOther) const
+{
+ if (maFamilyName != rOther.maFamilyName)
+ return false;
+
+ if (maStyleName != rOther.maStyleName)
+ return false;
+
+ if (meWeight != rOther.meWeight)
+ return false;
+
+ if (meItalic != rOther.meItalic)
+ return false;
+
+ if (meFamily != rOther.meFamily)
+ return false;
+
+ if (mePitch != rOther.mePitch)
+ return false;
+
+ if (meWidthType != rOther.meWidthType)
+ return false;
+
+ if (mbSymbolFlag != rOther.mbSymbolFlag)
+ return false;
+
+ return true;
+}
+
+ImplFontAttributes::ImplFontAttributes()
+ : mnWidth ( 0 )
+ , mnOrientation( 0 )
+ , mnAscent( 0 )
+ , mnDescent( 0 )
+ , mnIntLeading( 0 )
+ , mnExtLeading( 0 )
+ , mnSlant( 0 )
+ , mnMinKashida( 0 )
+ , mbScalableFont( false )
+ , mbTrueTypeFont( false )
+ , mbKernableFont( false )
+ , mbFullstopCentered( false )
+ , mnBulletOffset( 0 )
+ , mnUnderlineSize( 0 )
+ , mnUnderlineOffset( 0 )
+ , mnBUnderlineSize( 0 )
+ , mnBUnderlineOffset( 0 )
+ , mnDUnderlineSize( 0 )
+ , mnDUnderlineOffset1( 0 )
+ , mnDUnderlineOffset2( 0 )
+ , mnWUnderlineSize( 0 )
+ , mnWUnderlineOffset( 0 )
+ , mnAboveUnderlineSize( 0 )
+ , mnAboveUnderlineOffset( 0 )
+ , mnAboveBUnderlineSize( 0 )
+ , mnAboveBUnderlineOffset( 0 )
+ , mnAboveDUnderlineSize( 0 )
+ , mnAboveDUnderlineOffset1( 0 )
+ , mnAboveDUnderlineOffset2( 0 )
+ , mnAboveWUnderlineSize( 0 )
+ , mnAboveWUnderlineOffset( 0 )
+ , mnStrikeoutSize( 0 )
+ , mnStrikeoutOffset( 0 )
+ , mnBStrikeoutSize( 0 )
+ , mnBStrikeoutOffset( 0 )
+ , mnDStrikeoutSize( 0 )
+ , mnDStrikeoutOffset1( 0 )
+ , mnDStrikeoutOffset2( 0 )
+{
+ // empty
+}
+
+ImplFontAttributes::ImplFontAttributes( const FontSelectPattern& rFontSelData )
+ : mnWidth ( rFontSelData.mnWidth )
+ , mnOrientation( (short)(rFontSelData.mnOrientation) )
+ , mnAscent( 0 )
+ , mnDescent( 0 )
+ , mnIntLeading( 0 )
+ , mnExtLeading( 0 )
+ , mnSlant( 0 )
+ , mnMinKashida( 0 )
+ , mbScalableFont( false )
+ , mbTrueTypeFont( false )
+ , mbKernableFont( false )
+ , mbFullstopCentered( false )
+ , mnBulletOffset( 0 )
+ , mnUnderlineSize( 0 )
+ , mnUnderlineOffset( 0 )
+ , mnBUnderlineSize( 0 )
+ , mnBUnderlineOffset( 0 )
+ , mnDUnderlineSize( 0 )
+ , mnDUnderlineOffset1( 0 )
+ , mnDUnderlineOffset2( 0 )
+ , mnWUnderlineSize( 0 )
+ , mnWUnderlineOffset( 0 )
+ , mnAboveUnderlineSize( 0 )
+ , mnAboveUnderlineOffset( 0 )
+ , mnAboveBUnderlineSize( 0 )
+ , mnAboveBUnderlineOffset( 0 )
+ , mnAboveDUnderlineSize( 0 )
+ , mnAboveDUnderlineOffset1( 0 )
+ , mnAboveDUnderlineOffset2( 0 )
+ , mnAboveWUnderlineSize( 0 )
+ , mnAboveWUnderlineOffset( 0 )
+ , mnStrikeoutSize( 0 )
+ , mnStrikeoutOffset( 0 )
+ , mnBStrikeoutSize( 0 )
+ , mnBStrikeoutOffset( 0 )
+ , mnDStrikeoutSize( 0 )
+ , mnDStrikeoutOffset1( 0 )
+ , mnDStrikeoutOffset2( 0 )
+{
+ // intialize the used font name
+ if( rFontSelData.mpFontData )
+ {
+ SetFamilyName( rFontSelData.mpFontData->GetFamilyName() );
+ SetStyleName( rFontSelData.mpFontData->GetStyleName() );
+ SetBuiltInFontFlag( rFontSelData.mpFontData->IsBuiltInFont() );
+ SetKernableFlag( true );
+ }
+ else
+ {
+ sal_Int32 nTokenPos = 0;
+ SetFamilyName( GetNextFontToken( rFontSelData.GetFamilyName(), nTokenPos ) );
+ SetStyleName( rFontSelData.GetStyleName() );
+ SetBuiltInFontFlag( false );
+ SetKernableFlag( false );
+ }
+}
+
+
+void ImplFontAttributes::ImplInitTextLineSize( const OutputDevice* pDev )
+{
+ long nDescent = mnDescent;
+ if ( nDescent <= 0 )
+ {
+ nDescent = mnAscent / 10;
+ if ( !nDescent )
+ nDescent = 1;
+ }
+
+ // #i55341# for some fonts it is not a good idea to calculate
+ // their text line metrics from the real font descent
+ // => work around this problem just for these fonts
+ if( 3*nDescent > mnAscent )
+ nDescent = mnAscent / 3;
+
+ long nLineHeight = ((nDescent*25)+50) / 100;
+ if ( !nLineHeight )
+ nLineHeight = 1;
+ long nLineHeight2 = nLineHeight / 2;
+ if ( !nLineHeight2 )
+ nLineHeight2 = 1;
+
+ long nBLineHeight = ((nDescent*50)+50) / 100;
+ if ( nBLineHeight == nLineHeight )
+ nBLineHeight++;
+ long nBLineHeight2 = nBLineHeight/2;
+ if ( !nBLineHeight2 )
+ nBLineHeight2 = 1;
+
+ long n2LineHeight = ((nDescent*16)+50) / 100;
+ if ( !n2LineHeight )
+ n2LineHeight = 1;
+ long n2LineDY = n2LineHeight;
+ /* #117909#
+ * add some pixels to minimum double line distance on higher resolution devices
+ */
+ long nMin2LineDY = 1 + pDev->GetDPIY()/150;
+ if ( n2LineDY < nMin2LineDY )
+ n2LineDY = nMin2LineDY;
+ long n2LineDY2 = n2LineDY/2;
+ if ( !n2LineDY2 )
+ n2LineDY2 = 1;
+
+ long nUnderlineOffset = mnDescent/2 + 1;
+ long nStrikeoutOffset = -((mnAscent - mnIntLeading) / 3);
+
+ mnUnderlineSize = nLineHeight;
+ mnUnderlineOffset = nUnderlineOffset - nLineHeight2;
+
+ mnBUnderlineSize = nBLineHeight;
+ mnBUnderlineOffset = nUnderlineOffset - nBLineHeight2;
+
+ mnDUnderlineSize = n2LineHeight;
+ mnDUnderlineOffset1 = nUnderlineOffset - n2LineDY2 - n2LineHeight;
+ mnDUnderlineOffset2 = mnDUnderlineOffset1 + n2LineDY + n2LineHeight;
+
+ long nWCalcSize = mnDescent;
+ if ( nWCalcSize < 6 )
+ {
+ if ( (nWCalcSize == 1) || (nWCalcSize == 2) )
+ mnWUnderlineSize = nWCalcSize;
+ else
+ mnWUnderlineSize = 3;
+ }
+ else
+ mnWUnderlineSize = ((nWCalcSize*50)+50) / 100;
+
+ // Don't assume that wavelines are never placed below the descent, because for most fonts the waveline
+ // is drawn into the text
+ mnWUnderlineOffset = nUnderlineOffset;
+
+ mnStrikeoutSize = nLineHeight;
+ mnStrikeoutOffset = nStrikeoutOffset - nLineHeight2;
+
+ mnBStrikeoutSize = nBLineHeight;
+ mnBStrikeoutOffset = nStrikeoutOffset - nBLineHeight2;
+
+ mnDStrikeoutSize = n2LineHeight;
+ mnDStrikeoutOffset1 = nStrikeoutOffset - n2LineDY2 - n2LineHeight;
+ mnDStrikeoutOffset2 = mnDStrikeoutOffset1 + n2LineDY + n2LineHeight;
+
+ const vcl::Font& rFont ( pDev->GetFont() );
+ bool bCentered = true;
+ if (MsLangId::isCJK(rFont.GetLanguage()))
+ {
+ const OUString sFullstop( sal_Unicode( 0x3001 ) ); // Fullwidth fullstop
+ Rectangle aRect;
+ pDev->GetTextBoundRect( aRect, sFullstop );
+ const sal_uInt16 nH = rFont.GetSize().Height();
+ const sal_uInt16 nB = aRect.Left();
+ // Use 18.75% as a threshold to define a centered fullwidth fullstop.
+ // In general, nB/nH < 5% for most Japanese fonts.
+ bCentered = nB > (((nH >> 1)+nH)>>3);
+ }
+ SetFullstopCenteredFlag( bCentered );
+
+ mnBulletOffset = ( pDev->GetTextWidth( OUString( sal_Unicode( 0x20 ) ) ) - pDev->GetTextWidth( OUString( sal_Unicode( 0xb7 ) ) ) ) >> 1 ;
+
+}
+
+void ImplFontAttributes::ImplInitAboveTextLineSize()
+{
+ long nIntLeading = mnIntLeading;
+ // TODO: assess usage of nLeading below (changed in extleading CWS)
+ // if no leading is available, we assume 15% of the ascent
+ if ( nIntLeading <= 0 )
+ {
+ nIntLeading = mnAscent*15/100;
+ if ( !nIntLeading )
+ nIntLeading = 1;
+ }
+
+ long nLineHeight = ((nIntLeading*25)+50) / 100;
+ if ( !nLineHeight )
+ nLineHeight = 1;
+
+ long nBLineHeight = ((nIntLeading*50)+50) / 100;
+ if ( nBLineHeight == nLineHeight )
+ nBLineHeight++;
+
+ long n2LineHeight = ((nIntLeading*16)+50) / 100;
+ if ( !n2LineHeight )
+ n2LineHeight = 1;
+
+ long nCeiling = -mnAscent;
+
+ mnAboveUnderlineSize = nLineHeight;
+ mnAboveUnderlineOffset = nCeiling + (nIntLeading - nLineHeight + 1) / 2;
+
+ mnAboveBUnderlineSize = nBLineHeight;
+ mnAboveBUnderlineOffset = nCeiling + (nIntLeading - nBLineHeight + 1) / 2;
+
+ mnAboveDUnderlineSize = n2LineHeight;
+ mnAboveDUnderlineOffset1 = nCeiling + (nIntLeading - 3*n2LineHeight + 1) / 2;
+ mnAboveDUnderlineOffset2 = nCeiling + (nIntLeading + n2LineHeight + 1) / 2;
+
+ long nWCalcSize = nIntLeading;
+ if ( nWCalcSize < 6 )
+ {
+ if ( (nWCalcSize == 1) || (nWCalcSize == 2) )
+ mnAboveWUnderlineSize = nWCalcSize;
+ else
+ mnAboveWUnderlineSize = 3;
+ }
+ else
+ mnAboveWUnderlineSize = ((nWCalcSize*50)+50) / 100;
+
+ mnAboveWUnderlineOffset = nCeiling + (nIntLeading + 1) / 2;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/font/fontcache.cxx b/vcl/source/font/fontcache.cxx
new file mode 100644
index 0000000..1b4b110
--- /dev/null
+++ b/vcl/source/font/fontcache.cxx
@@ -0,0 +1,366 @@
+/* -*- 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 .
+ */
+
+#include "i18nlangtag/mslangid.hxx"
+
+#include <unotools/configmgr.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/print.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/sysdata.hxx>
+#include <vcl/fontcharmap.hxx>
+
+#include "sallayout.hxx"
+#include "svdata.hxx"
+
+#include "impfont.hxx"
+#include "outdata.hxx"
+#include "fontentry.hxx"
+#include "fontattributes.hxx"
+
+#include "outdev.h"
+#include "window.h"
+
+#include "PhysicalFontCollection.hxx"
+#include "PhysicalFontFace.hxx"
+#include "PhysicalFontFamily.hxx"
+
+#include "svids.hrc"
+
+#include <config_graphite.h>
+#if ENABLE_GRAPHITE
+#include "graphite_features.hxx"
+#endif
+
+#include "../gdi/pdfwriter_impl.hxx"
+
+#include <boost/functional/hash.hpp>
+#include <cmath>
+#include <cstring>
+#include <memory>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+using namespace ::utl;
+
+size_t ImplFontCache::IFSD_Hash::operator()( const FontSelectPattern& rFSD ) const
+{
+ return rFSD.hashCode();
+}
+
+bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const FontSelectPattern& rB) const
+{
+ // check normalized font family name
+ if( rA.maSearchName != rB.maSearchName )
+ return false;
+
+ // check font transformation
+ if( (rA.mnHeight != rB.mnHeight)
+ || (rA.mnWidth != rB.mnWidth)
+ || (rA.mnOrientation != rB.mnOrientation) )
+ return false;
+
+ // check mapping relevant attributes
+ if( (rA.mbVertical != rB.mbVertical)
+ || (rA.meLanguage != rB.meLanguage) )
+ return false;
+
+ // check font face attributes
+ if( (rA.GetWeight() != rB.GetWeight())
+ || (rA.GetSlantType() != rB.GetSlantType())
+// || (rA.meFamily != rB.meFamily) // TODO: remove this mostly obsolete member
+ || (rA.GetPitch() != rB.GetPitch()) )
+ return false;
+
+ // check style name
+ if( rA.GetStyleName() != rB.GetStyleName() )
+ return false;
+
+ // Symbol fonts may recode from one type to another So they are only
+ // safely equivalent for equal targets
+ if (
+ (rA.mpFontData && rA.mpFontData->IsSymbolFont()) ||
+ (rB.mpFontData && rB.mpFontData->IsSymbolFont())
+ )
+ {
+ if (rA.maTargetName != rB.maTargetName)
+ return false;
+ }
+
+#if ENABLE_GRAPHITE
+ // check for features
+ if ((rA.maTargetName.indexOf(grutils::GrFeatureParser::FEAT_PREFIX)
+ != -1 ||
+ rB.maTargetName.indexOf(grutils::GrFeatureParser::FEAT_PREFIX)
+ != -1) && rA.maTargetName != rB.maTargetName)
+ return false;
+#endif
+
+ if (rA.mbEmbolden != rB.mbEmbolden)
+ return false;
+
+ if (rA.maItalicMatrix != rB.maItalicMatrix)
+ return false;
+
+ return true;
+}
+
+ImplFontCache::ImplFontCache()
+: mpFirstEntry( nullptr ),
+ mnRef0Count( 0 )
+{}
+
+ImplFontCache::~ImplFontCache()
+{
+ FontInstanceList::iterator it = maFontInstanceList.begin();
+ for(; it != maFontInstanceList.end(); ++it )
+ {
+ ImplFontEntry* pEntry = (*it).second;
+ delete pEntry;
+ }
+}
+
+ImplFontEntry* ImplFontCache::GetFontEntry( PhysicalFontCollection* pFontList,
+ const vcl::Font& rFont, const Size& rSize, float fExactHeight )
+{
+ OUString aSearchName = rFont.GetName();
+
+ // initialize internal font request object
+ FontSelectPattern aFontSelData( rFont, aSearchName, rSize, fExactHeight );
+ return GetFontEntry( pFontList, aFontSelData );
+}
+
+ImplFontEntry* ImplFontCache::GetFontEntry( PhysicalFontCollection* pFontList,
+ FontSelectPattern& aFontSelData )
+{
+ // check if a directly matching logical font instance is already cached,
+ // the most recently used font usually has a hit rate of >50%
+ ImplFontEntry *pEntry = nullptr;
+ PhysicalFontFamily* pFontFamily = nullptr;
+ IFSD_Equal aIFSD_Equal;
+ if( mpFirstEntry && aIFSD_Equal( aFontSelData, mpFirstEntry->maFontSelData ) )
+ pEntry = mpFirstEntry;
+ else
+ {
+ FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
+ if( it != maFontInstanceList.end() )
+ pEntry = (*it).second;
+ }
+
+ if( !pEntry ) // no direct cache hit
+ {
+ // find the best matching logical font family and update font selector accordingly
+ pFontFamily = pFontList->FindFontFamilyByFont( aFontSelData );
+ DBG_ASSERT( (pFontFamily != nullptr), "ImplFontCache::Get() No logical font found!" );
+ if( pFontFamily )
+ aFontSelData.maSearchName = pFontFamily->GetSearchName();
+
+ // check if an indirectly matching logical font instance is already cached
+ FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
+ if( it != maFontInstanceList.end() )
+ {
+ // we have an indirect cache hit
+ pEntry = (*it).second;
+ }
+ }
+
+ PhysicalFontFace* pFontData = nullptr;
+
+ if (!pEntry && pFontFamily)// no cache hit => find the best matching physical font face
+ {
+ bool bOrigWasSymbol = aFontSelData.mpFontData && aFontSelData.mpFontData->IsSymbolFont();
+ pFontData = pFontFamily->FindBestFontFace( aFontSelData );
+ aFontSelData.mpFontData = pFontData;
+ bool bNewIsSymbol = aFontSelData.mpFontData && aFontSelData.mpFontData->IsSymbolFont();
+
+ if (bNewIsSymbol != bOrigWasSymbol)
+ {
+ // it is possible, though generally unlikely, that at this point we
+ // will attempt to use a symbol font as a last-ditch fallback for a
+ // non-symbol font request or vice versa, and by changing
+ // aFontSelData.mpFontData to/from a symbol font we may now find
+ // something in the cache that can be reused which previously
+ // wasn't a candidate
+ FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
+ if( it != maFontInstanceList.end() )
+ pEntry = (*it).second;
+ }
+ }
+
+ if( pEntry ) // cache hit => use existing font instance
+ {
+ // increase the font instance's reference count
+ Acquire(pEntry);
+ }
+
+ if (!pEntry && pFontData)// still no cache hit => create a new font instance
+ {
+ // create a new logical font instance from this physical font face
+ pEntry = pFontData->CreateFontInstance( aFontSelData );
+ pEntry->m_pFontCache = this;
+
+ // if we're subtituting from or to a symbol font we may need a symbol
+ // conversion table
+ if( pFontData->IsSymbolFont() || aFontSelData.IsSymbolFont() )
+ {
+ if( aFontSelData.maTargetName != aFontSelData.maSearchName )
+ pEntry->mpConversion = ConvertChar::GetRecodeData( aFontSelData.maTargetName, aFontSelData.maSearchName );
+ }
+
+#ifdef MACOSX
+ //It might be better to dig out the font version of the target font
+ //to see if it's a modern re-coded apple symbol font in case that
+ //font shows up on a different platform
+ if (!pEntry->mpConversion &&
+ aFontSelData.maTargetName.equalsIgnoreAsciiCase("symbol") &&
+ aFontSelData.maSearchName.equalsIgnoreAsciiCase("symbol"))
+ {
+ pEntry->mpConversion = ConvertChar::GetRecodeData( "Symbol", "AppleSymbol" );
+ }
+#endif
+
+ // add the new entry to the cache
+ maFontInstanceList[ aFontSelData ] = pEntry;
+ }
+
+ mpFirstEntry = pEntry;
+ return pEntry;
+}
+
+ImplFontEntry* ImplFontCache::GetGlyphFallbackFont( PhysicalFontCollection* pFontCollection,
+ FontSelectPattern& rFontSelData, int nFallbackLevel, OUString& rMissingCodes )
+{
+ // get a candidate font for glyph fallback
+ // unless the previously selected font got a device specific substitution
+ // e.g. PsPrint Arial->Helvetica for udiaeresis when Helvetica doesn't support it
+ if( nFallbackLevel >= 1)
+ {
+ PhysicalFontFamily* pFallbackData = nullptr;
+
+ //fdo#33898 If someone has EUDC installed then they really want that to
+ //be used as the first-choice glyph fallback seeing as it's filled with
+ //private area codes with don't make any sense in any other font so
+ //prioritise it here if it's available. Ideally we would remove from
+ //rMissingCodes all the glyphs which it is able to resolve as an
+ //optimization, but that's tricky to achieve cross-platform without
+ //sufficient heavy-weight code that's likely to undo the value of the
+ //optimization
+ if (nFallbackLevel == 1)
+ pFallbackData = pFontCollection->FindFontFamily("EUDC");
+ if (!pFallbackData)
+ pFallbackData = pFontCollection->GetGlyphFallbackFont(rFontSelData, rMissingCodes, nFallbackLevel-1);
+ // escape when there are no font candidates
+ if( !pFallbackData )
+ return nullptr;
+ // override the font name
+ rFontSelData.SetFamilyName( pFallbackData->GetFamilyName() );
+ // clear the cached normalized name
+ rFontSelData.maSearchName.clear();
+ }
+
+ ImplFontEntry* pFallbackFont = GetFontEntry( pFontCollection, rFontSelData );
+ return pFallbackFont;
+}
+
+void ImplFontCache::Acquire(ImplFontEntry* pEntry)
+{
+ assert(pEntry->m_pFontCache == this);
+
+ if (0 == pEntry->mnRefCount++)
+ --mnRef0Count;
+}
+
+void ImplFontCache::Release(ImplFontEntry* pEntry)
+{
+ static const int FONTCACHE_MAX = getenv("LO_TESTNAME") ? 1 : 50;
+
+ assert(pEntry->mnRefCount > 0 && "ImplFontCache::Release() - font refcount underflow");
+ if( --pEntry->mnRefCount > 0 )
+ return;
+
+ if (++mnRef0Count < FONTCACHE_MAX)
+ return;
+
+ assert(CountUnreferencedEntries() == mnRef0Count);
+
+ // remove unused entries from font instance cache
+ FontInstanceList::iterator it_next = maFontInstanceList.begin();
+ while( it_next != maFontInstanceList.end() )
+ {
+ FontInstanceList::iterator it = it_next++;
+ ImplFontEntry* pFontEntry = (*it).second;
+ if( pFontEntry->mnRefCount > 0 )
+ continue;
+
+ maFontInstanceList.erase( it );
+ delete pFontEntry;
+ --mnRef0Count;
+ assert(mnRef0Count>=0 && "ImplFontCache::Release() - refcount0 underflow");
+
+ if( mpFirstEntry == pFontEntry )
+ mpFirstEntry = nullptr;
+ }
+
+ 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 )
+ {
+ ImplFontEntry* pFontEntry = (*it).second;
+ if( pFontEntry->mnRefCount > 0 )
+ continue;
+
+ delete pFontEntry;
+ --mnRef0Count;
+ }
+
+ // #112304# make sure the font cache is really clean
+ mpFirstEntry = nullptr;
+ maFontInstanceList.clear();
+
+ assert(mnRef0Count==0 && "ImplFontCache::Invalidate() - mnRef0Count non-zero");
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 4593900..6a0faa9 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -1011,305 +1011,6 @@ FontSelectPatternAttributes::FontSelectPatternAttributes( const vcl::Font& rFont
mnWidth = -mnWidth;
}
-size_t ImplFontCache::IFSD_Hash::operator()( const FontSelectPattern& rFSD ) const
-{
- return rFSD.hashCode();
-}
-
-bool ImplFontCache::IFSD_Equal::operator()(const FontSelectPattern& rA, const FontSelectPattern& rB) const
-{
- // check normalized font family name
- if( rA.maSearchName != rB.maSearchName )
- return false;
-
- // check font transformation
- if( (rA.mnHeight != rB.mnHeight)
- || (rA.mnWidth != rB.mnWidth)
- || (rA.mnOrientation != rB.mnOrientation) )
- return false;
-
- // check mapping relevant attributes
- if( (rA.mbVertical != rB.mbVertical)
- || (rA.meLanguage != rB.meLanguage) )
- return false;
-
- // check font face attributes
- if( (rA.GetWeight() != rB.GetWeight())
- || (rA.GetSlantType() != rB.GetSlantType())
-// || (rA.meFamily != rB.meFamily) // TODO: remove this mostly obsolete member
- || (rA.GetPitch() != rB.GetPitch()) )
- return false;
-
- // check style name
- if( rA.GetStyleName() != rB.GetStyleName() )
- return false;
-
- // Symbol fonts may recode from one type to another So they are only
- // safely equivalent for equal targets
- if (
- (rA.mpFontData && rA.mpFontData->IsSymbolFont()) ||
- (rB.mpFontData && rB.mpFontData->IsSymbolFont())
- )
- {
- if (rA.maTargetName != rB.maTargetName)
- return false;
- }
-
-#if ENABLE_GRAPHITE
- // check for features
- if ((rA.maTargetName.indexOf(grutils::GrFeatureParser::FEAT_PREFIX)
- != -1 ||
- rB.maTargetName.indexOf(grutils::GrFeatureParser::FEAT_PREFIX)
- != -1) && rA.maTargetName != rB.maTargetName)
- return false;
-#endif
-
- if (rA.mbEmbolden != rB.mbEmbolden)
- return false;
-
- if (rA.maItalicMatrix != rB.maItalicMatrix)
- return false;
-
- return true;
-}
-
-ImplFontCache::ImplFontCache()
-: mpFirstEntry( nullptr ),
- mnRef0Count( 0 )
-{}
-
-ImplFontCache::~ImplFontCache()
-{
- FontInstanceList::iterator it = maFontInstanceList.begin();
- for(; it != maFontInstanceList.end(); ++it )
- {
- ImplFontEntry* pEntry = (*it).second;
- delete pEntry;
- }
-}
-
-ImplFontEntry* ImplFontCache::GetFontEntry( PhysicalFontCollection* pFontList,
- const vcl::Font& rFont, const Size& rSize, float fExactHeight )
-{
- OUString aSearchName = rFont.GetName();
-
- // initialize internal font request object
- FontSelectPattern aFontSelData( rFont, aSearchName, rSize, fExactHeight );
- return GetFontEntry( pFontList, aFontSelData );
-}
-
-ImplFontEntry* ImplFontCache::GetFontEntry( PhysicalFontCollection* pFontList,
- FontSelectPattern& aFontSelData )
-{
- // check if a directly matching logical font instance is already cached,
- // the most recently used font usually has a hit rate of >50%
- ImplFontEntry *pEntry = nullptr;
- PhysicalFontFamily* pFontFamily = nullptr;
- IFSD_Equal aIFSD_Equal;
- if( mpFirstEntry && aIFSD_Equal( aFontSelData, mpFirstEntry->maFontSelData ) )
- pEntry = mpFirstEntry;
- else
- {
- FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
- if( it != maFontInstanceList.end() )
- pEntry = (*it).second;
- }
-
- if( !pEntry ) // no direct cache hit
- {
- // find the best matching logical font family and update font selector accordingly
- pFontFamily = pFontList->FindFontFamilyByFont( aFontSelData );
- DBG_ASSERT( (pFontFamily != nullptr), "ImplFontCache::Get() No logical font found!" );
- if( pFontFamily )
- aFontSelData.maSearchName = pFontFamily->GetSearchName();
-
- // check if an indirectly matching logical font instance is already cached
- FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
- if( it != maFontInstanceList.end() )
- {
- // we have an indirect cache hit
- pEntry = (*it).second;
- }
- }
-
- PhysicalFontFace* pFontData = nullptr;
-
- if (!pEntry && pFontFamily)// no cache hit => find the best matching physical font face
- {
- bool bOrigWasSymbol = aFontSelData.mpFontData && aFontSelData.mpFontData->IsSymbolFont();
- pFontData = pFontFamily->FindBestFontFace( aFontSelData );
- aFontSelData.mpFontData = pFontData;
- bool bNewIsSymbol = aFontSelData.mpFontData && aFontSelData.mpFontData->IsSymbolFont();
-
- if (bNewIsSymbol != bOrigWasSymbol)
- {
- // it is possible, though generally unlikely, that at this point we
- // will attempt to use a symbol font as a last-ditch fallback for a
- // non-symbol font request or vice versa, and by changing
- // aFontSelData.mpFontData to/from a symbol font we may now find
- // something in the cache that can be reused which previously
- // wasn't a candidate
- FontInstanceList::iterator it = maFontInstanceList.find( aFontSelData );
- if( it != maFontInstanceList.end() )
- pEntry = (*it).second;
- }
- }
-
- if( pEntry ) // cache hit => use existing font instance
- {
- // increase the font instance's reference count
- Acquire(pEntry);
- }
-
- if (!pEntry && pFontData)// still no cache hit => create a new font instance
- {
- // create a new logical font instance from this physical font face
- pEntry = pFontData->CreateFontInstance( aFontSelData );
- pEntry->m_pFontCache = this;
-
- // if we're subtituting from or to a symbol font we may need a symbol
- // conversion table
- if( pFontData->IsSymbolFont() || aFontSelData.IsSymbolFont() )
- {
- if( aFontSelData.maTargetName != aFontSelData.maSearchName )
- pEntry->mpConversion = ConvertChar::GetRecodeData( aFontSelData.maTargetName, aFontSelData.maSearchName );
- }
-
-#ifdef MACOSX
- //It might be better to dig out the font version of the target font
- //to see if it's a modern re-coded apple symbol font in case that
- //font shows up on a different platform
- if (!pEntry->mpConversion &&
- aFontSelData.maTargetName.equalsIgnoreAsciiCase("symbol") &&
- aFontSelData.maSearchName.equalsIgnoreAsciiCase("symbol"))
- {
- pEntry->mpConversion = ConvertChar::GetRecodeData( "Symbol", "AppleSymbol" );
- }
-#endif
-
- // add the new entry to the cache
- maFontInstanceList[ aFontSelData ] = pEntry;
- }
-
- mpFirstEntry = pEntry;
- return pEntry;
-}
-
-ImplFontEntry* ImplFontCache::GetGlyphFallbackFont( PhysicalFontCollection* pFontCollection,
- FontSelectPattern& rFontSelData, int nFallbackLevel, OUString& rMissingCodes )
-{
- // get a candidate font for glyph fallback
- // unless the previously selected font got a device specific substitution
- // e.g. PsPrint Arial->Helvetica for udiaeresis when Helvetica doesn't support it
- if( nFallbackLevel >= 1)
- {
- PhysicalFontFamily* pFallbackData = nullptr;
-
- //fdo#33898 If someone has EUDC installed then they really want that to
- //be used as the first-choice glyph fallback seeing as it's filled with
- //private area codes with don't make any sense in any other font so
- //prioritise it here if it's available. Ideally we would remove from
- //rMissingCodes all the glyphs which it is able to resolve as an
- //optimization, but that's tricky to achieve cross-platform without
- //sufficient heavy-weight code that's likely to undo the value of the
- //optimization
- if (nFallbackLevel == 1)
- pFallbackData = pFontCollection->FindFontFamily("EUDC");
- if (!pFallbackData)
- pFallbackData = pFontCollection->GetGlyphFallbackFont(rFontSelData, rMissingCodes, nFallbackLevel-1);
- // escape when there are no font candidates
- if( !pFallbackData )
- return nullptr;
- // override the font name
- rFontSelData.SetFamilyName( pFallbackData->GetFamilyName() );
- // clear the cached normalized name
- rFontSelData.maSearchName.clear();
- }
-
- ImplFontEntry* pFallbackFont = GetFontEntry( pFontCollection, rFontSelData );
- return pFallbackFont;
-}
-
-void ImplFontCache::Acquire(ImplFontEntry* pEntry)
-{
- assert(pEntry->m_pFontCache == this);
-
- if (0 == pEntry->mnRefCount++)
- --mnRef0Count;
-}
-
-void ImplFontCache::Release(ImplFontEntry* pEntry)
-{
- static const int FONTCACHE_MAX = getenv("LO_TESTNAME") ? 1 : 50;
-
- assert(pEntry->mnRefCount > 0 && "ImplFontCache::Release() - font refcount underflow");
- if( --pEntry->mnRefCount > 0 )
- return;
-
- if (++mnRef0Count < FONTCACHE_MAX)
- return;
-
- assert(CountUnreferencedEntries() == mnRef0Count);
-
- // remove unused entries from font instance cache
- FontInstanceList::iterator it_next = maFontInstanceList.begin();
- while( it_next != maFontInstanceList.end() )
- {
- FontInstanceList::iterator it = it_next++;
- ImplFontEntry* pFontEntry = (*it).second;
- if( pFontEntry->mnRefCount > 0 )
- continue;
-
- maFontInstanceList.erase( it );
- delete pFontEntry;
- --mnRef0Count;
- assert(mnRef0Count>=0 && "ImplFontCache::Release() - refcount0 underflow");
-
- if( mpFirstEntry == pFontEntry )
- mpFirstEntry = nullptr;
- }
-
- 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 )
- {
- ImplFontEntry* pFontEntry = (*it).second;
- if( pFontEntry->mnRefCount > 0 )
- continue;
-
- delete pFontEntry;
- --mnRef0Count;
- }
-
- // #112304# make sure the font cache is really clean
- mpFirstEntry = nullptr;
- maFontInstanceList.clear();
-
- assert(mnRef0Count==0 && "ImplFontCache::Invalidate() - mnRef0Count non-zero");
-}
-
void OutputDevice::ImplInitFontList() const
{
if( !mpFontCollection->Count() )
@@ -1545,288 +1246,6 @@ void OutputDevice::SetFontOrientation( ImplFontEntry* const pFontEntry ) const
}
}
-bool ImplFontAttributes::CompareDeviceIndependentFontAttributes(const ImplFontAttributes& rOther) const
-{
- if (maFamilyName != rOther.maFamilyName)
- return false;
-
- if (maStyleName != rOther.maStyleName)
- return false;
-
- if (meWeight != rOther.meWeight)
- return false;
-
- if (meItalic != rOther.meItalic)
- return false;
-
- if (meFamily != rOther.meFamily)
- return false;
-
- if (mePitch != rOther.mePitch)
- return false;
-
- if (meWidthType != rOther.meWidthType)
- return false;
-
- if (mbSymbolFlag != rOther.mbSymbolFlag)
- return false;
-
- return true;
-}
-
-ImplFontAttributes::ImplFontAttributes()
- : mnWidth ( 0 )
- , mnOrientation( 0 )
- , mnAscent( 0 )
- , mnDescent( 0 )
- , mnIntLeading( 0 )
- , mnExtLeading( 0 )
- , mnSlant( 0 )
- , mnMinKashida( 0 )
- , mbScalableFont( false )
- , mbTrueTypeFont( false )
- , mbKernableFont( false )
- , mbFullstopCentered( false )
- , mnBulletOffset( 0 )
- , mnUnderlineSize( 0 )
- , mnUnderlineOffset( 0 )
- , mnBUnderlineSize( 0 )
- , mnBUnderlineOffset( 0 )
- , mnDUnderlineSize( 0 )
- , mnDUnderlineOffset1( 0 )
- , mnDUnderlineOffset2( 0 )
- , mnWUnderlineSize( 0 )
- , mnWUnderlineOffset( 0 )
- , mnAboveUnderlineSize( 0 )
- , mnAboveUnderlineOffset( 0 )
- , mnAboveBUnderlineSize( 0 )
- , mnAboveBUnderlineOffset( 0 )
- , mnAboveDUnderlineSize( 0 )
- , mnAboveDUnderlineOffset1( 0 )
- , mnAboveDUnderlineOffset2( 0 )
- , mnAboveWUnderlineSize( 0 )
- , mnAboveWUnderlineOffset( 0 )
- , mnStrikeoutSize( 0 )
- , mnStrikeoutOffset( 0 )
- , mnBStrikeoutSize( 0 )
- , mnBStrikeoutOffset( 0 )
- , mnDStrikeoutSize( 0 )
- , mnDStrikeoutOffset1( 0 )
- , mnDStrikeoutOffset2( 0 )
-{
- // empty
-}
-
-ImplFontAttributes::ImplFontAttributes( const FontSelectPattern& rFontSelData )
- : mnWidth ( rFontSelData.mnWidth )
- , mnOrientation( (short)(rFontSelData.mnOrientation) )
- , mnAscent( 0 )
- , mnDescent( 0 )
- , mnIntLeading( 0 )
- , mnExtLeading( 0 )
- , mnSlant( 0 )
- , mnMinKashida( 0 )
- , mbScalableFont( false )
- , mbTrueTypeFont( false )
- , mbKernableFont( false )
- , mbFullstopCentered( false )
- , mnBulletOffset( 0 )
- , mnUnderlineSize( 0 )
- , mnUnderlineOffset( 0 )
- , mnBUnderlineSize( 0 )
- , mnBUnderlineOffset( 0 )
- , mnDUnderlineSize( 0 )
- , mnDUnderlineOffset1( 0 )
- , mnDUnderlineOffset2( 0 )
- , mnWUnderlineSize( 0 )
- , mnWUnderlineOffset( 0 )
- , mnAboveUnderlineSize( 0 )
- , mnAboveUnderlineOffset( 0 )
- , mnAboveBUnderlineSize( 0 )
- , mnAboveBUnderlineOffset( 0 )
- , mnAboveDUnderlineSize( 0 )
- , mnAboveDUnderlineOffset1( 0 )
- , mnAboveDUnderlineOffset2( 0 )
- , mnAboveWUnderlineSize( 0 )
- , mnAboveWUnderlineOffset( 0 )
- , mnStrikeoutSize( 0 )
- , mnStrikeoutOffset( 0 )
- , mnBStrikeoutSize( 0 )
- , mnBStrikeoutOffset( 0 )
- , mnDStrikeoutSize( 0 )
- , mnDStrikeoutOffset1( 0 )
- , mnDStrikeoutOffset2( 0 )
-{
- // intialize the used font name
- if( rFontSelData.mpFontData )
- {
- SetFamilyName( rFontSelData.mpFontData->GetFamilyName() );
- SetStyleName( rFontSelData.mpFontData->GetStyleName() );
- SetBuiltInFontFlag( rFontSelData.mpFontData->IsBuiltInFont() );
- SetKernableFlag( true );
- }
- else
- {
- sal_Int32 nTokenPos = 0;
- SetFamilyName( GetNextFontToken( rFontSelData.GetFamilyName(), nTokenPos ) );
- SetStyleName( rFontSelData.GetStyleName() );
- SetBuiltInFontFlag( false );
- SetKernableFlag( false );
- }
-}
-
-
-void ImplFontAttributes::ImplInitTextLineSize( const OutputDevice* pDev )
-{
- long nDescent = mnDescent;
- if ( nDescent <= 0 )
- {
- nDescent = mnAscent / 10;
- if ( !nDescent )
- nDescent = 1;
- }
-
- // #i55341# for some fonts it is not a good idea to calculate
- // their text line metrics from the real font descent
- // => work around this problem just for these fonts
- if( 3*nDescent > mnAscent )
- nDescent = mnAscent / 3;
-
- long nLineHeight = ((nDescent*25)+50) / 100;
- if ( !nLineHeight )
- nLineHeight = 1;
- long nLineHeight2 = nLineHeight / 2;
- if ( !nLineHeight2 )
- nLineHeight2 = 1;
-
- long nBLineHeight = ((nDescent*50)+50) / 100;
- if ( nBLineHeight == nLineHeight )
- nBLineHeight++;
- long nBLineHeight2 = nBLineHeight/2;
- if ( !nBLineHeight2 )
- nBLineHeight2 = 1;
-
- long n2LineHeight = ((nDescent*16)+50) / 100;
- if ( !n2LineHeight )
- n2LineHeight = 1;
- long n2LineDY = n2LineHeight;
- /* #117909#
- * add some pixels to minimum double line distance on higher resolution devices
- */
- long nMin2LineDY = 1 + pDev->GetDPIY()/150;
- if ( n2LineDY < nMin2LineDY )
- n2LineDY = nMin2LineDY;
- long n2LineDY2 = n2LineDY/2;
- if ( !n2LineDY2 )
- n2LineDY2 = 1;
-
- long nUnderlineOffset = mnDescent/2 + 1;
- long nStrikeoutOffset = -((mnAscent - mnIntLeading) / 3);
-
- mnUnderlineSize = nLineHeight;
- mnUnderlineOffset = nUnderlineOffset - nLineHeight2;
-
- mnBUnderlineSize = nBLineHeight;
- mnBUnderlineOffset = nUnderlineOffset - nBLineHeight2;
-
- mnDUnderlineSize = n2LineHeight;
- mnDUnderlineOffset1 = nUnderlineOffset - n2LineDY2 - n2LineHeight;
- mnDUnderlineOffset2 = mnDUnderlineOffset1 + n2LineDY + n2LineHeight;
-
- long nWCalcSize = mnDescent;
- if ( nWCalcSize < 6 )
- {
- if ( (nWCalcSize == 1) || (nWCalcSize == 2) )
- mnWUnderlineSize = nWCalcSize;
- else
- mnWUnderlineSize = 3;
- }
- else
- mnWUnderlineSize = ((nWCalcSize*50)+50) / 100;
-
- // Don't assume that wavelines are never placed below the descent, because for most fonts the waveline
- // is drawn into the text
- mnWUnderlineOffset = nUnderlineOffset;
-
- mnStrikeoutSize = nLineHeight;
- mnStrikeoutOffset = nStrikeoutOffset - nLineHeight2;
-
- mnBStrikeoutSize = nBLineHeight;
- mnBStrikeoutOffset = nStrikeoutOffset - nBLineHeight2;
-
- mnDStrikeoutSize = n2LineHeight;
- mnDStrikeoutOffset1 = nStrikeoutOffset - n2LineDY2 - n2LineHeight;
- mnDStrikeoutOffset2 = mnDStrikeoutOffset1 + n2LineDY + n2LineHeight;
-
- const vcl::Font& rFont ( pDev->GetFont() );
- bool bCentered = true;
- if (MsLangId::isCJK(rFont.GetLanguage()))
- {
- const OUString sFullstop( sal_Unicode( 0x3001 ) ); // Fullwidth fullstop
- Rectangle aRect;
- pDev->GetTextBoundRect( aRect, sFullstop );
- const sal_uInt16 nH = rFont.GetSize().Height();
- const sal_uInt16 nB = aRect.Left();
- // Use 18.75% as a threshold to define a centered fullwidth fullstop.
- // In general, nB/nH < 5% for most Japanese fonts.
- bCentered = nB > (((nH >> 1)+nH)>>3);
- }
- SetFullstopCenteredFlag( bCentered );
-
- mnBulletOffset = ( pDev->GetTextWidth( OUString( sal_Unicode( 0x20 ) ) ) - pDev->GetTextWidth( OUString( sal_Unicode( 0xb7 ) ) ) ) >> 1 ;
-
-}
-
-void ImplFontAttributes::ImplInitAboveTextLineSize()
-{
- long nIntLeading = mnIntLeading;
- // TODO: assess usage of nLeading below (changed in extleading CWS)
- // if no leading is available, we assume 15% of the ascent
- if ( nIntLeading <= 0 )
- {
- nIntLeading = mnAscent*15/100;
- if ( !nIntLeading )
- nIntLeading = 1;
- }
-
- long nLineHeight = ((nIntLeading*25)+50) / 100;
- if ( !nLineHeight )
- nLineHeight = 1;
-
- long nBLineHeight = ((nIntLeading*50)+50) / 100;
- if ( nBLineHeight == nLineHeight )
- nBLineHeight++;
-
- long n2LineHeight = ((nIntLeading*16)+50) / 100;
- if ( !n2LineHeight )
- n2LineHeight = 1;
-
- long nCeiling = -mnAscent;
-
- mnAboveUnderlineSize = nLineHeight;
- mnAboveUnderlineOffset = nCeiling + (nIntLeading - nLineHeight + 1) / 2;
-
- mnAboveBUnderlineSize = nBLineHeight;
- mnAboveBUnderlineOffset = nCeiling + (nIntLeading - nBLineHeight + 1) / 2;
-
- mnAboveDUnderlineSize = n2LineHeight;
- mnAboveDUnderlineOffset1 = nCeiling + (nIntLeading - 3*n2LineHeight + 1) / 2;
- mnAboveDUnderlineOffset2 = nCeiling + (nIntLeading + n2LineHeight + 1) / 2;
-
- long nWCalcSize = nIntLeading;
- if ( nWCalcSize < 6 )
- {
- if ( (nWCalcSize == 1) || (nWCalcSize == 2) )
- mnAboveWUnderlineSize = nWCalcSize;
- else
- mnAboveWUnderlineSize = 3;
- }
- else
- mnAboveWUnderlineSize = ((nWCalcSize*50)+50) / 100;
-
- mnAboveWUnderlineOffset = nCeiling + (nIntLeading + 1) / 2;
-}
-
void OutputDevice::ImplDrawEmphasisMark( long nBaseX, long nX, long nY,
const tools::PolyPolygon& rPolyPoly, bool bPolyLine,
const Rectangle& rRect1, const Rectangle& rRect2 )
commit 50261ea4b7242e365717c77a9370afd1044a97e3
Author: Chris Sherlock <chris.sherlock79 at gmail.com>
Date: Thu Jan 7 21:51:12 2016 +1100
vcl: reorganize ImplFontEntry functions
I have moved all ImplFontEntry functions into vcl/source/font/fontentry.cxx
and also created a new hash function that hashes std::pair<sal_UCS4,FontWeight>
types by specializing std::hash.
Change-Id: Ibbe07c38b98e3c976836a895dbfdcaecd5daff8d
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 27142a0..89132a5 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -394,6 +394,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/font/PhysicalFontFace \
vcl/source/font/PhysicalFontFamily \
vcl/source/font/fontselect \
+ vcl/source/font/fontentry \
vcl/source/fontsubset/cff \
vcl/source/fontsubset/fontsubset \
vcl/source/fontsubset/gsub \
diff --git a/vcl/inc/fontentry.hxx b/vcl/inc/fontentry.hxx
index 2768423..d654788 100644
--- a/vcl/inc/fontentry.hxx
+++ b/vcl/inc/fontentry.hxx
@@ -61,9 +61,7 @@ private:
// cache of Unicode characters and replacement font names
// TODO: a fallback map can be shared with many other ImplFontEntries
// TODO: at least the ones which just differ in orientation, stretching or height
- typedef ::std::pair<sal_UCS4,FontWeight> GFBCacheKey;
- struct GFBCacheKey_Hash{ size_t operator()( const GFBCacheKey& ) const; };
- typedef ::std::unordered_map<GFBCacheKey,OUString,GFBCacheKey_Hash> UnicodeFallbackList;
+ typedef ::std::unordered_map< ::std::pair<sal_UCS4,FontWeight>, OUString > UnicodeFallbackList;
UnicodeFallbackList* mpUnicodeFallbackList;
};
diff --git a/vcl/source/font/fontentry.cxx b/vcl/source/font/fontentry.cxx
new file mode 100644
index 0000000..ebcf556
--- /dev/null
+++ b/vcl/source/font/fontentry.cxx
@@ -0,0 +1,134 @@
+/* -*- 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 .
+ */
+
+#include "i18nlangtag/mslangid.hxx"
+
+#include <unotools/configmgr.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/print.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/sysdata.hxx>
+#include <vcl/fontcharmap.hxx>
+
+#include "sallayout.hxx"
+#include "svdata.hxx"
+
+#include "impfont.hxx"
+#include "outdata.hxx"
+#include "fontentry.hxx"
+#include "fontattributes.hxx"
+
+#include "outdev.h"
+#include "window.h"
+
+#include "PhysicalFontCollection.hxx"
+#include "PhysicalFontFace.hxx"
+#include "PhysicalFontFamily.hxx"
+
+#include "svids.hrc"
+
+#include <config_graphite.h>
+#if ENABLE_GRAPHITE
+#include "graphite_features.hxx"
+#endif
+
+#include "../gdi/pdfwriter_impl.hxx"
+
+#include <boost/functional/hash.hpp>
+#include <cmath>
+#include <cstring>
+#include <memory>
+#include <algorithm>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+using namespace ::utl;
+
+// extend std namespace to add custom hash needed for ImplFontEntry
+
+namespace std
+{
+ template <> struct hash< pair< sal_UCS4, FontWeight > >
+ {
+ size_t operator()(const pair< sal_UCS4, FontWeight >& rData) const
+ {
+ size_t h1 = hash<sal_UCS4>()(rData.first);
+ size_t h2 = hash<int>()(rData.second);
+ return h1 ^ h2;
+ }
+ };
+}
+
+
+ImplFontEntry::ImplFontEntry( const FontSelectPattern& rFontSelData )
+ : m_pFontCache(nullptr)
+ , maFontSelData( rFontSelData )
+ , maFontAttributes( rFontSelData )
+ , mpConversion( nullptr )
+ , mnLineHeight( 0 )
+ , mnRefCount( 1 )
+ , mnSetFontFlags( 0 )
+ , mnOwnOrientation( 0 )
+ , mnOrientation( 0 )
+ , mbInit( false )
+ , mpUnicodeFallbackList( nullptr )
+{
+ maFontSelData.mpFontEntry = this;
+}
+
+ImplFontEntry::~ImplFontEntry()
+{
+ delete mpUnicodeFallbackList;
+ m_pFontCache = nullptr;
+}
+
+void ImplFontEntry::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
+{
+ if( !mpUnicodeFallbackList )
+ mpUnicodeFallbackList = new UnicodeFallbackList;
+ (*mpUnicodeFallbackList)[ std::pair< sal_UCS4, FontWeight >(cChar,eWeight) ] = rFontName;
+}
+
+bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, OUString* pFontName ) const
+{
+ if( !mpUnicodeFallbackList )
+ return false;
+
+ UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( std::pair< sal_UCS4, FontWeight >(cChar,eWeight) );
+ if( it == mpUnicodeFallbackList->end() )
+ return false;
+
+ *pFontName = (*it).second;
+ return true;
+}
+
+void ImplFontEntry::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
+{
+ UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( std::pair< sal_UCS4,FontWeight >(cChar,eWeight) );
+ if( it == mpUnicodeFallbackList->end() )
+ return;
+ if( (*it).second == rFontName )
+ mpUnicodeFallbackList->erase( it );
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 915cc89..4593900 100644
--- a/vcl/source/outdev/font.cxx
+++ b/vcl/source/outdev/font.cxx
@@ -979,66 +979,6 @@ vcl::Font OutputDevice::GetDefaultFont( DefaultFontType nType, LanguageType eLan
return aFont;
}
-ImplFontEntry::ImplFontEntry( const FontSelectPattern& rFontSelData )
- : m_pFontCache(nullptr)
- , maFontSelData( rFontSelData )
- , maFontAttributes( rFontSelData )
- , mpConversion( nullptr )
- , mnLineHeight( 0 )
- , mnRefCount( 1 )
- , mnSetFontFlags( 0 )
- , mnOwnOrientation( 0 )
- , mnOrientation( 0 )
- , mbInit( false )
- , mpUnicodeFallbackList( nullptr )
-{
- maFontSelData.mpFontEntry = this;
-}
-
-ImplFontEntry::~ImplFontEntry()
-{
- delete mpUnicodeFallbackList;
- m_pFontCache = nullptr;
-}
-
-size_t ImplFontEntry::GFBCacheKey_Hash::operator()( const GFBCacheKey& rData ) const
-{
- boost::hash<sal_UCS4> a;
- boost::hash<int > b;
- return a(rData.first) ^ b(rData.second);
-}
-
-void ImplFontEntry::AddFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
-{
- if( !mpUnicodeFallbackList )
- mpUnicodeFallbackList = new UnicodeFallbackList;
- (*mpUnicodeFallbackList)[ GFBCacheKey(cChar,eWeight) ] = rFontName;
-}
-
-bool ImplFontEntry::GetFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, OUString* pFontName ) const
-{
- if( !mpUnicodeFallbackList )
- return false;
-
- UnicodeFallbackList::const_iterator it = mpUnicodeFallbackList->find( GFBCacheKey(cChar,eWeight) );
- if( it == mpUnicodeFallbackList->end() )
- return false;
-
- *pFontName = (*it).second;
- return true;
-}
-
-void ImplFontEntry::IgnoreFallbackForUnicode( sal_UCS4 cChar, FontWeight eWeight, const OUString& rFontName )
-{
-// DBG_ASSERT( mpUnicodeFallbackList, "ImplFontEntry::IgnoreFallbackForUnicode no list" );
- UnicodeFallbackList::iterator it = mpUnicodeFallbackList->find( GFBCacheKey(cChar,eWeight) );
-// DBG_ASSERT( it != mpUnicodeFallbackList->end(), "ImplFontEntry::IgnoreFallbackForUnicode no match" );
- if( it == mpUnicodeFallbackList->end() )
- return;
- if( (*it).second == rFontName )
- mpUnicodeFallbackList->erase( it );
-}
-
FontSelectPatternAttributes::FontSelectPatternAttributes( const vcl::Font& rFont,
const OUString& rSearchName, const Size& rSize, float fExactHeight )
: maSearchName( rSearchName )
More information about the Libreoffice-commits
mailing list