summaryrefslogtreecommitdiff
path: root/vcl/source/outdev
diff options
context:
space:
mode:
authorChris Sherlock <chris.sherlock79@gmail.com>2016-01-07 22:09:33 +1100
committerChris Sherlock <chris.sherlock79@gmail.com>2016-01-07 22:23:08 +1100
commitf952a9f7139b079deb0aa8a31d1d5e2437846216 (patch)
treedbc2306e584d16d5d8c88bac6730be3a7cd0f073 /vcl/source/outdev
parent50261ea4b7242e365717c77a9370afd1044a97e3 (diff)
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
Diffstat (limited to 'vcl/source/outdev')
-rw-r--r--vcl/source/outdev/font.cxx581
1 files changed, 0 insertions, 581 deletions
diff --git a/vcl/source/outdev/font.cxx b/vcl/source/outdev/font.cxx
index 4593900da3cf..6a0faa965dad 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 )