[Libreoffice-commits] core.git: Branch 'aoo/trunk' - 2 commits - vcl/aqua vcl/inc vcl/Library_vcl.mk vcl/source
Herbert Dürr
hdu at apache.org
Thu Jan 2 10:08:11 PST 2014
vcl/Library_vcl.mk | 1
vcl/aqua/source/gdi/salatsuifontutils.cxx | 154 -----
vcl/inc/impfont.hxx | 3
vcl/inc/vcl/metric.hxx | 20
vcl/source/gdi/impfont.cxx | 871 ++++++++++++++++++++++++++++++
vcl/source/gdi/metric.cxx | 695 -----------------------
6 files changed, 886 insertions(+), 858 deletions(-)
New commits:
commit 12d51cf294b62453c140a2db2b32aceb9dfb6ea8
Author: Herbert Dürr <hdu at apache.org>
Date: Thu Jan 2 17:13:47 2014 +0000
#i123951# include impfont.hxx header also for ATSUI
diff --git a/vcl/aqua/source/gdi/salatsuifontutils.cxx b/vcl/aqua/source/gdi/salatsuifontutils.cxx
index e49b29c..89bf44e 100644
--- a/vcl/aqua/source/gdi/salatsuifontutils.cxx
+++ b/vcl/aqua/source/gdi/salatsuifontutils.cxx
@@ -33,6 +33,7 @@
#include "aqua/salgdi.h"
#include "aqua/saldata.hxx"
#include "aqua/salatsuifontutils.hxx"
+#include "impfont.hxx"
// -----------------------------------------------------------------------
commit a3895516f02a80151caaac8b92fb50aa5f7ee93b
Author: Herbert Dürr <hdu at apache.org>
Date: Thu Jan 2 16:42:32 2014 +0000
#i123895# split impfont.cxx source from metric.cxx
and move the helper function UpdateAttributesFromPSName() there to
make it available for all platforms, not only ATSUI-based ones.
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index cd2ba69..eba3270 100755
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -347,6 +347,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/gdi/imagerepository \
vcl/source/gdi/impanmvw \
vcl/source/gdi/impbmp \
+ vcl/source/gdi/impfont \
vcl/source/gdi/impgraph \
vcl/source/gdi/impimage \
vcl/source/gdi/impimagetree \
diff --git a/vcl/aqua/source/gdi/salatsuifontutils.cxx b/vcl/aqua/source/gdi/salatsuifontutils.cxx
index cddea21..e49b29c 100644
--- a/vcl/aqua/source/gdi/salatsuifontutils.cxx
+++ b/vcl/aqua/source/gdi/salatsuifontutils.cxx
@@ -34,159 +34,6 @@
#include "aqua/saldata.hxx"
#include "aqua/salatsuifontutils.hxx"
-// we have to get the font attributes from the name table
-// since neither head's macStyle nor OS/2's panose are easily available
-// during font enumeration. macStyle bits would be not sufficient anyway
-// and SFNT fonts on Mac usually do not contain an OS/2 table.
-static void UpdateAttributesFromPSName( const String& rPSName, ImplDevFontAttributes& rDFA )
-{
- ByteString aPSName( rPSName, RTL_TEXTENCODING_UTF8 );
- aPSName.ToLowerAscii();
-
- // TODO: use a multi-string ignore-case matcher once it becomes available
- if( (aPSName.Search("regular") != STRING_NOTFOUND)
- || (aPSName.Search("normal") != STRING_NOTFOUND)
- || (aPSName.Search("roman") != STRING_NOTFOUND)
- || (aPSName.Search("medium") != STRING_NOTFOUND)
- || (aPSName.Search("plain") != STRING_NOTFOUND)
- || (aPSName.Search("standard") != STRING_NOTFOUND)
- || (aPSName.Search("std") != STRING_NOTFOUND) )
- {
- rDFA.meWidthType = WIDTH_NORMAL;
- rDFA.meWeight = WEIGHT_NORMAL;
- rDFA.meItalic = ITALIC_NONE;
- }
-
- // heuristics for font weight
- if (aPSName.Search("extrablack") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_BLACK;
- else if (aPSName.Search("black") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_BLACK;
- //else if (aPSName.Search("book") != STRING_NOTFOUND)
- // rDFA.meWeight = WEIGHT_SEMIBOLD;
- else if( (aPSName.Search("semibold") != STRING_NOTFOUND)
- || (aPSName.Search("smbd") != STRING_NOTFOUND))
- rDFA.meWeight = WEIGHT_SEMIBOLD;
- else if (aPSName.Search("ultrabold") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_ULTRABOLD;
- else if (aPSName.Search("extrabold") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_BLACK;
- else if( (aPSName.Search("bold") != STRING_NOTFOUND)
- || (aPSName.Search("-bd") != STRING_NOTFOUND))
- rDFA.meWeight = WEIGHT_BOLD;
- else if (aPSName.Search("extralight") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_ULTRALIGHT;
- else if (aPSName.Search("ultralight") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_ULTRALIGHT;
- else if (aPSName.Search("light") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_LIGHT;
- else if (aPSName.Search("thin") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_THIN;
- else if (aPSName.Search("-w3") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_LIGHT;
- else if (aPSName.Search("-w4") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_SEMILIGHT;
- else if (aPSName.Search("-w5") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_NORMAL;
- else if (aPSName.Search("-w6") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_SEMIBOLD;
- else if (aPSName.Search("-w7") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_BOLD;
- else if (aPSName.Search("-w8") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_ULTRABOLD;
- else if (aPSName.Search("-w9") != STRING_NOTFOUND)
- rDFA.meWeight = WEIGHT_BLACK;
-
- // heuristics for font slant
- if( (aPSName.Search("italic") != STRING_NOTFOUND)
- || (aPSName.Search(" ital") != STRING_NOTFOUND)
- || (aPSName.Search("cursive") != STRING_NOTFOUND)
- || (aPSName.Search("-it") != STRING_NOTFOUND)
- || (aPSName.Search("lightit") != STRING_NOTFOUND)
- || (aPSName.Search("mediumit") != STRING_NOTFOUND)
- || (aPSName.Search("boldit") != STRING_NOTFOUND)
- || (aPSName.Search("cnit") != STRING_NOTFOUND)
- || (aPSName.Search("bdcn") != STRING_NOTFOUND)
- || (aPSName.Search("bdit") != STRING_NOTFOUND)
- || (aPSName.Search("condit") != STRING_NOTFOUND)
- || (aPSName.Search("bookit") != STRING_NOTFOUND)
- || (aPSName.Search("blackit") != STRING_NOTFOUND) )
- rDFA.meItalic = ITALIC_NORMAL;
- if( (aPSName.Search("oblique") != STRING_NOTFOUND)
- || (aPSName.Search("inclined") != STRING_NOTFOUND)
- || (aPSName.Search("slanted") != STRING_NOTFOUND) )
- rDFA.meItalic = ITALIC_OBLIQUE;
-
- // heuristics for font width
- if( (aPSName.Search("condensed") != STRING_NOTFOUND)
- || (aPSName.Search("-cond") != STRING_NOTFOUND)
- || (aPSName.Search("boldcond") != STRING_NOTFOUND)
- || (aPSName.Search("boldcn") != STRING_NOTFOUND)
- || (aPSName.Search("cnit") != STRING_NOTFOUND) )
- rDFA.meWidthType = WIDTH_CONDENSED;
- else if (aPSName.Search("narrow") != STRING_NOTFOUND)
- rDFA.meWidthType = WIDTH_SEMI_CONDENSED;
- else if (aPSName.Search("expanded") != STRING_NOTFOUND)
- rDFA.meWidthType = WIDTH_EXPANDED;
- else if (aPSName.Search("wide") != STRING_NOTFOUND)
- rDFA.meWidthType = WIDTH_EXPANDED;
-
- // heuristics for font pitch
- if( (aPSName.Search("mono") != STRING_NOTFOUND)
- || (aPSName.Search("courier") != STRING_NOTFOUND)
- || (aPSName.Search("monaco") != STRING_NOTFOUND)
- || (aPSName.Search("typewriter") != STRING_NOTFOUND) )
- rDFA.mePitch = PITCH_FIXED;
-
- // heuristics for font family type
- if( (aPSName.Search("script") != STRING_NOTFOUND)
- || (aPSName.Search("chancery") != STRING_NOTFOUND)
- || (aPSName.Search("zapfino") != STRING_NOTFOUND))
- rDFA.meFamily = FAMILY_SCRIPT;
- else if( (aPSName.Search("comic") != STRING_NOTFOUND)
- || (aPSName.Search("outline") != STRING_NOTFOUND)
- || (aPSName.Search("pinpoint") != STRING_NOTFOUND) )
- rDFA.meFamily = FAMILY_DECORATIVE;
- else if( (aPSName.Search("sans") != STRING_NOTFOUND)
- || (aPSName.Search("arial") != STRING_NOTFOUND) )
- rDFA.meFamily = FAMILY_SWISS;
- else if( (aPSName.Search("roman") != STRING_NOTFOUND)
- || (aPSName.Search("times") != STRING_NOTFOUND) )
- rDFA.meFamily = FAMILY_ROMAN;
-
- // heuristics for codepoint semantic
- if( (aPSName.Search("symbol") != STRING_NOTFOUND)
- || (aPSName.Search("dings") != STRING_NOTFOUND)
- || (aPSName.Search("dingbats") != STRING_NOTFOUND)
- || (aPSName.Search("ornaments") != STRING_NOTFOUND)
- || (aPSName.Search("embellishments") != STRING_NOTFOUND) )
- rDFA.mbSymbolFlag = true;
-
- // #i100020# special heuristic for names with single-char styles
- // NOTE: we are checking name that hasn't been lower-cased
- if( rPSName.Len() > 3 )
- {
- int i = rPSName.Len();
- sal_Unicode c = rPSName.GetChar( --i );
- if( c == 'C' ) { // "capitals"
- rDFA.meFamily = FAMILY_DECORATIVE;
- c = rPSName.GetChar( --i );
- }
- if( c == 'O' ) { // CFF-based OpenType
- c = rPSName.GetChar( --i );
- }
- if( c == 'I' ) { // "italic"
- rDFA.meItalic = ITALIC_NORMAL;
- c = rPSName.GetChar( --i );
- }
- if( c == 'B' ) // "bold"
- rDFA.meWeight = WEIGHT_BOLD;
- if( c == 'C' ) // "capitals"
- rDFA.meFamily = FAMILY_DECORATIVE;
- // TODO: check that all single-char styles have been resolved?
- }
-}
-
// -----------------------------------------------------------------------
static bool GetDevFontAttributes( ATSUFontID nFontID, ImplDevFontAttributes& rDFA )
diff --git a/vcl/inc/impfont.hxx b/vcl/inc/impfont.hxx
index bfac13d..0b16a7d 100644
--- a/vcl/inc/impfont.hxx
+++ b/vcl/inc/impfont.hxx
@@ -31,6 +31,7 @@
#include <vcl/dllapi.h>
#include <vcl/vclenum.hxx>
#include <vcl/fntstyle.hxx>
+#include <outfont.hxx>
// ------------
// - Impl_Font -
@@ -231,5 +232,7 @@ public:
bool ParseCMAP( const unsigned char* pRawData, int nRawLength, CmapResult& );
+void UpdateAttributesFromPSName( const String& rPSName, ImplDevFontAttributes& );
+
#endif // _SV_IMPFONT_HXX
diff --git a/vcl/inc/vcl/metric.hxx b/vcl/inc/vcl/metric.hxx
index 5e8e413..65f53ed 100644
--- a/vcl/inc/vcl/metric.hxx
+++ b/vcl/inc/vcl/metric.hxx
@@ -97,19 +97,19 @@ public:
FontCharMap();
~FontCharMap();
- sal_Bool IsDefaultMap() const;
- sal_Bool HasChar( sal_uInt32 ) const;
- int CountCharsInRange( sal_uInt32 cMin, sal_uInt32 cMax ) const;
- int GetCharCount() const;
+ bool IsDefaultMap( void ) const;
+ bool HasChar( sal_UCS4 ) const;
+ int CountCharsInRange( sal_UCS4 cMin, sal_UCS4 cMax ) const;
+ int GetCharCount( void ) const;
- sal_uInt32 GetFirstChar() const;
- sal_uInt32 GetLastChar() const;
+ sal_UCS4 GetFirstChar( void ) const;
+ sal_UCS4 GetLastChar( void ) const;
- sal_uInt32 GetNextChar( sal_uInt32 ) const;
- sal_uInt32 GetPrevChar( sal_uInt32 ) const;
+ sal_UCS4 GetNextChar( sal_UCS4 ) const;
+ sal_UCS4 GetPrevChar( sal_UCS4 ) const;
- int GetIndexFromChar( sal_uInt32 ) const;
- sal_uInt32 GetCharFromIndex( int ) const;
+ int GetIndexFromChar( sal_UCS4 ) const;
+ sal_UCS4 GetCharFromIndex( int ) const;
private:
diff --git a/vcl/source/gdi/impfont.cxx b/vcl/source/gdi/impfont.cxx
new file mode 100644
index 0000000..a776ac5
--- /dev/null
+++ b/vcl/source/gdi/impfont.cxx
@@ -0,0 +1,871 @@
+/**************************************************************
+ *
+ * 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
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#include <vcl/metric.hxx>
+#include <outfont.hxx>
+#include <impfont.hxx>
+
+#include <vector>
+#include <set>
+
+// =======================================================================
+
+CmapResult::CmapResult( bool bSymbolic,
+ const sal_UCS4* pRangeCodes, int nRangeCount,
+ const int* pStartGlyphs, const sal_uInt16* pExtraGlyphIds )
+: mpRangeCodes( pRangeCodes)
+, mpStartGlyphs( pStartGlyphs)
+, mpGlyphIds( pExtraGlyphIds)
+, mnRangeCount( nRangeCount)
+, mbSymbolic( bSymbolic)
+, mbRecoded( false)
+{}
+
+// =======================================================================
+
+ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR )
+: mpRangeCodes( rCR.mpRangeCodes )
+, mpStartGlyphs( rCR.mpStartGlyphs )
+, mpGlyphIds( rCR.mpGlyphIds )
+, mnRangeCount( rCR.mnRangeCount )
+, mnCharCount( 0 )
+, mnRefCount( 1 )
+{
+ const sal_UCS4* pRangePtr = mpRangeCodes;
+ for( int i = mnRangeCount; --i >= 0; pRangePtr += 2 )
+ {
+ sal_UCS4 cFirst = pRangePtr[0];
+ sal_UCS4 cLast = pRangePtr[1];
+ mnCharCount += cLast - cFirst;
+ }
+}
+
+static ImplFontCharMap* pDefaultImplFontCharMap = NULL;
+static const sal_UCS4 aDefaultUnicodeRanges[] = {0x0020,0xD800, 0xE000,0xFFF0};
+static const sal_UCS4 aDefaultSymbolRanges[] = {0x0020,0x0100, 0xF020,0xF100};
+
+// -----------------------------------------------------------------------
+
+bool ImplFontCharMap::IsDefaultMap() const
+{
+ const bool bIsDefault = (mpRangeCodes == aDefaultUnicodeRanges) || (mpRangeCodes == aDefaultSymbolRanges);
+ return bIsDefault;
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontCharMap::~ImplFontCharMap()
+{
+ if( IsDefaultMap() )
+ return;
+ delete[] mpRangeCodes;
+ delete[] mpStartGlyphs;
+ delete[] mpGlyphIds;
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontCharMap* ImplFontCharMap::GetDefaultMap( bool bSymbols)
+{
+ if( pDefaultImplFontCharMap )
+ pDefaultImplFontCharMap->AddReference();
+ else
+ {
+ const sal_UCS4* pRangeCodes = aDefaultUnicodeRanges;
+ int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes);
+ if( bSymbols )
+ {
+ pRangeCodes = aDefaultSymbolRanges;
+ nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes);
+ }
+
+ CmapResult aDefaultCR( bSymbols, pRangeCodes, nCodesCount/2 );
+ pDefaultImplFontCharMap = new ImplFontCharMap( aDefaultCR );
+ }
+
+ return pDefaultImplFontCharMap;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFontCharMap::AddReference( void) const
+{
+ ++mnRefCount;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplFontCharMap::DeReference( void) const
+{
+ if( --mnRefCount <= 0 )
+ if( this != pDefaultImplFontCharMap )
+ delete this;
+}
+
+// -----------------------------------------------------------------------
+
+int ImplFontCharMap::GetCharCount() const
+{
+ return mnCharCount;
+}
+
+// -----------------------------------------------------------------------
+
+int ImplFontCharMap::ImplFindRangeIndex( sal_UCS4 cChar ) const
+{
+ int nLower = 0;
+ int nMid = mnRangeCount;
+ int nUpper = 2 * mnRangeCount - 1;
+ while( nLower < nUpper )
+ {
+ if( cChar >= mpRangeCodes[ nMid ] )
+ nLower = nMid;
+ else
+ nUpper = nMid - 1;
+ nMid = (nLower + nUpper + 1) / 2;
+ }
+
+ return nMid;
+}
+
+// -----------------------------------------------------------------------
+
+bool ImplFontCharMap::HasChar( sal_UCS4 cChar ) const
+{
+ bool bHasChar = false;
+
+ if( mpStartGlyphs == NULL ) { // only the char-ranges are known
+ const int nRange = ImplFindRangeIndex( cChar );
+ if( nRange==0 && cChar<mpRangeCodes[0] )
+ return false;
+ bHasChar = ((nRange & 1) == 0); // inside a range
+ } else { // glyph mapping is available
+ const int nGlyphIndex = GetGlyphIndex( cChar );
+ bHasChar = (nGlyphIndex != 0); // not the notdef-glyph
+ }
+
+ return bHasChar;
+}
+
+// -----------------------------------------------------------------------
+
+int ImplFontCharMap::GetGlyphIndex( sal_UCS4 cChar ) const
+{
+ // return -1 if the object doesn't know the glyph ids
+ if( !mpStartGlyphs )
+ return -1;
+
+ // return 0 if the unicode doesn't have a matching glyph
+ int nRange = ImplFindRangeIndex( cChar );
+ // check that we are inside any range
+ if( (nRange == 0) && (cChar < mpRangeCodes[0]) ) {
+ // symbol aliasing gives symbol fonts a second chance
+ const bool bSymbolic = (mpRangeCodes[0]>=0xF000) & (mpRangeCodes[1]<=0xF0FF);
+ if( !bSymbolic )
+ return 0;
+ // check for symbol aliasing (U+F0xx -> U+00xx)
+ nRange = ImplFindRangeIndex( cChar | 0xF000 );
+ }
+ // check that we are inside a range
+ if( (nRange & 1) != 0 )
+ return 0;
+
+ // get glyph index directly or indirectly
+ int nGlyphIndex = cChar - mpRangeCodes[ nRange ];
+ const int nStartIndex = mpStartGlyphs[ nRange/2 ];
+ if( nStartIndex >= 0 ) {
+ // the glyph index can be calculated
+ nGlyphIndex += nStartIndex;
+ } else {
+ // the glyphid array has the glyph index
+ nGlyphIndex = mpGlyphIds[ nGlyphIndex - nStartIndex];
+ }
+
+ return nGlyphIndex;
+}
+
+// -----------------------------------------------------------------------
+
+// returns the number of chars supported by the font, which
+// are inside the unicode range from cMin to cMax (inclusive)
+int ImplFontCharMap::CountCharsInRange( sal_UCS4 cMin, sal_UCS4 cMax ) const
+{
+ int nCount = 0;
+
+ // find and adjust range and char count for cMin
+ int nRangeMin = ImplFindRangeIndex( cMin );
+ if( nRangeMin & 1 )
+ ++nRangeMin;
+ else if( cMin > mpRangeCodes[ nRangeMin ] )
+ nCount -= cMin - mpRangeCodes[ nRangeMin ];
+
+ // find and adjust range and char count for cMax
+ int nRangeMax = ImplFindRangeIndex( cMax );
+ if( nRangeMax & 1 )
+ --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 ImplFontCharMap::GetFirstChar() const
+{
+ return mpRangeCodes[0];
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 ImplFontCharMap::GetLastChar() const
+{
+ return (mpRangeCodes[ 2*mnRangeCount-1 ] - 1);
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 ImplFontCharMap::GetNextChar( sal_UCS4 cChar ) const
+{
+ if( cChar < GetFirstChar() )
+ return GetFirstChar();
+ if( cChar >= GetLastChar() )
+ return GetLastChar();
+
+ int nRange = ImplFindRangeIndex( cChar + 1 );
+ if( nRange & 1 ) // outside of range?
+ return mpRangeCodes[ nRange + 1 ]; // => first in next range
+ return (cChar + 1);
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 ImplFontCharMap::GetPrevChar( sal_UCS4 cChar ) const
+{
+ if( cChar <= GetFirstChar() )
+ return GetFirstChar();
+ if( cChar > GetLastChar() )
+ return GetLastChar();
+
+ int nRange = ImplFindRangeIndex( cChar - 1 );
+ if( nRange & 1 ) // outside a range?
+ return (mpRangeCodes[ nRange ] - 1); // => last in prev range
+ return (cChar - 1);
+}
+
+// -----------------------------------------------------------------------
+
+int ImplFontCharMap::GetIndexFromChar( sal_UCS4 cChar ) const
+{
+ // TODO: improve linear walk?
+ int nCharIndex = 0;
+ const sal_UCS4* pRange = &mpRangeCodes[0];
+ for( int i = 0; i < mnRangeCount; ++i )
+ {
+ sal_UCS4 cFirst = *(pRange++);
+ sal_UCS4 cLast = *(pRange++);
+ if( cChar >= cLast )
+ nCharIndex += cLast - cFirst;
+ else if( cChar >= cFirst )
+ return nCharIndex + (cChar - cFirst);
+ else
+ break;
+ }
+
+ return -1;
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 ImplFontCharMap::GetCharFromIndex( int nCharIndex ) const
+{
+ // TODO: improve linear walk?
+ const sal_UCS4* pRange = &mpRangeCodes[0];
+ for( int i = 0; i < mnRangeCount; ++i )
+ {
+ sal_UCS4 cFirst = *(pRange++);
+ sal_UCS4 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];
+}
+
+// =======================================================================
+
+static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);}
+static unsigned Getsal_uInt16( const unsigned char* p ){ return((p[0]<<8) | p[1]);}
+static int GetSShort( const unsigned char* p ){ return((static_cast<signed char>(p[0])<<8)|p[1]);}
+
+// TODO: move CMAP parsing directly into the ImplFontCharMap class
+bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
+{
+ rResult.mpRangeCodes = NULL;
+ rResult.mpStartGlyphs= NULL;
+ rResult.mpGlyphIds = NULL;
+ rResult.mnRangeCount = 0;
+ rResult.mbRecoded = false;
+ rResult.mbSymbolic = false;
+
+ // parse the table header and check for validity
+ if( !pCmap || (nLength < 24) )
+ return false;
+
+ if( Getsal_uInt16( pCmap ) != 0x0000 ) // simple check for CMAP corruption
+ return false;
+
+ int nSubTables = Getsal_uInt16( pCmap + 2 );
+ if( (nSubTables <= 0) || (nLength < (24 + 8*nSubTables)) )
+ return false;
+
+ // find the most interesting subtable in the CMAP
+ rtl_TextEncoding eRecodeFrom = RTL_TEXTENCODING_UNICODE;
+ int nOffset = 0;
+ int nFormat = -1;
+ int nBestVal = 0;
+ for( const unsigned char* p = pCmap + 4; --nSubTables >= 0; p += 8 )
+ {
+ int nPlatform = Getsal_uInt16( p );
+ int nEncoding = Getsal_uInt16( p+2 );
+ int nPlatformEncoding = (nPlatform << 8) + nEncoding;
+
+ int nValue;
+ rtl_TextEncoding eTmpEncoding = RTL_TEXTENCODING_UNICODE;
+ switch( nPlatformEncoding )
+ {
+ case 0x000: nValue = 20; break; // Unicode 1.0
+ case 0x001: nValue = 21; break; // Unicode 1.1
+ case 0x002: nValue = 22; break; // iso10646_1993
+ case 0x003: nValue = 23; break; // UCS-2
+ case 0x004: nValue = 24; break; // UCS-4
+ case 0x100: nValue = 22; break; // Mac Unicode<2.0
+ case 0x103: nValue = 23; break; // Mac Unicode>2.0
+ case 0x300: nValue = 5; rResult.mbSymbolic = true; break; // Win Symbol
+ case 0x301: nValue = 28; break; // Win UCS-2
+ case 0x30A: nValue = 29; break; // Win-UCS-4
+ case 0x302: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_SHIFT_JIS; break;
+ case 0x303: nValue = 12; eTmpEncoding = RTL_TEXTENCODING_GB_18030; break;
+ case 0x304: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_BIG5; break;
+ case 0x305: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_MS_949; break;
+ case 0x306: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_MS_1361; break;
+ default: nValue = 0; break;
+ }
+
+ if( nValue <= 0 ) // ignore unknown encodings
+ continue;
+
+ int nTmpOffset = GetUInt( p+4 );
+ int nTmpFormat = Getsal_uInt16( pCmap + nTmpOffset );
+ if( nTmpFormat == 12 ) // 32bit code -> glyph map format
+ nValue += 3;
+ else if( nTmpFormat != 4 ) // 16bit code -> glyph map format
+ continue; // ignore other formats
+
+ if( nBestVal < nValue )
+ {
+ nBestVal = nValue;
+ nOffset = nTmpOffset;
+ nFormat = nTmpFormat;
+ eRecodeFrom = eTmpEncoding;
+ }
+ }
+
+ // parse the best CMAP subtable
+ int nRangeCount = 0;
+ sal_UCS4* pCodePairs = NULL;
+ int* pStartGlyphs = NULL;
+
+ typedef std::vector<sal_uInt16> U16Vector;
+ U16Vector aGlyphIdArray;
+ aGlyphIdArray.reserve( 0x1000 );
+ aGlyphIdArray.push_back( 0 );
+
+ // format 4, the most common 16bit char mapping table
+ if( (nFormat == 4) && ((nOffset+16) < nLength) )
+ {
+ int nSegCountX2 = Getsal_uInt16( pCmap + nOffset + 6 );
+ nRangeCount = nSegCountX2/2 - 1;
+ pCodePairs = new sal_UCS4[ nRangeCount * 2 ];
+ pStartGlyphs = new int[ nRangeCount ];
+ const unsigned char* pLimitBase = pCmap + nOffset + 14;
+ const unsigned char* pBeginBase = pLimitBase + nSegCountX2 + 2;
+ const unsigned char* pDeltaBase = pBeginBase + nSegCountX2;
+ const unsigned char* pOffsetBase = pDeltaBase + nSegCountX2;
+ sal_UCS4* pCP = pCodePairs;
+ for( int i = 0; i < nRangeCount; ++i )
+ {
+ const sal_UCS4 cMinChar = Getsal_uInt16( pBeginBase + 2*i );
+ const sal_UCS4 cMaxChar = Getsal_uInt16( pLimitBase + 2*i );
+ const int nGlyphDelta = GetSShort( pDeltaBase + 2*i );
+ const int nRangeOffset = Getsal_uInt16( pOffsetBase + 2*i );
+ if( cMinChar > cMaxChar ) // no sane font should trigger this
+ break;
+ if( cMaxChar == 0xFFFF )
+ break;
+ *(pCP++) = cMinChar;
+ *(pCP++) = cMaxChar + 1;
+ if( !nRangeOffset ) {
+ // glyphid can be calculated directly
+ pStartGlyphs[i] = (cMinChar + nGlyphDelta) & 0xFFFF;
+ } else {
+ // update the glyphid-array with the glyphs in this range
+ pStartGlyphs[i] = -(int)aGlyphIdArray.size();
+ const unsigned char* pGlyphIdPtr = pOffsetBase + 2*i + nRangeOffset;
+ for( sal_UCS4 c = cMinChar; c <= cMaxChar; ++c, pGlyphIdPtr+=2 ) {
+ const int nGlyphIndex = Getsal_uInt16( pGlyphIdPtr ) + nGlyphDelta;
+ aGlyphIdArray.push_back( static_cast<sal_uInt16>(nGlyphIndex) );
+ }
+ }
+ }
+ nRangeCount = (pCP - pCodePairs) / 2;
+ }
+ // format 12, the most common 32bit char mapping table
+ else if( (nFormat == 12) && ((nOffset+16) < nLength) )
+ {
+ nRangeCount = GetUInt( pCmap + nOffset + 12 );
+ pCodePairs = new sal_UCS4[ nRangeCount * 2 ];
+ pStartGlyphs = new int[ nRangeCount ];
+ const unsigned char* pGroup = pCmap + nOffset + 16;
+ sal_UCS4* pCP = pCodePairs;
+ for( int i = 0; i < nRangeCount; ++i )
+ {
+ sal_UCS4 cMinChar = GetUInt( pGroup + 0 );
+ sal_UCS4 cMaxChar = GetUInt( pGroup + 4 );
+ int nGlyphId = GetUInt( pGroup + 8 );
+ pGroup += 12;
+#if 0 // TODO: remove unicode baseplane clipping for UCS-4 support
+ if( cMinChar > 0xFFFF )
+ continue;
+ if( cMaxChar > 0xFFFF )
+ cMaxChar = 0xFFFF;
+#else
+ if( cMinChar > cMaxChar ) // no sane font should trigger this
+ break;
+#endif
+ *(pCP++) = cMinChar;
+ *(pCP++) = cMaxChar + 1;
+ pStartGlyphs[i] = nGlyphId;
+ }
+ nRangeCount = (pCP - pCodePairs) / 2;
+ }
+
+ // check if any subtable resulted in something usable
+ if( nRangeCount <= 0 )
+ {
+ delete[] pCodePairs;
+ delete[] pStartGlyphs;
+
+ // even when no CMAP is available we know it for symbol fonts
+ if( rResult.mbSymbolic )
+ {
+ pCodePairs = new sal_UCS4[4];
+ pCodePairs[0] = 0x0020; // aliased symbols
+ pCodePairs[1] = 0x0100;
+ pCodePairs[2] = 0xF020; // original symbols
+ pCodePairs[3] = 0xF100;
+ rResult.mpRangeCodes = pCodePairs;
+ rResult.mnRangeCount = 2;
+ return true;
+ }
+
+ return false;
+ }
+
+ // recode the code ranges to their unicode encoded ranges if needed
+ rtl_TextToUnicodeConverter aConverter = NULL;
+ rtl_UnicodeToTextContext aCvtContext = NULL;
+
+ rResult.mbRecoded = ( eRecodeFrom != RTL_TEXTENCODING_UNICODE );
+ if( rResult.mbRecoded )
+ {
+ aConverter = rtl_createTextToUnicodeConverter( eRecodeFrom );
+ aCvtContext = rtl_createTextToUnicodeContext( aConverter );
+ }
+
+ if( aConverter && aCvtContext )
+ {
+ // determine the set of supported unicodes from encoded ranges
+ typedef std::set<sal_UCS4> Ucs4Set;
+ Ucs4Set aSupportedUnicodes;
+
+ static const int NINSIZE = 64;
+ static const int NOUTSIZE = 64;
+ sal_Char cCharsInp[ NINSIZE ];
+ sal_Unicode cCharsOut[ NOUTSIZE ];
+ sal_UCS4* pCP = pCodePairs;
+ for( int i = 0; i < nRangeCount; ++i )
+ {
+ sal_UCS4 cMin = *(pCP++);
+ sal_UCS4 cEnd = *(pCP++);
+ while( cMin < cEnd )
+ {
+ int j = 0;
+ for(; (cMin < cEnd) && (j < NINSIZE); ++cMin )
+ {
+ if( cMin >= 0x0100 )
+ cCharsInp[ j++ ] = static_cast<sal_Char>(cMin >> 8);
+ if( (cMin >= 0x0100) || (cMin < 0x00A0) )
+ cCharsInp[ j++ ] = static_cast<sal_Char>(cMin);
+ }
+
+ sal_uInt32 nCvtInfo;
+ sal_Size nSrcCvtBytes;
+ int nOutLen = rtl_convertTextToUnicode(
+ aConverter, aCvtContext,
+ cCharsInp, j, cCharsOut, NOUTSIZE,
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE
+ | RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE,
+ &nCvtInfo, &nSrcCvtBytes );
+
+ for( j = 0; j < nOutLen; ++j )
+ aSupportedUnicodes.insert( cCharsOut[j] );
+ }
+ }
+
+ rtl_destroyTextToUnicodeConverter( aCvtContext );
+ rtl_destroyTextToUnicodeConverter( aConverter );
+
+ // convert the set of supported unicodes to ranges
+ typedef std::vector<sal_UCS4> Ucs4Vector;
+ Ucs4Vector aSupportedRanges;
+
+ Ucs4Set::const_iterator itChar = aSupportedUnicodes.begin();
+ for(; itChar != aSupportedUnicodes.end(); ++itChar )
+ {
+ if( aSupportedRanges.empty()
+ || (aSupportedRanges.back() != *itChar) )
+ {
+ // add new range beginning with current unicode
+ aSupportedRanges.push_back( *itChar );
+ aSupportedRanges.push_back( 0 );
+ }
+
+ // extend existing range to include current unicode
+ aSupportedRanges.back() = *itChar + 1;
+ }
+
+ // glyph mapping for non-unicode fonts not implemented
+ delete[] pStartGlyphs;
+ pStartGlyphs = NULL;
+ aGlyphIdArray.clear();
+
+ // make a pCodePairs array using the vector from above
+ delete[] pCodePairs;
+ nRangeCount = aSupportedRanges.size() / 2;
+ if( nRangeCount <= 0 )
+ return false;
+ pCodePairs = new sal_UCS4[ nRangeCount * 2 ];
+ Ucs4Vector::const_iterator itInt = aSupportedRanges.begin();
+ for( pCP = pCodePairs; itInt != aSupportedRanges.end(); ++itInt )
+ *(pCP++) = *itInt;
+ }
+
+ // prepare the glyphid-array if needed
+ // TODO: merge ranges if they are close enough?
+ sal_uInt16* pGlyphIds = NULL;
+ if( !aGlyphIdArray.empty())
+ {
+ pGlyphIds = new sal_uInt16[ aGlyphIdArray.size() ];
+ sal_uInt16* pOut = pGlyphIds;
+ U16Vector::const_iterator it = aGlyphIdArray.begin();
+ while( it != aGlyphIdArray.end() )
+ *(pOut++) = *(it++);
+ }
+
+ // update the result struct
+ rResult.mpRangeCodes = pCodePairs;
+ rResult.mpStartGlyphs = pStartGlyphs;
+ rResult.mnRangeCount = nRangeCount;
+ rResult.mpGlyphIds = pGlyphIds;
+ return true;
+}
+
+// =======================================================================
+
+FontCharMap::FontCharMap()
+: mpImpl( ImplFontCharMap::GetDefaultMap() )
+{}
+
+// -----------------------------------------------------------------------
+
+FontCharMap::~FontCharMap()
+{
+ mpImpl->DeReference();
+ mpImpl = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+int FontCharMap::GetCharCount() const
+{
+ return mpImpl->GetCharCount();
+}
+
+// -----------------------------------------------------------------------
+
+int FontCharMap::CountCharsInRange( sal_UCS4 cMin, sal_UCS4 cMax ) const
+{
+ return mpImpl->CountCharsInRange( cMin, cMax );
+}
+
+// -----------------------------------------------------------------------
+
+void FontCharMap::Reset( const 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_UCS4 cChar ) const
+{
+ return mpImpl->HasChar( cChar );
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 FontCharMap::GetFirstChar() const
+{
+ return mpImpl->GetFirstChar();
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 FontCharMap::GetLastChar() const
+{
+ return mpImpl->GetLastChar();
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 FontCharMap::GetNextChar( sal_UCS4 cChar ) const
+{
+ return mpImpl->GetNextChar( cChar );
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 FontCharMap::GetPrevChar( sal_UCS4 cChar ) const
+{
+ return mpImpl->GetPrevChar( cChar );
+}
+
+// -----------------------------------------------------------------------
+
+int FontCharMap::GetIndexFromChar( sal_UCS4 cChar ) const
+{
+ return mpImpl->GetIndexFromChar( cChar );
+}
+
+// -----------------------------------------------------------------------
+
+sal_UCS4 FontCharMap::GetCharFromIndex( int nIndex ) const
+{
+ return mpImpl->GetCharFromIndex( nIndex );
+}
+
+// =======================================================================
+
+// on some systems we have to get the font attributes from the name table
+// since neither head's macStyle nor OS/2's panose are easily available
+// during font enumeration. macStyle bits would be not sufficient anyway
+// and SFNT fonts on Mac usually do not contain an OS/2 table.
+void UpdateAttributesFromPSName( const String& rPSName, ImplDevFontAttributes& rDFA )
+{
+ ByteString aPSName( rPSName, RTL_TEXTENCODING_UTF8 );
+ aPSName.ToLowerAscii();
+
+ // TODO: use a multi-string ignore-case matcher once it becomes available
+ if( (aPSName.Search("regular") != STRING_NOTFOUND)
+ || (aPSName.Search("normal") != STRING_NOTFOUND)
+ || (aPSName.Search("roman") != STRING_NOTFOUND)
+ || (aPSName.Search("medium") != STRING_NOTFOUND)
+ || (aPSName.Search("plain") != STRING_NOTFOUND)
+ || (aPSName.Search("standard") != STRING_NOTFOUND)
+ || (aPSName.Search("std") != STRING_NOTFOUND) )
+ {
+ rDFA.meWidthType = WIDTH_NORMAL;
+ rDFA.meWeight = WEIGHT_NORMAL;
+ rDFA.meItalic = ITALIC_NONE;
+ }
+
+ // heuristics for font weight
+ if (aPSName.Search("extrablack") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_BLACK;
+ else if (aPSName.Search("black") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_BLACK;
+#if 1
+ else if (aPSName.Search("book") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_NORMAL;
+#endif
+ else if( (aPSName.Search("semibold") != STRING_NOTFOUND)
+ || (aPSName.Search("smbd") != STRING_NOTFOUND))
+ rDFA.meWeight = WEIGHT_SEMIBOLD;
+ else if( aPSName.Search("ultrabold") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_ULTRABOLD;
+ else if( aPSName.Search("extrabold") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_BLACK;
+ else if( (aPSName.Search("bold") != STRING_NOTFOUND)
+ || (aPSName.Search("-bd") != STRING_NOTFOUND))
+ rDFA.meWeight = WEIGHT_BOLD;
+ else if( aPSName.Search("extralight") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_ULTRALIGHT;
+ else if( aPSName.Search("ultralight") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_ULTRALIGHT;
+ else if( aPSName.Search("light") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_LIGHT;
+ else if( aPSName.Search("thin") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_THIN;
+ else if( aPSName.Search("-w3") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_LIGHT;
+ else if( aPSName.Search("-w4") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_SEMILIGHT;
+ else if( aPSName.Search("-w5") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_NORMAL;
+ else if( aPSName.Search("-w6") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_SEMIBOLD;
+ else if( aPSName.Search("-w7") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_BOLD;
+ else if( aPSName.Search("-w8") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_ULTRABOLD;
+ else if( aPSName.Search("-w9") != STRING_NOTFOUND)
+ rDFA.meWeight = WEIGHT_BLACK;
+
+ // heuristics for font slant
+ if( (aPSName.Search("italic") != STRING_NOTFOUND)
+ || (aPSName.Search(" ital") != STRING_NOTFOUND)
+ || (aPSName.Search("cursive") != STRING_NOTFOUND)
+ || (aPSName.Search("-it") != STRING_NOTFOUND)
+ || (aPSName.Search("lightit") != STRING_NOTFOUND)
+ || (aPSName.Search("mediumit") != STRING_NOTFOUND)
+ || (aPSName.Search("boldit") != STRING_NOTFOUND)
+ || (aPSName.Search("cnit") != STRING_NOTFOUND)
+ || (aPSName.Search("bdcn") != STRING_NOTFOUND)
+ || (aPSName.Search("bdit") != STRING_NOTFOUND)
+ || (aPSName.Search("condit") != STRING_NOTFOUND)
+ || (aPSName.Search("bookit") != STRING_NOTFOUND)
+ || (aPSName.Search("blackit") != STRING_NOTFOUND) )
+ rDFA.meItalic = ITALIC_NORMAL;
+ if( (aPSName.Search("oblique") != STRING_NOTFOUND)
+ || (aPSName.Search("inclined") != STRING_NOTFOUND)
+ || (aPSName.Search("slanted") != STRING_NOTFOUND) )
+ rDFA.meItalic = ITALIC_OBLIQUE;
+
+ // heuristics for font width
+ if( (aPSName.Search("condensed") != STRING_NOTFOUND)
+ || (aPSName.Search("-cond") != STRING_NOTFOUND)
+ || (aPSName.Search("boldcond") != STRING_NOTFOUND)
+ || (aPSName.Search("boldcn") != STRING_NOTFOUND)
+ || (aPSName.Search("cnit") != STRING_NOTFOUND) )
+ rDFA.meWidthType = WIDTH_CONDENSED;
+ else if (aPSName.Search("narrow") != STRING_NOTFOUND)
+ rDFA.meWidthType = WIDTH_SEMI_CONDENSED;
+ else if (aPSName.Search("expanded") != STRING_NOTFOUND)
+ rDFA.meWidthType = WIDTH_EXPANDED;
+ else if (aPSName.Search("wide") != STRING_NOTFOUND)
+ rDFA.meWidthType = WIDTH_EXPANDED;
+
+ // heuristics for font pitch
+ if( (aPSName.Search("mono") != STRING_NOTFOUND)
+ || (aPSName.Search("courier") != STRING_NOTFOUND)
+ || (aPSName.Search("monaco") != STRING_NOTFOUND)
+ || (aPSName.Search("typewriter") != STRING_NOTFOUND) )
+ rDFA.mePitch = PITCH_FIXED;
+
+ // heuristics for font family type
+ if( (aPSName.Search("script") != STRING_NOTFOUND)
+ || (aPSName.Search("chancery") != STRING_NOTFOUND)
+ || (aPSName.Search("zapfino") != STRING_NOTFOUND))
+ rDFA.meFamily = FAMILY_SCRIPT;
+ else if( (aPSName.Search("comic") != STRING_NOTFOUND)
+ || (aPSName.Search("outline") != STRING_NOTFOUND)
+ || (aPSName.Search("pinpoint") != STRING_NOTFOUND) )
+ rDFA.meFamily = FAMILY_DECORATIVE;
+ else if( (aPSName.Search("sans") != STRING_NOTFOUND)
+ || (aPSName.Search("arial") != STRING_NOTFOUND) )
+ rDFA.meFamily = FAMILY_SWISS;
+ else if( (aPSName.Search("roman") != STRING_NOTFOUND)
+ || (aPSName.Search("times") != STRING_NOTFOUND) )
+ rDFA.meFamily = FAMILY_ROMAN;
+
+ // heuristics for codepoint semantic
+ if( (aPSName.Search("symbol") != STRING_NOTFOUND)
+ || (aPSName.Search("dings") != STRING_NOTFOUND)
+ || (aPSName.Search("dingbats") != STRING_NOTFOUND)
+ || (aPSName.Search("braille") != STRING_NOTFOUND)
+ || (aPSName.Search("ornaments") != STRING_NOTFOUND)
+ || (aPSName.Search("embellishments") != STRING_NOTFOUND) )
+ rDFA.mbSymbolFlag = true;
+
+ // #i100020# special heuristic for names with single-char styles
+ // NOTE: we are checking name that hasn't been lower-cased
+ if( rPSName.Len() > 3 )
+ {
+ int i = rPSName.Len();
+ sal_Unicode c = rPSName.GetChar( --i );
+ if( c == 'C' ) { // "capitals"
+ rDFA.meFamily = FAMILY_DECORATIVE;
+ c = rPSName.GetChar( --i );
+ }
+ if( c == 'O' ) { // CFF-based OpenType
+ c = rPSName.GetChar( --i );
+ }
+ if( c == 'I' ) { // "italic"
+ rDFA.meItalic = ITALIC_NORMAL;
+ c = rPSName.GetChar( --i );
+ }
+ if( c == 'B' ) // "bold"
+ rDFA.meWeight = WEIGHT_BOLD;
+ if( c == 'C' ) // "capitals"
+ rDFA.meFamily = FAMILY_DECORATIVE;
+ // TODO: check that all single-char styles have been resolved?
+ }
+}
+
+// =======================================================================
+
diff --git a/vcl/source/gdi/metric.cxx b/vcl/source/gdi/metric.cxx
index c2df97c..2ec76f6 100644
--- a/vcl/source/gdi/metric.cxx
+++ b/vcl/source/gdi/metric.cxx
@@ -233,698 +233,3 @@ sal_Bool FontMetric::operator==( const FontMetric& rMetric ) const
// =======================================================================
-CmapResult::CmapResult( bool bSymbolic,
- const sal_uInt32* pRangeCodes, int nRangeCount,
- const int* pStartGlyphs, const sal_uInt16* pExtraGlyphIds )
-: mpRangeCodes( pRangeCodes)
-, mpStartGlyphs( pStartGlyphs)
-, mpGlyphIds( pExtraGlyphIds)
-, mnRangeCount( nRangeCount)
-, mbSymbolic( bSymbolic)
-, mbRecoded( false)
-{}
-
-// =======================================================================
-
-ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR )
-: mpRangeCodes( rCR.mpRangeCodes )
-, mpStartGlyphs( rCR.mpStartGlyphs )
-, mpGlyphIds( rCR.mpGlyphIds )
-, mnRangeCount( rCR.mnRangeCount )
-, mnCharCount( 0 )
-, mnRefCount( 0 )
-{
- const sal_uInt32* pRangePtr = mpRangeCodes;
- for( int i = mnRangeCount; --i >= 0; pRangePtr += 2 )
- {
- sal_uInt32 cFirst = pRangePtr[0];
- sal_uInt32 cLast = pRangePtr[1];
- mnCharCount += cLast - cFirst;
- }
-}
-
-static ImplFontCharMap* pDefaultUnicodeImplFontCharMap = NULL;
-static ImplFontCharMap* pDefaultSymbolImplFontCharMap = NULL;
-static const sal_uInt32 aDefaultUnicodeRanges[] = {0x0020,0xD800, 0xE000,0xFFF0};
-static const sal_uInt32 aDefaultSymbolRanges[] = {0x0020,0x0100, 0xF020,0xF100};
-
-// -----------------------------------------------------------------------
-
-bool ImplFontCharMap::IsDefaultMap() const
-{
- const bool bIsDefault = (mpRangeCodes == aDefaultUnicodeRanges) || (mpRangeCodes == aDefaultSymbolRanges);
- return bIsDefault;
-}
-
-// -----------------------------------------------------------------------
-
-ImplFontCharMap::~ImplFontCharMap()
-{
- if( IsDefaultMap() )
- return;
- delete[] mpRangeCodes;
- delete[] mpStartGlyphs;
- delete[] mpGlyphIds;
- }
-
-// -----------------------------------------------------------------------
-
-namespace
-{
- ImplFontCharMap *GetDefaultUnicodeMap()
- {
- if( !pDefaultUnicodeImplFontCharMap )
- {
- const sal_uInt32* pRangeCodes = aDefaultUnicodeRanges;
- int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes);
- CmapResult aDefaultCR( false, pRangeCodes, nCodesCount/2 );
- pDefaultUnicodeImplFontCharMap = new ImplFontCharMap( aDefaultCR );
- pDefaultUnicodeImplFontCharMap->AddReference();
- }
-
- return pDefaultUnicodeImplFontCharMap;
- }
-
- ImplFontCharMap *GetDefaultSymbolMap()
- {
- if( !pDefaultSymbolImplFontCharMap )
- {
- const sal_uInt32* pRangeCodes = aDefaultSymbolRanges;
- int nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes);
- CmapResult aDefaultCR( true, pRangeCodes, nCodesCount/2 );
- pDefaultSymbolImplFontCharMap = new ImplFontCharMap( aDefaultCR );
- pDefaultSymbolImplFontCharMap->AddReference();
- }
-
- return pDefaultSymbolImplFontCharMap;
- }
-}
-
-ImplFontCharMap* ImplFontCharMap::GetDefaultMap( bool bSymbols)
-{
- return bSymbols ? GetDefaultSymbolMap() : GetDefaultUnicodeMap();
-}
-
-// -----------------------------------------------------------------------
-
-void ImplFontCharMap::AddReference( void ) const
-{
- // TODO: disable refcounting on the default maps?
- ++mnRefCount;
-}
-
-// -----------------------------------------------------------------------
-
-void ImplFontCharMap::DeReference( void ) const
-{
- if( --mnRefCount <= 0 )
- if( (this != pDefaultUnicodeImplFontCharMap) && (this != pDefaultSymbolImplFontCharMap) )
- delete this;
-}
-
-// -----------------------------------------------------------------------
-
-int ImplFontCharMap::GetCharCount() const
-{
- return mnCharCount;
-}
-
-// -----------------------------------------------------------------------
-
-int ImplFontCharMap::ImplFindRangeIndex( sal_uInt32 cChar ) const
-{
- int nLower = 0;
- int nMid = mnRangeCount;
- int nUpper = 2 * mnRangeCount - 1;
- while( nLower < nUpper )
- {
- if( cChar >= mpRangeCodes[ nMid ] )
- nLower = nMid;
- else
- nUpper = nMid - 1;
- nMid = (nLower + nUpper + 1) / 2;
- }
-
- return nMid;
-}
-
-// -----------------------------------------------------------------------
-
-bool ImplFontCharMap::HasChar( sal_uInt32 cChar ) const
-{
- bool bHasChar = false;
-
- if( mpStartGlyphs == NULL ) { // only the char-ranges are known
- const int nRange = ImplFindRangeIndex( cChar );
- if( nRange==0 && cChar<mpRangeCodes[0] )
- return false;
- bHasChar = ((nRange & 1) == 0); // inside a range
- } else { // glyph mapping is available
- const int nGlyphIndex = GetGlyphIndex( cChar );
- bHasChar = (nGlyphIndex != 0); // not the notdef-glyph
- }
-
- return bHasChar;
-}
-
-// -----------------------------------------------------------------------
-
-int ImplFontCharMap::GetGlyphIndex( sal_uInt32 cChar ) const
-{
- // return -1 if the object doesn't know the glyph ids
- if( !mpStartGlyphs )
- return -1;
-
- // return 0 if the unicode doesn't have a matching glyph
- int nRange = ImplFindRangeIndex( cChar );
- // check that we are inside any range
- if( (nRange == 0) && (cChar < mpRangeCodes[0]) ) {
- // symbol aliasing gives symbol fonts a second chance
- const bool bSymbolic = (mpRangeCodes[0]>=0xF000) & (mpRangeCodes[1]<=0xF0FF);
- if( !bSymbolic )
- return 0;
- // check for symbol aliasing (U+00xx <-> U+F0xx)
- cChar |= 0xF000;
- nRange = ImplFindRangeIndex( cChar );
- }
- // check that we are inside a range
- if( (nRange & 1) != 0 )
- return 0;
-
- // get glyph index directly or indirectly
- int nGlyphIndex = cChar - mpRangeCodes[ nRange ];
- const int nStartIndex = mpStartGlyphs[ nRange/2 ];
- if( nStartIndex >= 0 ) {
- // the glyph index can be calculated
- nGlyphIndex += nStartIndex;
- } else {
- // the glyphid array has the glyph index
- nGlyphIndex = mpGlyphIds[ nGlyphIndex - nStartIndex ];
- }
-
- return nGlyphIndex;
-}
-
-// -----------------------------------------------------------------------
-
-// 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 )
- ++nRangeMin;
- else if( cMin > mpRangeCodes[ nRangeMin ] )
- nCount -= cMin - mpRangeCodes[ nRangeMin ];
-
- // find and adjust range and char count for cMax
- int nRangeMax = ImplFindRangeIndex( cMax );
- if( nRangeMax & 1 )
- --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_uInt32 ImplFontCharMap::GetFirstChar() const
-{
- return mpRangeCodes[0];
-}
-
-// -----------------------------------------------------------------------
-
-sal_uInt32 ImplFontCharMap::GetLastChar() const
-{
- return (mpRangeCodes[ 2*mnRangeCount-1 ] - 1);
-}
-
-// -----------------------------------------------------------------------
-
-sal_uInt32 ImplFontCharMap::GetNextChar( sal_uInt32 cChar ) const
-{
- if( cChar < GetFirstChar() )
- return GetFirstChar();
- if( cChar >= GetLastChar() )
- return GetLastChar();
-
- int nRange = ImplFindRangeIndex( cChar + 1 );
- if( nRange & 1 ) // outside of range?
- return mpRangeCodes[ nRange + 1 ]; // => first in next range
- return (cChar + 1);
-}
-
-// -----------------------------------------------------------------------
-
-sal_uInt32 ImplFontCharMap::GetPrevChar( sal_uInt32 cChar ) const
-{
- if( cChar <= GetFirstChar() )
- return GetFirstChar();
- if( cChar > GetLastChar() )
- return GetLastChar();
-
- int nRange = ImplFindRangeIndex( cChar - 1 );
- if( nRange & 1 ) // outside a range?
- return (mpRangeCodes[ nRange ] - 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 )
- nCharIndex += cLast - cFirst;
- else if( cChar >= cFirst )
- return nCharIndex + (cChar - cFirst);
- else
- break;
- }
-
- 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];
-}
-
-// =======================================================================
-
-static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);}
-static unsigned GetUShort( const unsigned char* p ){ return((p[0]<<8) | p[1]);}
-static int GetSShort( const unsigned char* p ){ return((static_cast<signed char>(p[0])<<8)|p[1]);}
-
-// TODO: move CMAP parsing directly into the ImplFontCharMap class
-bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
-{
- rResult.mpRangeCodes = NULL;
- rResult.mpStartGlyphs= NULL;
- rResult.mpGlyphIds = NULL;
- rResult.mnRangeCount = 0;
- rResult.mbRecoded = false;
- rResult.mbSymbolic = false;
-
- // parse the table header and check for validity
- if( !pCmap || (nLength < 24) )
- return false;
-
- if( GetUShort( pCmap ) != 0x0000 ) // simple check for CMAP corruption
- return false;
-
- int nSubTables = GetUShort( pCmap + 2 );
- if( (nSubTables <= 0) || (nLength < (24 + 8*nSubTables)) )
- return false;
-
- // find the most interesting subtable in the CMAP
- rtl_TextEncoding eRecodeFrom = RTL_TEXTENCODING_UNICODE;
- int nOffset = 0;
- int nFormat = -1;
- int nBestVal = 0;
- for( const unsigned char* p = pCmap + 4; --nSubTables >= 0; p += 8 )
- {
- int nPlatform = GetUShort( p );
- int nEncoding = GetUShort( p+2 );
- int nPlatformEncoding = (nPlatform << 8) + nEncoding;
-
- int nValue;
- rtl_TextEncoding eTmpEncoding = RTL_TEXTENCODING_UNICODE;
- switch( nPlatformEncoding )
- {
- case 0x000: nValue = 20; break; // Unicode 1.0
- case 0x001: nValue = 21; break; // Unicode 1.1
- case 0x002: nValue = 22; break; // iso10646_1993
- case 0x003: nValue = 23; break; // UCS-2
- case 0x004: nValue = 24; break; // UCS-4
- case 0x100: nValue = 22; break; // Mac Unicode<2.0
- case 0x103: nValue = 23; break; // Mac Unicode>2.0
- case 0x300: nValue = 5; rResult.mbSymbolic = true; break; // Win Symbol
- case 0x301: nValue = 28; break; // Win UCS-2
- case 0x30A: nValue = 29; break; // Win-UCS-4
- case 0x302: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_SHIFT_JIS; break;
- case 0x303: nValue = 12; eTmpEncoding = RTL_TEXTENCODING_GB_18030; break;
- case 0x304: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_BIG5; break;
- case 0x305: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_MS_949; break;
- case 0x306: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_MS_1361; break;
- default: nValue = 0; break;
- }
-
- if( nValue <= 0 ) // ignore unknown encodings
- continue;
-
- int nTmpOffset = GetUInt( p+4 );
- int nTmpFormat = GetUShort( pCmap + nTmpOffset );
- if( nTmpFormat == 12 ) // 32bit code -> glyph map format
- nValue += 3;
- else if( nTmpFormat != 4 ) // 16bit code -> glyph map format
- continue; // ignore other formats
-
- if( nBestVal < nValue )
- {
- nBestVal = nValue;
- nOffset = nTmpOffset;
- nFormat = nTmpFormat;
- eRecodeFrom = eTmpEncoding;
- }
- }
-
- // parse the best CMAP subtable
- int nRangeCount = 0;
- sal_uInt32* pCodePairs = NULL;
- int* pStartGlyphs = NULL;
-
- typedef std::vector<sal_uInt16> U16Vector;
- U16Vector aGlyphIdArray;
- aGlyphIdArray.reserve( 0x1000 );
- aGlyphIdArray.push_back( 0 );
-
- // format 4, the most common 16bit char mapping table
- if( (nFormat == 4) && ((nOffset+16) < nLength) )
- {
- int nSegCountX2 = GetUShort( pCmap + nOffset + 6 );
- nRangeCount = nSegCountX2/2 - 1;
- pCodePairs = new sal_uInt32[ nRangeCount * 2 ];
- pStartGlyphs = new int[ nRangeCount ];
- const unsigned char* pLimitBase = pCmap + nOffset + 14;
- const unsigned char* pBeginBase = pLimitBase + nSegCountX2 + 2;
- const unsigned char* pDeltaBase = pBeginBase + nSegCountX2;
- const unsigned char* pOffsetBase = pDeltaBase + nSegCountX2;
- sal_uInt32* pCP = pCodePairs;
- for( int i = 0; i < nRangeCount; ++i )
- {
- const sal_uInt32 cMinChar = GetUShort( pBeginBase + 2*i );
- const sal_uInt32 cMaxChar = GetUShort( pLimitBase + 2*i );
- const int nGlyphDelta = GetSShort( pDeltaBase + 2*i );
- const int nRangeOffset = GetUShort( pOffsetBase + 2*i );
- if( cMinChar > cMaxChar ) // no sane font should trigger this
- break;
- if( cMaxChar == 0xFFFF )
- break;
- *(pCP++) = cMinChar;
- *(pCP++) = cMaxChar + 1;
- if( !nRangeOffset ) {
- // glyphid can be calculated directly
- pStartGlyphs[i] = (cMinChar + nGlyphDelta) & 0xFFFF;
- } else {
- // update the glyphid-array with the glyphs in this range
- pStartGlyphs[i] = -(int)aGlyphIdArray.size();
- const unsigned char* pGlyphIdPtr = pOffsetBase + 2*i + nRangeOffset;
- for( sal_uInt32 c = cMinChar; c <= cMaxChar; ++c, pGlyphIdPtr+=2 ) {
- const int nGlyphIndex = GetUShort( pGlyphIdPtr ) + nGlyphDelta;
- aGlyphIdArray.push_back( static_cast<sal_uInt16>(nGlyphIndex) );
- }
- }
- }
- nRangeCount = (pCP - pCodePairs) / 2;
- }
- // format 12, the most common 32bit char mapping table
- else if( (nFormat == 12) && ((nOffset+16) < nLength) )
- {
- nRangeCount = GetUInt( pCmap + nOffset + 12 );
- pCodePairs = new sal_uInt32[ nRangeCount * 2 ];
- pStartGlyphs = new int[ nRangeCount ];
- const unsigned char* pGroup = pCmap + nOffset + 16;
- sal_uInt32* pCP = pCodePairs;
- for( int i = 0; i < nRangeCount; ++i )
- {
- sal_uInt32 cMinChar = GetUInt( pGroup + 0 );
- sal_uInt32 cMaxChar = GetUInt( pGroup + 4 );
- int nGlyphId = GetUInt( pGroup + 8 );
- pGroup += 12;
-#if 0 // TODO: remove unicode baseplane clipping for UCS-4 support
- if( cMinChar > 0xFFFF )
- continue;
- if( cMaxChar > 0xFFFF )
- cMaxChar = 0xFFFF;
-#else
- if( cMinChar > cMaxChar ) // no sane font should trigger this
- break;
-#endif
- *(pCP++) = cMinChar;
- *(pCP++) = cMaxChar + 1;
- pStartGlyphs[i] = nGlyphId;
- }
- nRangeCount = (pCP - pCodePairs) / 2;
- }
-
- // check if any subtable resulted in something usable
- if( nRangeCount <= 0 )
- {
- delete[] pCodePairs;
- delete[] pStartGlyphs;
-
- // even when no CMAP is available we know it for symbol fonts
- if( rResult.mbSymbolic )
- {
- pCodePairs = new sal_uInt32[4];
- pCodePairs[0] = 0x0020; // aliased symbols
- pCodePairs[1] = 0x0100;
- pCodePairs[2] = 0xF020; // original symbols
- pCodePairs[3] = 0xF100;
- rResult.mpRangeCodes = pCodePairs;
- rResult.mnRangeCount = 2;
- return true;
- }
-
- return false;
- }
-
- // recode the code ranges to their unicode encoded ranges if needed
- rtl_TextToUnicodeConverter aConverter = NULL;
- rtl_UnicodeToTextContext aCvtContext = NULL;
-
- rResult.mbRecoded = ( eRecodeFrom != RTL_TEXTENCODING_UNICODE );
- if( rResult.mbRecoded )
- {
- aConverter = rtl_createTextToUnicodeConverter( eRecodeFrom );
- aCvtContext = rtl_createTextToUnicodeContext( aConverter );
- }
-
- if( aConverter && aCvtContext )
- {
- // determine the set of supported unicodes from encoded ranges
- typedef std::set<sal_uInt32> IntSet;
- IntSet aSupportedUnicodes;
-
- static const int NINSIZE = 64;
- static const int NOUTSIZE = 64;
- sal_Char cCharsInp[ NINSIZE ];
- sal_Unicode cCharsOut[ NOUTSIZE ];
- sal_uInt32* pCP = pCodePairs;
- for( int i = 0; i < nRangeCount; ++i )
- {
- sal_uInt32 cMin = *(pCP++);
- sal_uInt32 cEnd = *(pCP++);
- while( cMin < cEnd )
- {
- int j = 0;
- for (; (cMin < cEnd) && (j < (NINSIZE-1)); ++cMin)
- {
- if( cMin >= 0x0100 )
- cCharsInp[ j++ ] = static_cast<sal_Char>(cMin >> 8);
- if( (cMin >= 0x0100) || (cMin < 0x00A0) )
- cCharsInp[ j++ ] = static_cast<sal_Char>(cMin);
- }
-
- sal_uInt32 nCvtInfo;
- sal_Size nSrcCvtBytes;
- int nOutLen = rtl_convertTextToUnicode(
- aConverter, aCvtContext,
- cCharsInp, j, cCharsOut, NOUTSIZE,
- RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE
- | RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE,
- &nCvtInfo, &nSrcCvtBytes );
-
- for( j = 0; j < nOutLen; ++j )
- aSupportedUnicodes.insert( cCharsOut[j] );
- }
- }
-
- rtl_destroyTextToUnicodeConverter( aCvtContext );
- rtl_destroyTextToUnicodeConverter( aConverter );
-
- // convert the set of supported unicodes to ranges
- typedef std::vector<sal_uInt32> IntVector;
- IntVector aSupportedRanges;
-
- IntSet::const_iterator itChar = aSupportedUnicodes.begin();
- for(; itChar != aSupportedUnicodes.end(); ++itChar )
- {
- if( aSupportedRanges.empty()
- || (aSupportedRanges.back() != *itChar) )
- {
- // add new range beginning with current unicode
- aSupportedRanges.push_back( *itChar );
- aSupportedRanges.push_back( 0 );
- }
-
- // extend existing range to include current unicode
- aSupportedRanges.back() = *itChar + 1;
- }
-
- // glyph mapping for non-unicode fonts not implemented
- delete[] pStartGlyphs;
- pStartGlyphs = NULL;
- aGlyphIdArray.clear();
-
- // make a pCodePairs array using the vector from above
- delete[] pCodePairs;
- nRangeCount = aSupportedRanges.size() / 2;
- if( nRangeCount <= 0 )
- return false;
- pCodePairs = new sal_uInt32[ nRangeCount * 2 ];
- IntVector::const_iterator itInt = aSupportedRanges.begin();
- for( pCP = pCodePairs; itInt != aSupportedRanges.end(); ++itInt )
- *(pCP++) = *itInt;
- }
-
- // prepare the glyphid-array if needed
- // TODO: merge ranges if they are close enough?
- sal_uInt16* pGlyphIds = NULL;
- if( !aGlyphIdArray.empty())
- {
- pGlyphIds = new sal_uInt16[ aGlyphIdArray.size() ];
- sal_uInt16* pOut = pGlyphIds;
- U16Vector::const_iterator it = aGlyphIdArray.begin();
- while( it != aGlyphIdArray.end() )
- *(pOut++) = *(it++);
- }
-
- // update the result struct
- rResult.mpRangeCodes = pCodePairs;
- rResult.mpStartGlyphs = pStartGlyphs;
- rResult.mnRangeCount = nRangeCount;
- rResult.mpGlyphIds = pGlyphIds;
- return true;
-}
-
-// =======================================================================
-
-FontCharMap::FontCharMap()
-: mpImpl( ImplFontCharMap::GetDefaultMap() )
-{
- mpImpl->AddReference();
-}
-
-// -----------------------------------------------------------------------
-
-FontCharMap::~FontCharMap()
-{
- mpImpl->DeReference();
- mpImpl = NULL;
-}
-
-// -----------------------------------------------------------------------
-
-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( const ImplFontCharMap* pNewMap )
-{
- mpImpl->DeReference();
- if( pNewMap == NULL )
- mpImpl = ImplFontCharMap::GetDefaultMap();
- else if( pNewMap != mpImpl )
- mpImpl = pNewMap;
- mpImpl->AddReference();
-}
-
-// -----------------------------------------------------------------------
-
-sal_Bool FontCharMap::IsDefaultMap() const
-{
- return mpImpl->IsDefaultMap();
-}
-
-// -----------------------------------------------------------------------
-
-sal_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 );
-}
-
-// =======================================================================
-
More information about the Libreoffice-commits
mailing list