summaryrefslogtreecommitdiff
path: root/vcl/source/gdi/metric.cxx
diff options
context:
space:
mode:
authorRüdiger Timm <rt@openoffice.org>2004-07-13 08:29:57 +0000
committerRüdiger Timm <rt@openoffice.org>2004-07-13 08:29:57 +0000
commit3527a72859a3a37f9c5878039f93badbb531dfbc (patch)
tree2d173b7f52fb435619f0c4c36ba3656612d18f50 /vcl/source/gdi/metric.cxx
parent35da1acfcdff5d551ab3f036834c0c63681ff284 (diff)
INTEGRATION: CWS fontlists02 (1.8.126); FILE MERGED
2004/06/24 06:28:05 hdu 1.8.126.10: #21821# use CTL processing for diacritical marks 2004/06/23 08:18:50 hdu 1.8.126.9: #i26679# fix typo 2004/06/18 09:12:57 hdu 1.8.126.8: #i26679# make ImplFontCharMap refcount usable from outside 2004/06/18 09:00:38 hdu 1.8.126.7: #i26679# better export of default ImplFontCharMap 2004/05/25 09:01:10 hdu 1.8.126.6: #i26679# special case for default charmap 2004/05/25 07:18:16 hdu 1.8.126.5: #i26679# export more symbols 2004/05/24 12:49:44 hdu 1.8.126.4: #i26679# add FontCharMap::CountCharsInRange() 2004/05/19 15:39:00 hdu 1.8.126.3: #i26679# pImpl-ify fontcharmap and fontmetric 2004/05/12 13:47:49 hdu 1.8.126.2: #i26679# use CJK/CTL flags 2004/03/25 16:38:56 hdu 1.8.126.1: Font Management Refactoring, first step: Keep the externally visible original algorithms intact Split up the ImplFontCache::Get(..) monster method Make implicit relationships between font management classes explicit Allow derivation from ImplFontData+ImplFontEntry for font technology specific caching Get rid of linear searches in mainstream code, use efficient STL containers Get rid of some obsolete data types BOOL->bool, USHORT->int, etc. Improve infrastructure for unicode surrogate processing
Diffstat (limited to 'vcl/source/gdi/metric.cxx')
-rw-r--r--vcl/source/gdi/metric.cxx483
1 files changed, 376 insertions, 107 deletions
diff --git a/vcl/source/gdi/metric.cxx b/vcl/source/gdi/metric.cxx
index 22ca9121e308..f43942b2582b 100644
--- a/vcl/source/gdi/metric.cxx
+++ b/vcl/source/gdi/metric.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: metric.cxx,v $
*
- * $Revision: 1.9 $
+ * $Revision: 1.10 $
*
- * last change: $Author: rt $ $Date: 2004-06-17 12:17:38 $
+ * last change: $Author: rt $ $Date: 2004-07-13 09:29:57 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -59,44 +59,77 @@
*
************************************************************************/
+#include <impfont.hxx>
#include <metric.hxx>
// =======================================================================
-FontInfo::FontInfo()
+ImplFontMetric::ImplFontMetric()
+: mnRefCount( 1 ),
+ mnMiscFlags( 0 ),
+ mnAscent( 0 ),
+ mnDescent( 0 ),
+ mnIntLeading( 0 ),
+ mnExtLeading( 0 ),
+ mnLineHeight( 0 ),
+ mnSlant( 0 )
+{}
+
+// -----------------------------------------------------------------------
+
+inline void ImplFontMetric::AddReference()
+{
+ ++mnRefCount;
+}
+
+// -----------------------------------------------------------------------
+
+inline void ImplFontMetric::DeReference()
+{
+ if( --mnRefCount <= 0 )
+ delete this;
+}
+
+// -----------------------------------------------------------------------
+
+bool ImplFontMetric::operator==( const ImplFontMetric& r ) const
{
- mpImplMetric = new ImplFontMetric;
- mpImplMetric->mnRefCount = 1;
- mpImplMetric->meType = TYPE_DONTKNOW;
- mpImplMetric->mbDevice = FALSE;
- mpImplMetric->mnAscent = 0;
- mpImplMetric->mnDescent = 0;
- mpImplMetric->mnIntLeading = 0;
- mpImplMetric->mnExtLeading = 0;
- mpImplMetric->mnLineHeight = 0;
- mpImplMetric->mnSlant = 0;
- mpImplMetric->mnFirstChar = 0;
- mpImplMetric->mnLastChar = 0;
+ if( mnMiscFlags != r.mnMiscFlags )
+ return false;
+ if( mnAscent != r.mnAscent )
+ return false;
+ if( mnDescent != r.mnDescent )
+ return false;
+ if( mnIntLeading != r.mnIntLeading )
+ return false;
+ if( mnExtLeading != r.mnExtLeading )
+ return false;
+ if( mnSlant != r.mnSlant )
+ return false;
+
+ return true;
}
+// =======================================================================
+
+FontInfo::FontInfo()
+: mpImplMetric( new ImplFontMetric )
+{}
+
// -----------------------------------------------------------------------
-FontInfo::FontInfo( const FontInfo& rInfo ) :
- Font( rInfo )
+FontInfo::FontInfo( const FontInfo& rInfo )
+: Font( rInfo )
{
mpImplMetric = rInfo.mpImplMetric;
- mpImplMetric->mnRefCount++;
+ mpImplMetric->AddReference();
}
// -----------------------------------------------------------------------
FontInfo::~FontInfo()
{
- // Eventuell Metric loeschen
- if ( mpImplMetric->mnRefCount > 1 )
- mpImplMetric->mnRefCount--;
- else
- delete mpImplMetric;
+ mpImplMetric->DeReference();
}
// -----------------------------------------------------------------------
@@ -105,131 +138,197 @@ FontInfo& FontInfo::operator=( const FontInfo& rInfo )
{
Font::operator=( rInfo );
- // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann
- rInfo.mpImplMetric->mnRefCount++;
-
- // Sind wir nicht die letzten ?
- if ( mpImplMetric->mnRefCount > 1 )
- mpImplMetric->mnRefCount--;
- else
- delete mpImplMetric;
-
- mpImplMetric = rInfo.mpImplMetric;
+ if( mpImplMetric != rInfo.mpImplMetric )
+ {
+ mpImplMetric->DeReference();
+ mpImplMetric = rInfo.mpImplMetric;
+ mpImplMetric->AddReference();
+ }
return *this;
-
}
// -----------------------------------------------------------------------
BOOL FontInfo::operator==( const FontInfo& rInfo ) const
{
- if ( !Font::operator==( rInfo ) )
+ if( !Font::operator==( rInfo ) )
return FALSE;
-
- if ( mpImplMetric == rInfo.mpImplMetric )
+ if( mpImplMetric == rInfo.mpImplMetric )
return TRUE;
-
- if ( (mpImplMetric->meType == rInfo.mpImplMetric->meType ) &&
- (mpImplMetric->mbDevice == rInfo.mpImplMetric->mbDevice ) &&
- (mpImplMetric->mnAscent == rInfo.mpImplMetric->mnAscent ) &&
- (mpImplMetric->mnDescent == rInfo.mpImplMetric->mnDescent ) &&
- (mpImplMetric->mnIntLeading== rInfo.mpImplMetric->mnIntLeading ) &&
- (mpImplMetric->mnExtLeading== rInfo.mpImplMetric->mnExtLeading ) &&
- (mpImplMetric->mnSlant == rInfo.mpImplMetric->mnSlant ) &&
- (mpImplMetric->mnFirstChar == rInfo.mpImplMetric->mnFirstChar ) &&
- (mpImplMetric->mnLastChar == rInfo.mpImplMetric->mnLastChar ) )
+ if( *mpImplMetric == *rInfo.mpImplMetric )
return TRUE;
- else
- return FALSE;
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+FontType FontInfo::GetType() const
+{
+ return (mpImplMetric->IsScalable() ? TYPE_SCALABLE : TYPE_RASTER);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontInfo::IsDeviceFont() const
+{
+ return mpImplMetric->IsDeviceFont();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontInfo::SupportsLatin() const
+{
+ return mpImplMetric->SupportsLatin();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontInfo::SupportsCJK() const
+{
+ return mpImplMetric->SupportsCJK();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontInfo::SupportsCTL() const
+{
+ return mpImplMetric->SupportsCTL();
}
// =======================================================================
-static const sal_UCS4 pDefaultRangeCodes[] = {0x0020,0xD800, 0xE000,0xFFF0};
+FontMetric::FontMetric( const FontMetric& rMetric )
+: FontInfo( rMetric )
+{}
-FontCharMap::FontCharMap()
-: mpRangeCodes( NULL )
+// -----------------------------------------------------------------------
+
+long FontMetric::GetAscent() const
{
- ImplSetDefaultRanges();
+ return mpImplMetric->GetAscent();
}
// -----------------------------------------------------------------------
-FontCharMap::~FontCharMap()
+long FontMetric::GetDescent() const
{
- ImplSetRanges( 0, NULL );
+ return mpImplMetric->GetDescent();
}
// -----------------------------------------------------------------------
-FontCharMap& FontCharMap::operator=( const FontCharMap& rMap )
+long FontMetric::GetIntLeading() const
{
- if( rMap.mpRangeCodes == pDefaultRangeCodes )
- {
- ImplSetDefaultRanges();
- }
- else
- {
- ULONG nPairs = rMap.mnRangeCount;
- sal_UCS4* pCodes = new sal_UCS4[ 2 * nPairs ];
- for( ULONG i = 0; i < 2*nPairs; ++i )
- pCodes[ i ] = rMap.mpRangeCodes[ i ];
- ImplSetRanges( nPairs, pCodes );
- }
+ return mpImplMetric->GetIntLeading();
+}
+
+// -----------------------------------------------------------------------
+
+long FontMetric::GetExtLeading() const
+{
+ return mpImplMetric->GetExtLeading();
+}
+
+// -----------------------------------------------------------------------
+
+long FontMetric::GetLineHeight() const
+{
+ return mpImplMetric->GetLineHeight();
+}
+
+// -----------------------------------------------------------------------
+
+long FontMetric::GetSlant() const
+{
+ return mpImplMetric->GetSlant();
+}
+
+// -----------------------------------------------------------------------
+FontMetric& FontMetric::operator =( const FontMetric& rMetric )
+{
+ FontInfo::operator=( rMetric );
return *this;
}
// -----------------------------------------------------------------------
-void FontCharMap::ImplSetRanges( ULONG nPairs, const sal_UCS4* pCodes )
+BOOL FontMetric::operator==( const FontMetric& rMetric ) const
{
- if( mpRangeCodes && mpRangeCodes != pDefaultRangeCodes )
- delete[] const_cast<sal_UCS4*>( mpRangeCodes );
+ return FontInfo::operator==( rMetric );
+}
- mnRangeCount = nPairs;
- mpRangeCodes = pCodes;
+// =======================================================================
- mnCharCount = 0;
- for( int i = 0; i < nPairs; ++i )
- mnCharCount += mpRangeCodes[ 2*i+1 ] - mpRangeCodes[ 2*i ];
+ImplFontCharMap::ImplFontCharMap( int nRangePairs, const sal_uInt32* pRangeCodes )
+: mpRangeCodes( pRangeCodes ),
+ mnRangeCount( nRangePairs ),
+ mnCharCount( 0 ),
+ mnRefCount( 1 )
+{
+ while( --nRangePairs >= 0 )
+ {
+ sal_uInt32 cFirst = *(pRangeCodes++);
+ sal_uInt32 cLast = *(pRangeCodes++);
+ mnCharCount += cLast - cFirst;
+ }
}
+static ImplFontCharMap* pDefaultImplFontCharMap = NULL;
+static const sal_uInt32 pDefaultRangeCodes[] = {0x0020,0xD800, 0xE000,0xFFF0};
+
// -----------------------------------------------------------------------
-void FontCharMap::ImplSetDefaultRanges()
+ImplFontCharMap::~ImplFontCharMap()
{
- int nCodes = sizeof(pDefaultRangeCodes) / sizeof(*pDefaultRangeCodes);
- ImplSetRanges( nCodes/2, pDefaultRangeCodes );
+ if( mpRangeCodes != pDefaultRangeCodes )
+ delete[] mpRangeCodes;
}
// -----------------------------------------------------------------------
-BOOL FontCharMap::IsDefaultMap() const
+ImplFontCharMap* ImplFontCharMap::GetDefaultMap()
+{
+ if( !pDefaultImplFontCharMap )
+ pDefaultImplFontCharMap = new ImplFontCharMap( 2, pDefaultRangeCodes );
+ pDefaultImplFontCharMap->AddReference();
+ return pDefaultImplFontCharMap;
+}
+
+// -----------------------------------------------------------------------
+
+bool ImplFontCharMap::IsDefaultMap() const
{
return (mpRangeCodes == pDefaultRangeCodes);
}
// -----------------------------------------------------------------------
-void FontCharMap::GetRange( ULONG i, sal_UCS4& cBegin, sal_UCS4& cEnd ) const
+void ImplFontCharMap::AddReference()
{
- if( i < 0 || i >= mnRangeCount )
- {
- cBegin = pDefaultRangeCodes[ 0 ];
- cEnd = pDefaultRangeCodes[ 1 ];
- }
- else
- {
- cBegin = mpRangeCodes[ 2*i ];
- cEnd = mpRangeCodes[ 2*i+1 ];
- }
+ ++mnRefCount;
}
// -----------------------------------------------------------------------
-int FontCharMap::ImplFindRange( sal_UCS4 cChar ) const
+void ImplFontCharMap::DeReference()
+{
+ if( --mnRefCount <= 0 )
+ if( this != pDefaultImplFontCharMap )
+ delete this;
+}
+
+// -----------------------------------------------------------------------
+
+int ImplFontCharMap::GetCharCount() const
+{
+ return mnCharCount;
+}
+
+// -----------------------------------------------------------------------
+
+int ImplFontCharMap::ImplFindRangeIndex( sal_uInt32 cChar ) const
{
int nLower = 0;
int nMid = mnRangeCount;
@@ -242,63 +341,233 @@ int FontCharMap::ImplFindRange( sal_UCS4 cChar ) const
nUpper = nMid - 1;
nMid = (nLower + nUpper + 1) / 2;
}
+
return nMid;
}
// -----------------------------------------------------------------------
-BOOL FontCharMap::HasChar( sal_UCS4 cChar ) const
+bool ImplFontCharMap::HasChar( sal_uInt32 cChar ) const
{
- int nRange = ImplFindRange( cChar );
+ int nRange = ImplFindRangeIndex( cChar );
if( nRange==0 && cChar<mpRangeCodes[0] )
- return FALSE;
- return (nRange & 1) ? FALSE: TRUE;
+ return false;
+ return ((nRange & 1) == 0);
+}
+
+// -----------------------------------------------------------------------
+
+// returns the number of chars supported by the font, which
+// are inside the unicode range from cMin to cMax (inclusive)
+int ImplFontCharMap::CountCharsInRange( sal_uInt32 cMin, sal_uInt32 cMax ) const
+{
+ int nCount = 0;
+
+ // find and adjust range and char count for cMin
+ int nRangeMin = ImplFindRangeIndex( cMin );
+ if( (nRangeMin & 1) != 0 )
+ ++nRangeMin;
+ else if( cMin > mpRangeCodes[ nRangeMin ] )
+ nCount -= cMin - mpRangeCodes[ nRangeMin ];
+
+ // find and adjust range and char count for cMax
+ int nRangeMax = ImplFindRangeIndex( cMax );
+ if( (nRangeMin & 1) != 0 )
+ --nRangeMax;
+ else
+ nCount -= mpRangeCodes[ nRangeMax+1 ] - cMax - 1;
+
+ // count chars in complete ranges between cMin and cMax
+ for( int i = nRangeMin; i <= nRangeMax; i+=2 )
+ nCount += mpRangeCodes[i+1] - mpRangeCodes[i];
+
+ return nCount;
}
// -----------------------------------------------------------------------
-sal_UCS4 FontCharMap::GetFirstChar() const
+sal_uInt32 ImplFontCharMap::GetFirstChar() const
{
return mpRangeCodes[0];
}
// -----------------------------------------------------------------------
-sal_UCS4 FontCharMap::GetLastChar() const
+sal_uInt32 ImplFontCharMap::GetLastChar() const
{
return (mpRangeCodes[ 2*mnRangeCount-1 ] - 1);
}
// -----------------------------------------------------------------------
-sal_UCS4 FontCharMap::GetNextChar( sal_UCS4 cChar ) const
+sal_uInt32 ImplFontCharMap::GetNextChar( sal_uInt32 cChar ) const
{
if( cChar < GetFirstChar() )
return GetFirstChar();
if( cChar >= GetLastChar() )
return GetLastChar();
- int nRange = ImplFindRange( cChar );
- if( nRange & 1 ) // inbetween ranges?
- return mpRangeCodes[ nRange + 1 ]; // first in next range
+ int nRange = ImplFindRangeIndex( cChar );
+ if( nRange & 1 ) // outside a range?
+ return mpRangeCodes[ nRange + 1 ]; // => first in next range
return (cChar + 1);
}
// -----------------------------------------------------------------------
-sal_UCS4 FontCharMap::GetPrevChar( sal_UCS4 cChar ) const
+sal_uInt32 ImplFontCharMap::GetPrevChar( sal_uInt32 cChar ) const
{
if( cChar <= GetFirstChar() )
return GetFirstChar();
if( cChar > GetLastChar() )
return GetLastChar();
- int nRange = ImplFindRange( cChar );
- if( nRange & 1 ) // inbetween ranges?
- return (mpRangeCodes[ nRange ] - 1);
+ int nRange = ImplFindRangeIndex( cChar );
+ if( nRange & 1 ) // outside a range?
+ return (mpRangeCodes[ nRange ] - 1); // => last in prev range
else if( cChar == mpRangeCodes[ nRange ] ) // first in prev range?
- return (mpRangeCodes[ nRange-1 ] - 1);
+ return (mpRangeCodes[ nRange-1 ] - 1); // => last in prev range
return (cChar - 1);
}
+// -----------------------------------------------------------------------
+
+int ImplFontCharMap::GetIndexFromChar( sal_uInt32 cChar ) const
+{
+ // TODO: improve linear walk?
+ int nCharIndex = 0;
+ const sal_uInt32* pRange = &mpRangeCodes[0];
+ for( int i = 0; i < mnRangeCount; ++i )
+ {
+ sal_uInt32 cFirst = *(pRange++);
+ sal_uInt32 cLast = *(pRange++);
+ if( cChar >= cLast )
+ break;
+ if( cChar >= cFirst )
+ return nCharIndex + (cChar - cFirst);
+ nCharIndex += cLast - cFirst;
+ }
+
+ return -1;
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 ImplFontCharMap::GetCharFromIndex( int nCharIndex ) const
+{
+ // TODO: improve linear walk?
+ const sal_uInt32* pRange = &mpRangeCodes[0];
+ for( int i = 0; i < mnRangeCount; ++i )
+ {
+ sal_uInt32 cFirst = *(pRange++);
+ sal_uInt32 cLast = *(pRange++);
+ nCharIndex -= cLast - cFirst;
+ if( nCharIndex < 0 )
+ return (cLast + nCharIndex);
+ }
+
+ // we can only get here with an out-of-bounds charindex
+ return mpRangeCodes[0];
+}
+
+// =======================================================================
+
+FontCharMap::FontCharMap()
+: mpImpl( ImplFontCharMap::GetDefaultMap() )
+{}
+
+// -----------------------------------------------------------------------
+
+FontCharMap::~FontCharMap()
+{
+ mpImpl->DeReference();
+}
+
+// -----------------------------------------------------------------------
+
+int FontCharMap::GetCharCount() const
+{
+ return mpImpl->GetCharCount();
+}
+
+// -----------------------------------------------------------------------
+
+int FontCharMap::CountCharsInRange( sal_uInt32 cMin, sal_uInt32 cMax ) const
+{
+ return mpImpl->CountCharsInRange( cMin, cMax );
+}
+
+// -----------------------------------------------------------------------
+
+void FontCharMap::Reset( ImplFontCharMap* pNewMap )
+{
+ if( pNewMap == NULL )
+ {
+ mpImpl->DeReference();
+ mpImpl = ImplFontCharMap::GetDefaultMap();
+ }
+ else if( pNewMap != mpImpl )
+ {
+ mpImpl->DeReference();
+ mpImpl = pNewMap;
+ mpImpl->AddReference();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontCharMap::IsDefaultMap() const
+{
+ return mpImpl->IsDefaultMap();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontCharMap::HasChar( sal_uInt32 cChar ) const
+{
+ return mpImpl->HasChar( cChar );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 FontCharMap::GetFirstChar() const
+{
+ return mpImpl->GetFirstChar();
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 FontCharMap::GetLastChar() const
+{
+ return mpImpl->GetLastChar();
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 FontCharMap::GetNextChar( sal_uInt32 cChar ) const
+{
+ return mpImpl->GetNextChar( cChar );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 FontCharMap::GetPrevChar( sal_uInt32 cChar ) const
+{
+ return mpImpl->GetPrevChar( cChar );
+}
+
+// -----------------------------------------------------------------------
+
+int FontCharMap::GetIndexFromChar( sal_uInt32 cChar ) const
+{
+ return mpImpl->GetIndexFromChar( cChar );
+}
+
+// -----------------------------------------------------------------------
+
+sal_uInt32 FontCharMap::GetCharFromIndex( int nIndex ) const
+{
+ return mpImpl->GetCharFromIndex( nIndex );
+}
+
// =======================================================================