LCOV - code coverage report
Current view: top level - vcl/source/gdi - metric.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 238 426 55.9 %
Date: 2012-08-25 Functions: 36 56 64.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 96 314 30.6 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <impfont.hxx>
      31                 :            : #include <vcl/metric.hxx>
      32                 :            : 
      33                 :            : #include <vector>
      34                 :            : #include <set>
      35                 :            : 
      36                 :            : #include <cstdio>
      37                 :            : 
      38                 :            : // =======================================================================
      39                 :            : 
      40                 :    1143989 : ImplFontMetric::ImplFontMetric()
      41                 :            : :   mnAscent( 0 ),
      42                 :            :     mnDescent( 0 ),
      43                 :            :     mnIntLeading( 0 ),
      44                 :            :     mnExtLeading( 0 ),
      45                 :            :     mnLineHeight( 0 ),
      46                 :            :     mnSlant( 0 ),
      47                 :            :     mnMiscFlags( 0 ),
      48                 :    1143989 :     mnRefCount( 1 )
      49                 :    1143989 : {}
      50                 :            : 
      51                 :            : // -----------------------------------------------------------------------
      52                 :            : 
      53                 :     597757 : inline void ImplFontMetric::AddReference()
      54                 :            : {
      55                 :            :     // TODO: disable refcounting on the default maps?
      56                 :     597757 :     ++mnRefCount;
      57                 :     597757 : }
      58                 :            : 
      59                 :            : // -----------------------------------------------------------------------
      60                 :            : 
      61                 :    1718228 : inline void ImplFontMetric::DeReference()
      62                 :            : {
      63                 :            :     // TODO: disable refcounting on the default maps?
      64         [ +  + ]:    1718228 :     if( --mnRefCount <= 0 )
      65                 :    1120471 :         delete this;
      66                 :    1718228 : }
      67                 :            : 
      68                 :            : // -----------------------------------------------------------------------
      69                 :            : 
      70                 :          0 : bool ImplFontMetric::operator==( const ImplFontMetric& r ) const
      71                 :            : {
      72         [ #  # ]:          0 :     if( mnMiscFlags  != r.mnMiscFlags )
      73                 :          0 :         return false;
      74         [ #  # ]:          0 :     if( mnAscent     != r.mnAscent )
      75                 :          0 :         return false;
      76         [ #  # ]:          0 :     if( mnDescent    != r.mnDescent )
      77                 :          0 :         return false;
      78         [ #  # ]:          0 :     if( mnIntLeading != r.mnIntLeading )
      79                 :          0 :         return false;
      80         [ #  # ]:          0 :     if( mnExtLeading != r.mnExtLeading )
      81                 :          0 :         return false;
      82         [ #  # ]:          0 :     if( mnSlant      != r.mnSlant )
      83                 :          0 :         return false;
      84                 :            : 
      85                 :          0 :     return true;
      86                 :            : }
      87                 :            : 
      88                 :            : // =======================================================================
      89                 :            : 
      90                 :    1143989 : FontInfo::FontInfo()
      91         [ +  - ]:    1143989 : :   mpImplMetric( new ImplFontMetric )
      92                 :    1143989 : {}
      93                 :            : 
      94                 :            : // -----------------------------------------------------------------------
      95                 :            : 
      96                 :     594330 : FontInfo::FontInfo( const FontInfo& rInfo )
      97                 :     594330 : :  Font( rInfo )
      98                 :            : {
      99                 :     594330 :     mpImplMetric = rInfo.mpImplMetric;
     100                 :     594330 :     mpImplMetric->AddReference();
     101                 :     594330 : }
     102                 :            : 
     103                 :            : // -----------------------------------------------------------------------
     104                 :            : 
     105                 :    1714801 : FontInfo::~FontInfo()
     106                 :            : {
     107                 :    1714801 :     mpImplMetric->DeReference();
     108                 :    1714801 : }
     109                 :            : 
     110                 :            : // -----------------------------------------------------------------------
     111                 :            : 
     112                 :       3427 : FontInfo& FontInfo::operator=( const FontInfo& rInfo )
     113                 :            : {
     114                 :       3427 :     Font::operator=( rInfo );
     115                 :            : 
     116         [ +  - ]:       3427 :     if( mpImplMetric != rInfo.mpImplMetric )
     117                 :            :     {
     118                 :       3427 :         mpImplMetric->DeReference();
     119                 :       3427 :         mpImplMetric = rInfo.mpImplMetric;
     120                 :       3427 :         mpImplMetric->AddReference();
     121                 :            :     }
     122                 :            : 
     123                 :       3427 :     return *this;
     124                 :            : }
     125                 :            : 
     126                 :            : // -----------------------------------------------------------------------
     127                 :            : 
     128                 :          0 : sal_Bool FontInfo::operator==( const FontInfo& rInfo ) const
     129                 :            : {
     130         [ #  # ]:          0 :     if( !Font::operator==( rInfo ) )
     131                 :          0 :         return sal_False;
     132         [ #  # ]:          0 :     if( mpImplMetric == rInfo.mpImplMetric )
     133                 :          0 :         return sal_True;
     134         [ #  # ]:          0 :     if( *mpImplMetric == *rInfo.mpImplMetric  )
     135                 :          0 :         return sal_True;
     136                 :          0 :     return sal_False;
     137                 :            : }
     138                 :            : 
     139                 :            : // -----------------------------------------------------------------------
     140                 :            : 
     141                 :     752769 : FontType FontInfo::GetType() const
     142                 :            : {
     143         [ +  - ]:     752769 :     return (mpImplMetric->IsScalable() ? TYPE_SCALABLE : TYPE_RASTER);
     144                 :            : }
     145                 :            : 
     146                 :          0 : FontMetric::FontMetric( const FontMetric& rMetric )
     147                 :          0 : :    FontInfo( rMetric )
     148                 :          0 : {}
     149                 :            : 
     150                 :            : // -----------------------------------------------------------------------
     151                 :            : 
     152                 :     522721 : long FontMetric::GetAscent() const
     153                 :            : {
     154                 :     522721 :     return mpImplMetric->GetAscent();
     155                 :            : }
     156                 :            : 
     157                 :            : // -----------------------------------------------------------------------
     158                 :            : 
     159                 :     450533 : long FontMetric::GetDescent() const
     160                 :            : {
     161                 :     450533 :     return mpImplMetric->GetDescent();
     162                 :            : }
     163                 :            : 
     164                 :            : // -----------------------------------------------------------------------
     165                 :            : 
     166                 :     889347 : long FontMetric::GetIntLeading() const
     167                 :            : {
     168                 :     889347 :     return mpImplMetric->GetIntLeading();
     169                 :            : }
     170                 :            : 
     171                 :            : // -----------------------------------------------------------------------
     172                 :            : 
     173                 :       3864 : long FontMetric::GetExtLeading() const
     174                 :            : {
     175                 :       3864 :     return mpImplMetric->GetExtLeading();
     176                 :            : }
     177                 :            : 
     178                 :            : // -----------------------------------------------------------------------
     179                 :            : 
     180                 :          0 : long FontMetric::GetLineHeight() const
     181                 :            : {
     182                 :          0 :     return mpImplMetric->GetLineHeight();
     183                 :            : }
     184                 :            : 
     185                 :            : // -----------------------------------------------------------------------
     186                 :            : 
     187                 :          0 : long FontMetric::GetSlant() const
     188                 :            : {
     189                 :          0 :     return mpImplMetric->GetSlant();
     190                 :            : }
     191                 :            : 
     192                 :            : // -----------------------------------------------------------------------
     193                 :            : 
     194                 :       1583 : FontMetric& FontMetric::operator =( const FontMetric& rMetric )
     195                 :            : {
     196                 :       1583 :     FontInfo::operator=( rMetric );
     197                 :       1583 :     return *this;
     198                 :            : }
     199                 :            : 
     200                 :            : // -----------------------------------------------------------------------
     201                 :            : 
     202                 :          0 : sal_Bool FontMetric::operator==( const FontMetric& rMetric ) const
     203                 :            : {
     204                 :          0 :     return FontInfo::operator==( rMetric );
     205                 :            : }
     206                 :            : 
     207                 :            : // =======================================================================
     208                 :            : 
     209                 :        484 : CmapResult::CmapResult( bool bSymbolic,
     210                 :            :     const sal_uInt32* pRangeCodes, int nRangeCount,
     211                 :            :     const int* pStartGlyphs, const sal_uInt16* pExtraGlyphIds )
     212                 :            : :   mpRangeCodes( pRangeCodes)
     213                 :            : ,   mpStartGlyphs( pStartGlyphs)
     214                 :            : ,   mpGlyphIds( pExtraGlyphIds)
     215                 :            : ,   mnRangeCount( nRangeCount)
     216                 :            : ,   mbSymbolic( bSymbolic)
     217                 :        484 : ,   mbRecoded( false)
     218                 :        484 : {}
     219                 :            : 
     220                 :            : // =======================================================================
     221                 :            : 
     222                 :        484 : ImplFontCharMap::ImplFontCharMap( const CmapResult& rCR )
     223                 :            : :   mpRangeCodes( rCR.mpRangeCodes )
     224                 :            : ,   mpStartGlyphs( rCR.mpStartGlyphs )
     225                 :            : ,   mpGlyphIds( rCR.mpGlyphIds )
     226                 :            : ,   mnRangeCount( rCR.mnRangeCount )
     227                 :            : ,   mnCharCount( 0 )
     228                 :        484 : ,   mnRefCount( 0 )
     229                 :            : {
     230                 :        484 :     const sal_uInt32* pRangePtr = mpRangeCodes;
     231         [ +  + ]:      61905 :     for( int i = mnRangeCount; --i >= 0; pRangePtr += 2 )
     232                 :            :     {
     233                 :      61421 :         sal_uInt32 cFirst = pRangePtr[0];
     234                 :      61421 :         sal_uInt32 cLast  = pRangePtr[1];
     235                 :      61421 :         mnCharCount += cLast - cFirst;
     236                 :            :     }
     237                 :        484 : }
     238                 :            : 
     239                 :            : static ImplFontCharMap* pDefaultUnicodeImplFontCharMap = NULL;
     240                 :            : static ImplFontCharMap* pDefaultSymbolImplFontCharMap = NULL;
     241                 :            : static const sal_uInt32 aDefaultUnicodeRanges[] = {0x0020,0xD800, 0xE000,0xFFF0};
     242                 :            : static const sal_uInt32 aDefaultSymbolRanges[] = {0x0020,0x0100, 0xF020,0xF100};
     243                 :            : 
     244                 :            : // -----------------------------------------------------------------------
     245                 :            : 
     246                 :      10985 : bool ImplFontCharMap::IsDefaultMap() const
     247                 :            : {
     248 [ +  - ][ -  + ]:      10985 :     const bool bIsDefault = (mpRangeCodes == aDefaultUnicodeRanges) || (mpRangeCodes == aDefaultSymbolRanges);
     249                 :      10985 :     return bIsDefault;
     250                 :            : }
     251                 :            : 
     252                 :            : // -----------------------------------------------------------------------
     253                 :            : 
     254                 :        538 : ImplFontCharMap::~ImplFontCharMap()
     255                 :            : {
     256         [ -  + ]:        269 :     if( IsDefaultMap() )
     257                 :          0 :         return;
     258         [ +  - ]:        269 :     delete[] mpRangeCodes;
     259         [ +  + ]:        269 :     delete[] mpStartGlyphs;
     260         [ +  + ]:        269 :     delete[] mpGlyphIds;
     261         [ -  + ]:        538 :  }
     262                 :            : 
     263                 :            : // -----------------------------------------------------------------------
     264                 :            : 
     265                 :            : namespace
     266                 :            : {
     267                 :      21432 :     ImplFontCharMap *GetDefaultUnicodeMap()
     268                 :            :     {
     269         [ +  + ]:      21432 :         if( !pDefaultUnicodeImplFontCharMap )
     270                 :            :         {
     271                 :        215 :             const sal_uInt32* pRangeCodes = aDefaultUnicodeRanges;
     272                 :        215 :             int nCodesCount = sizeof(aDefaultUnicodeRanges) / sizeof(*pRangeCodes);
     273         [ +  - ]:        215 :             CmapResult aDefaultCR( false, pRangeCodes, nCodesCount/2 );
     274 [ +  - ][ +  - ]:        215 :             pDefaultUnicodeImplFontCharMap = new ImplFontCharMap( aDefaultCR );
     275         [ +  - ]:        215 :             pDefaultUnicodeImplFontCharMap->AddReference();
     276                 :            :         }
     277                 :            : 
     278                 :      21432 :         return pDefaultUnicodeImplFontCharMap;
     279                 :            :     }
     280                 :            : 
     281                 :          0 :     ImplFontCharMap *GetDefaultSymbolMap()
     282                 :            :     {
     283         [ #  # ]:          0 :         if( !pDefaultSymbolImplFontCharMap )
     284                 :            :         {
     285                 :          0 :             const sal_uInt32* pRangeCodes = aDefaultSymbolRanges;
     286                 :          0 :             int nCodesCount = sizeof(aDefaultSymbolRanges) / sizeof(*pRangeCodes);
     287         [ #  # ]:          0 :             CmapResult aDefaultCR( true, pRangeCodes, nCodesCount/2 );
     288 [ #  # ][ #  # ]:          0 :             pDefaultSymbolImplFontCharMap = new ImplFontCharMap( aDefaultCR );
     289         [ #  # ]:          0 :             pDefaultSymbolImplFontCharMap->AddReference();
     290                 :            :         }
     291                 :            : 
     292                 :          0 :         return pDefaultSymbolImplFontCharMap;
     293                 :            :     }
     294                 :            : }
     295                 :            : 
     296                 :      21432 : ImplFontCharMap* ImplFontCharMap::GetDefaultMap( bool bSymbols)
     297                 :            : {
     298         [ -  + ]:      21432 :     return bSymbols ? GetDefaultSymbolMap() : GetDefaultUnicodeMap();
     299                 :            : }
     300                 :            : 
     301                 :            : // -----------------------------------------------------------------------
     302                 :            : 
     303                 :      32632 : void ImplFontCharMap::AddReference( void ) const
     304                 :            : {
     305                 :            :     // TODO: disable refcounting on the default maps?
     306                 :      32632 :     ++mnRefCount;
     307                 :      32632 : }
     308                 :            : 
     309                 :            : // -----------------------------------------------------------------------
     310                 :            : 
     311                 :      32417 : void ImplFontCharMap::DeReference( void ) const
     312                 :            : {
     313         [ +  + ]:      32417 :     if( --mnRefCount <= 0 )
     314 [ +  - ][ +  - ]:        269 :         if( (this != pDefaultUnicodeImplFontCharMap) && (this != pDefaultSymbolImplFontCharMap) )
     315         [ +  - ]:        269 :             delete this;
     316                 :      32417 : }
     317                 :            : 
     318                 :            : // -----------------------------------------------------------------------
     319                 :            : 
     320                 :          0 : int ImplFontCharMap::GetCharCount() const
     321                 :            : {
     322                 :          0 :     return mnCharCount;
     323                 :            : }
     324                 :            : 
     325                 :            : // -----------------------------------------------------------------------
     326                 :            : 
     327                 :      44603 : int ImplFontCharMap::ImplFindRangeIndex( sal_uInt32 cChar ) const
     328                 :            : {
     329                 :      44603 :     int nLower = 0;
     330                 :      44603 :     int nMid   = mnRangeCount;
     331                 :      44603 :     int nUpper = 2 * mnRangeCount - 1;
     332         [ +  + ]:     420137 :     while( nLower < nUpper )
     333                 :            :     {
     334         [ +  + ]:     375534 :         if( cChar >= mpRangeCodes[ nMid ] )
     335                 :     208017 :             nLower = nMid;
     336                 :            :         else
     337                 :     167517 :             nUpper = nMid - 1;
     338                 :     375534 :         nMid = (nLower + nUpper + 1) / 2;
     339                 :            :     }
     340                 :            : 
     341                 :      44603 :     return nMid;
     342                 :            : }
     343                 :            : 
     344                 :            : // -----------------------------------------------------------------------
     345                 :            : 
     346                 :      44603 : bool ImplFontCharMap::HasChar( sal_uInt32 cChar ) const
     347                 :            : {
     348                 :      44603 :     bool bHasChar = false;
     349                 :            : 
     350         [ -  + ]:      44603 :     if( mpStartGlyphs  == NULL ) { // only the char-ranges are known
     351                 :          0 :         const int nRange = ImplFindRangeIndex( cChar );
     352 [ #  # ][ #  # ]:          0 :         if( nRange==0 && cChar<mpRangeCodes[0] )
     353                 :          0 :             return false;
     354                 :          0 :         bHasChar = ((nRange & 1) == 0); // inside a range
     355                 :            :     } else { // glyph mapping is available
     356                 :      44603 :         const int nGlyphIndex = GetGlyphIndex( cChar );
     357                 :      44603 :         bHasChar = (nGlyphIndex != 0); // not the notdef-glyph
     358                 :            :     }
     359                 :            : 
     360                 :      44603 :     return bHasChar;
     361                 :            : }
     362                 :            : 
     363                 :            : // -----------------------------------------------------------------------
     364                 :            : 
     365                 :      44603 : int ImplFontCharMap::GetGlyphIndex( sal_uInt32 cChar ) const
     366                 :            : {
     367                 :            :     // return -1 if the object doesn't know the glyph ids
     368         [ -  + ]:      44603 :     if( !mpStartGlyphs )
     369                 :          0 :         return -1;
     370                 :            : 
     371                 :            :     // return 0 if the unicode doesn't have a matching glyph
     372                 :      44603 :     int nRange = ImplFindRangeIndex( cChar );
     373                 :            :     // check that we are inside any range
     374 [ -  + ][ +  + ]:      44603 :     if( (nRange == 0) && (cChar < mpRangeCodes[0]) ) {
     375                 :            :         // symbol aliasing gives symbol fonts a second chance
     376                 :          0 :         const bool bSymbolic = (mpRangeCodes[0]>=0xF000) & (mpRangeCodes[1]<=0xF0FF);
     377         [ #  # ]:          0 :         if( !bSymbolic )
     378                 :          0 :             return 0;
     379                 :            :         // check for symbol aliasing (U+00xx <-> U+F0xx)
     380                 :          0 :         cChar |= 0xF000;
     381                 :          0 :         nRange = ImplFindRangeIndex( cChar );
     382                 :            :     }
     383                 :            :     // check that we are inside a range
     384         [ +  + ]:      44603 :     if( (nRange & 1) != 0 )
     385                 :      32912 :         return 0;
     386                 :            : 
     387                 :            :     // get glyph index directly or indirectly
     388                 :      11691 :     int nGlyphIndex = cChar - mpRangeCodes[ nRange ];
     389                 :      11691 :     const int nStartIndex = mpStartGlyphs[ nRange/2 ];
     390         [ +  - ]:      11691 :     if( nStartIndex >= 0 ) {
     391                 :            :         // the glyph index can be calculated
     392                 :      11691 :         nGlyphIndex += nStartIndex;
     393                 :            :     } else {
     394                 :            :         // the glyphid array has the glyph index
     395                 :          0 :         nGlyphIndex = mpGlyphIds[ nGlyphIndex - nStartIndex ];
     396                 :            :     }
     397                 :            : 
     398                 :      44603 :     return nGlyphIndex;
     399                 :            : }
     400                 :            : 
     401                 :            : // -----------------------------------------------------------------------
     402                 :            : 
     403                 :            : // returns the number of chars supported by the font, which
     404                 :            : // are inside the unicode range from cMin to cMax (inclusive)
     405                 :          0 : int ImplFontCharMap::CountCharsInRange( sal_uInt32 cMin, sal_uInt32 cMax ) const
     406                 :            : {
     407                 :          0 :     int nCount = 0;
     408                 :            : 
     409                 :            :     // find and adjust range and char count for cMin
     410                 :          0 :     int nRangeMin = ImplFindRangeIndex( cMin );
     411         [ #  # ]:          0 :     if( nRangeMin & 1 )
     412                 :          0 :         ++nRangeMin;
     413         [ #  # ]:          0 :     else if( cMin > mpRangeCodes[ nRangeMin ] )
     414                 :          0 :         nCount -= cMin - mpRangeCodes[ nRangeMin ];
     415                 :            : 
     416                 :            :     // find and adjust range and char count for cMax
     417                 :          0 :     int nRangeMax = ImplFindRangeIndex( cMax );
     418         [ #  # ]:          0 :     if( nRangeMax & 1 )
     419                 :          0 :         --nRangeMax;
     420                 :            :     else
     421                 :          0 :         nCount -= mpRangeCodes[ nRangeMax+1 ] - cMax - 1;
     422                 :            : 
     423                 :            :     // count chars in complete ranges between cMin and cMax
     424         [ #  # ]:          0 :     for( int i = nRangeMin; i <= nRangeMax; i+=2 )
     425                 :          0 :         nCount += mpRangeCodes[i+1] - mpRangeCodes[i];
     426                 :            : 
     427                 :          0 :     return nCount;
     428                 :            : }
     429                 :            : 
     430                 :            : // -----------------------------------------------------------------------
     431                 :            : 
     432                 :       1655 : sal_uInt32 ImplFontCharMap::GetFirstChar() const
     433                 :            : {
     434                 :       1655 :     return mpRangeCodes[0];
     435                 :            : }
     436                 :            : 
     437                 :            : // -----------------------------------------------------------------------
     438                 :            : 
     439                 :          0 : sal_uInt32 ImplFontCharMap::GetLastChar() const
     440                 :            : {
     441                 :          0 :     return (mpRangeCodes[ 2*mnRangeCount-1 ] - 1);
     442                 :            : }
     443                 :            : 
     444                 :            : // -----------------------------------------------------------------------
     445                 :            : 
     446                 :          0 : sal_uInt32 ImplFontCharMap::GetNextChar( sal_uInt32 cChar ) const
     447                 :            : {
     448         [ #  # ]:          0 :     if( cChar < GetFirstChar() )
     449                 :          0 :         return GetFirstChar();
     450         [ #  # ]:          0 :     if( cChar >= GetLastChar() )
     451                 :          0 :         return GetLastChar();
     452                 :            : 
     453                 :          0 :     int nRange = ImplFindRangeIndex( cChar + 1 );
     454         [ #  # ]:          0 :     if( nRange & 1 )                       // outside of range?
     455                 :          0 :         return mpRangeCodes[ nRange + 1 ]; // => first in next range
     456                 :          0 :     return (cChar + 1);
     457                 :            : }
     458                 :            : 
     459                 :            : // -----------------------------------------------------------------------
     460                 :            : 
     461                 :          0 : sal_uInt32 ImplFontCharMap::GetPrevChar( sal_uInt32 cChar ) const
     462                 :            : {
     463         [ #  # ]:          0 :     if( cChar <= GetFirstChar() )
     464                 :          0 :         return GetFirstChar();
     465         [ #  # ]:          0 :     if( cChar > GetLastChar() )
     466                 :          0 :         return GetLastChar();
     467                 :            : 
     468                 :          0 :     int nRange = ImplFindRangeIndex( cChar - 1 );
     469         [ #  # ]:          0 :     if( nRange & 1 )                            // outside a range?
     470                 :          0 :         return (mpRangeCodes[ nRange ] - 1);    // => last in prev range
     471                 :          0 :     return (cChar - 1);
     472                 :            : }
     473                 :            : 
     474                 :            : // -----------------------------------------------------------------------
     475                 :            : 
     476                 :          0 : int ImplFontCharMap::GetIndexFromChar( sal_uInt32 cChar ) const
     477                 :            : {
     478                 :            :     // TODO: improve linear walk?
     479                 :          0 :     int nCharIndex = 0;
     480                 :          0 :     const sal_uInt32* pRange = &mpRangeCodes[0];
     481         [ #  # ]:          0 :     for( int i = 0; i < mnRangeCount; ++i )
     482                 :            :     {
     483                 :          0 :         sal_uInt32 cFirst = *(pRange++);
     484                 :          0 :         sal_uInt32 cLast  = *(pRange++);
     485         [ #  # ]:          0 :         if( cChar >= cLast )
     486                 :          0 :             nCharIndex += cLast - cFirst;
     487         [ #  # ]:          0 :         else if( cChar >= cFirst )
     488                 :          0 :             return nCharIndex + (cChar - cFirst);
     489                 :            :         else
     490                 :          0 :             break;
     491                 :            :     }
     492                 :            : 
     493                 :          0 :     return -1;
     494                 :            : }
     495                 :            : 
     496                 :            : // -----------------------------------------------------------------------
     497                 :            : 
     498                 :          0 : sal_uInt32 ImplFontCharMap::GetCharFromIndex( int nCharIndex ) const
     499                 :            : {
     500                 :            :     // TODO: improve linear walk?
     501                 :          0 :     const sal_uInt32* pRange = &mpRangeCodes[0];
     502         [ #  # ]:          0 :     for( int i = 0; i < mnRangeCount; ++i )
     503                 :            :     {
     504                 :          0 :         sal_uInt32 cFirst = *(pRange++);
     505                 :          0 :         sal_uInt32 cLast  = *(pRange++);
     506                 :          0 :         nCharIndex -= cLast - cFirst;
     507         [ #  # ]:          0 :         if( nCharIndex < 0 )
     508                 :          0 :             return (cLast + nCharIndex);
     509                 :            :     }
     510                 :            : 
     511                 :            :     // we can only get here with an out-of-bounds charindex
     512                 :          0 :     return mpRangeCodes[0];
     513                 :            : }
     514                 :            : 
     515                 :            : // =======================================================================
     516                 :            : 
     517                 :     170427 : static unsigned GetUInt( const unsigned char* p ) { return((p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3]);}
     518                 :      30939 : static unsigned GetUShort( const unsigned char* p ){ return((p[0]<<8) | p[1]);}
     519                 :       4646 : static int GetSShort( const unsigned char* p ){ return((static_cast<signed char>(p[0])<<8)|p[1]);}
     520                 :            : 
     521                 :            : // TODO: move CMAP parsing directly into the ImplFontCharMap class
     522                 :        264 : bool ParseCMAP( const unsigned char* pCmap, int nLength, CmapResult& rResult )
     523                 :            : {
     524                 :        264 :     rResult.mpRangeCodes = NULL;
     525                 :        264 :     rResult.mpStartGlyphs= NULL;
     526                 :        264 :     rResult.mpGlyphIds   = NULL;
     527                 :        264 :     rResult.mnRangeCount = 0;
     528                 :        264 :     rResult.mbRecoded    = false;
     529                 :        264 :     rResult.mbSymbolic   = false;
     530                 :            : 
     531                 :            :     // parse the table header and check for validity
     532 [ +  - ][ -  + ]:        264 :     if( !pCmap || (nLength < 24) )
     533                 :          0 :         return false;
     534                 :            : 
     535         [ -  + ]:        264 :     if( GetUShort( pCmap ) != 0x0000 ) // simple check for CMAP corruption
     536                 :          0 :         return false;
     537                 :            : 
     538                 :        264 :     int nSubTables = GetUShort( pCmap + 2 );
     539 [ -  + ][ +  - ]:        264 :     if( (nSubTables <= 0) || (nLength < (24 + 8*nSubTables)) )
     540                 :          0 :         return false;
     541                 :            : 
     542                 :            :     // find the most interesting subtable in the CMAP
     543                 :        264 :     rtl_TextEncoding eRecodeFrom = RTL_TEXTENCODING_UNICODE;
     544                 :        264 :     int nOffset = 0;
     545                 :        264 :     int nFormat = -1;
     546                 :        264 :     int nBestVal = 0;
     547         [ +  + ]:       1486 :     for( const unsigned char* p = pCmap + 4; --nSubTables >= 0; p += 8 )
     548                 :            :     {
     549                 :       1222 :         int nPlatform = GetUShort( p );
     550                 :       1222 :         int nEncoding = GetUShort( p+2 );
     551                 :       1222 :         int nPlatformEncoding = (nPlatform << 8) + nEncoding;
     552                 :            : 
     553                 :            :         int nValue;
     554                 :       1222 :         rtl_TextEncoding eTmpEncoding = RTL_TEXTENCODING_UNICODE;
     555   [ -  -  -  +  :       1222 :         switch( nPlatformEncoding )
          +  +  -  -  +  
          +  -  -  -  -  
                   -  - ]
     556                 :            :         {
     557                 :          0 :             case 0x000: nValue = 20; break;                             // Unicode 1.0
     558                 :          0 :             case 0x001: nValue = 21; break;                             // Unicode 1.1
     559                 :          0 :             case 0x002: nValue = 22; break;                             // iso10646_1993
     560                 :        264 :             case 0x003: nValue = 23; break;                             // UCS-2
     561                 :        215 :             case 0x004: nValue = 24; break;                             // UCS-4
     562                 :        264 :             case 0x100: nValue = 22; break;                             // Mac Unicode<2.0
     563                 :          0 :             case 0x103: nValue = 23; break;                             // Mac Unicode>2.0
     564                 :          0 :             case 0x300: nValue =  5; rResult.mbSymbolic = true; break;  // Win Symbol
     565                 :        264 :             case 0x301: nValue = 28; break;                             // Win UCS-2
     566                 :        215 :             case 0x30A: nValue = 29; break;                             // Win-UCS-4
     567                 :          0 :             case 0x302: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_SHIFT_JIS; break;
     568                 :          0 :             case 0x303: nValue = 12; eTmpEncoding = RTL_TEXTENCODING_GB_18030; break;
     569                 :          0 :             case 0x304: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_BIG5; break;
     570                 :          0 :             case 0x305: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_MS_949; break;
     571                 :          0 :             case 0x306: nValue = 11; eTmpEncoding = RTL_TEXTENCODING_MS_1361; break;
     572                 :          0 :             default:    nValue = 0; break;
     573                 :            :         }
     574                 :            : 
     575         [ -  + ]:       1222 :         if( nValue <= 0 )   // ignore unknown encodings
     576                 :          0 :             continue;
     577                 :            : 
     578                 :       1222 :         int nTmpOffset = GetUInt( p+4 );
     579                 :       1222 :         int nTmpFormat = GetUShort( pCmap + nTmpOffset );
     580         [ +  + ]:       1222 :         if( nTmpFormat == 12 )                  // 32bit code -> glyph map format
     581                 :        430 :             nValue += 3;
     582         [ +  + ]:        792 :         else if( nTmpFormat != 4 )              // 16bit code -> glyph map format
     583                 :        264 :             continue;                           // ignore other formats
     584                 :            : 
     585         [ +  - ]:        958 :         if( nBestVal < nValue )
     586                 :            :         {
     587                 :        958 :             nBestVal = nValue;
     588                 :        958 :             nOffset = nTmpOffset;
     589                 :        958 :             nFormat = nTmpFormat;
     590                 :        958 :             eRecodeFrom = eTmpEncoding;
     591                 :            :         }
     592                 :            :     }
     593                 :            : 
     594                 :            :     // parse the best CMAP subtable
     595                 :        264 :     int nRangeCount = 0;
     596                 :        264 :     sal_uInt32* pCodePairs = NULL;
     597                 :        264 :     int* pStartGlyphs = NULL;
     598                 :            : 
     599                 :            :     typedef std::vector<sal_uInt16> U16Vector;
     600         [ +  - ]:        264 :     U16Vector aGlyphIdArray;
     601         [ +  - ]:        264 :     aGlyphIdArray.reserve( 0x1000 );
     602         [ +  - ]:        264 :     aGlyphIdArray.push_back( 0 );
     603                 :            : 
     604                 :            :     // format 4, the most common 16bit char mapping table
     605 [ +  + ][ +  - ]:        264 :     if( (nFormat == 4) && ((nOffset+16) < nLength) )
     606                 :            :     {
     607                 :         49 :         int nSegCountX2 = GetUShort( pCmap + nOffset + 6 );
     608                 :         49 :         nRangeCount = nSegCountX2/2 - 1;
     609         [ +  - ]:         49 :         pCodePairs = new sal_uInt32[ nRangeCount * 2 ];
     610         [ +  - ]:         49 :         pStartGlyphs = new int[ nRangeCount ];
     611                 :         49 :         const unsigned char* pLimitBase = pCmap + nOffset + 14;
     612                 :         49 :         const unsigned char* pBeginBase = pLimitBase + nSegCountX2 + 2;
     613                 :         49 :         const unsigned char* pDeltaBase = pBeginBase + nSegCountX2;
     614                 :         49 :         const unsigned char* pOffsetBase = pDeltaBase + nSegCountX2;
     615                 :         49 :         sal_uInt32* pCP = pCodePairs;
     616         [ +  + ]:       4695 :         for( int i = 0; i < nRangeCount; ++i )
     617                 :            :         {
     618                 :       4646 :             const sal_uInt32 cMinChar = GetUShort( pBeginBase + 2*i );
     619                 :       4646 :             const sal_uInt32 cMaxChar = GetUShort( pLimitBase + 2*i );
     620                 :       4646 :             const int nGlyphDelta  = GetSShort( pDeltaBase + 2*i );
     621                 :       4646 :             const int nRangeOffset = GetUShort( pOffsetBase + 2*i );
     622         [ -  + ]:       4646 :             if( cMinChar > cMaxChar )   // no sane font should trigger this
     623                 :          0 :                 break;
     624         [ -  + ]:       4646 :             if( cMaxChar == 0xFFFF )
     625                 :          0 :                 break;
     626                 :       4646 :             *(pCP++) = cMinChar;
     627                 :       4646 :             *(pCP++) = cMaxChar + 1;
     628         [ +  + ]:       4646 :             if( !nRangeOffset ) {
     629                 :            :                 // glyphid can be calculated directly
     630                 :       4547 :                 pStartGlyphs[i] = (cMinChar + nGlyphDelta) & 0xFFFF;
     631                 :            :             } else {
     632                 :            :                 // update the glyphid-array with the glyphs in this range
     633                 :         99 :                 pStartGlyphs[i] = -(int)aGlyphIdArray.size();
     634                 :         99 :                 const unsigned char* pGlyphIdPtr = pOffsetBase + 2*i + nRangeOffset;
     635         [ +  + ]:      12857 :                 for( sal_uInt32 c = cMinChar; c <= cMaxChar; ++c, pGlyphIdPtr+=2 ) {
     636                 :      12758 :                     const int nGlyphIndex = GetUShort( pGlyphIdPtr ) + nGlyphDelta;
     637         [ +  - ]:      12758 :                     aGlyphIdArray.push_back( static_cast<sal_uInt16>(nGlyphIndex) );
     638                 :            :                 }
     639                 :            :             }
     640                 :            :         }
     641                 :         49 :         nRangeCount = (pCP - pCodePairs) / 2;
     642                 :            :     }
     643                 :            :     // format 12, the most common 32bit char mapping table
     644 [ +  - ][ +  - ]:        215 :     else if( (nFormat == 12) && ((nOffset+16) < nLength) )
     645                 :            :     {
     646                 :        215 :         nRangeCount = GetUInt( pCmap + nOffset + 12 );
     647         [ +  - ]:        215 :         pCodePairs = new sal_uInt32[ nRangeCount * 2 ];
     648         [ +  - ]:        215 :         pStartGlyphs = new int[ nRangeCount ];
     649                 :        215 :         const unsigned char* pGroup = pCmap + nOffset + 16;
     650                 :        215 :         sal_uInt32* pCP = pCodePairs;
     651         [ +  + ]:      56545 :         for( int i = 0; i < nRangeCount; ++i )
     652                 :            :         {
     653                 :      56330 :             sal_uInt32 cMinChar = GetUInt( pGroup + 0 );
     654                 :      56330 :             sal_uInt32 cMaxChar = GetUInt( pGroup + 4 );
     655                 :      56330 :             int nGlyphId = GetUInt( pGroup + 8 );
     656                 :      56330 :             pGroup += 12;
     657         [ -  + ]:      56330 :             if( cMinChar > cMaxChar )   // no sane font should trigger this
     658                 :          0 :                 break;
     659                 :      56330 :             *(pCP++) = cMinChar;
     660                 :      56330 :             *(pCP++) = cMaxChar + 1;
     661                 :      56330 :             pStartGlyphs[i] = nGlyphId;
     662                 :            :         }
     663                 :        215 :         nRangeCount = (pCP - pCodePairs) / 2;
     664                 :            :     }
     665                 :            : 
     666                 :            :     // check if any subtable resulted in something usable
     667         [ -  + ]:        264 :     if( nRangeCount <= 0 )
     668                 :            :     {
     669         [ #  # ]:          0 :         delete[] pCodePairs;
     670         [ #  # ]:          0 :         delete[] pStartGlyphs;
     671                 :            : 
     672                 :            :         // even when no CMAP is available we know it for symbol fonts
     673         [ #  # ]:          0 :         if( rResult.mbSymbolic )
     674                 :            :         {
     675         [ #  # ]:          0 :             pCodePairs = new sal_uInt32[4];
     676                 :          0 :             pCodePairs[0] = 0x0020;    // aliased symbols
     677                 :          0 :             pCodePairs[1] = 0x0100;
     678                 :          0 :             pCodePairs[2] = 0xF020;    // original symbols
     679                 :          0 :             pCodePairs[3] = 0xF100;
     680                 :          0 :             rResult.mpRangeCodes = pCodePairs;
     681                 :          0 :             rResult.mnRangeCount = 2;
     682                 :          0 :             return true;
     683                 :            :         }
     684                 :            : 
     685                 :          0 :         return false;
     686                 :            :     }
     687                 :            : 
     688                 :            :     // recode the code ranges to their unicode encoded ranges if needed
     689                 :        264 :     rtl_TextToUnicodeConverter aConverter = NULL;
     690                 :        264 :     rtl_UnicodeToTextContext aCvtContext = NULL;
     691                 :            : 
     692                 :        264 :     rResult.mbRecoded = ( eRecodeFrom != RTL_TEXTENCODING_UNICODE );
     693         [ -  + ]:        264 :     if( rResult.mbRecoded )
     694                 :            :     {
     695         [ #  # ]:          0 :         aConverter = rtl_createTextToUnicodeConverter( eRecodeFrom );
     696         [ #  # ]:          0 :         aCvtContext = rtl_createTextToUnicodeContext( aConverter );
     697                 :            :     }
     698                 :            : 
     699 [ -  + ][ #  # ]:        264 :     if( aConverter && aCvtContext )
     700                 :            :     {
     701                 :            :         // determine the set of supported unicodes from encoded ranges
     702                 :            :         typedef std::set<sal_uInt32> IntSet;
     703         [ #  # ]:          0 :         IntSet aSupportedUnicodes;
     704                 :            : 
     705                 :            :         static const int NINSIZE = 64;
     706                 :            :         static const int NOUTSIZE = 64;
     707                 :            :         sal_Char    cCharsInp[ NINSIZE ];
     708                 :            :         sal_Unicode cCharsOut[ NOUTSIZE ];
     709                 :          0 :         sal_uInt32* pCP = pCodePairs;
     710         [ #  # ]:          0 :         for( int i = 0; i < nRangeCount; ++i )
     711                 :            :         {
     712                 :          0 :             sal_uInt32 cMin = *(pCP++);
     713                 :          0 :             sal_uInt32 cEnd = *(pCP++);
     714         [ #  # ]:          0 :             while( cMin < cEnd )
     715                 :            :             {
     716                 :          0 :                 int j = 0;
     717 [ #  # ][ #  # ]:          0 :                 for (; (cMin < cEnd) && (j < (NINSIZE-1)); ++cMin)
                 [ #  # ]
     718                 :            :                 {
     719         [ #  # ]:          0 :                     if( cMin >= 0x0100 )
     720                 :          0 :                         cCharsInp[ j++ ] = static_cast<sal_Char>(cMin >> 8);
     721 [ #  # ][ #  # ]:          0 :                     if( (cMin >= 0x0100) || (cMin < 0x00A0)  )
     722                 :          0 :                         cCharsInp[ j++ ] = static_cast<sal_Char>(cMin);
     723                 :            :                 }
     724                 :            : 
     725                 :            :                 sal_uInt32 nCvtInfo;
     726                 :            :                 sal_Size nSrcCvtBytes;
     727                 :            :                 int nOutLen = rtl_convertTextToUnicode(
     728                 :            :                     aConverter, aCvtContext,
     729                 :            :                     cCharsInp, j, cCharsOut, NOUTSIZE,
     730                 :            :                     RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE
     731                 :            :                     | RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE,
     732         [ #  # ]:          0 :                     &nCvtInfo, &nSrcCvtBytes );
     733                 :            : 
     734         [ #  # ]:          0 :                 for( j = 0; j < nOutLen; ++j )
     735         [ #  # ]:          0 :                     aSupportedUnicodes.insert( cCharsOut[j] );
     736                 :            :             }
     737                 :            :         }
     738                 :            : 
     739         [ #  # ]:          0 :         rtl_destroyTextToUnicodeConverter( aCvtContext );
     740         [ #  # ]:          0 :         rtl_destroyTextToUnicodeConverter( aConverter );
     741                 :            : 
     742                 :            :         // convert the set of supported unicodes to ranges
     743                 :            :         typedef std::vector<sal_uInt32> IntVector;
     744         [ #  # ]:          0 :         IntVector aSupportedRanges;
     745                 :            : 
     746                 :          0 :         IntSet::const_iterator itChar = aSupportedUnicodes.begin();
     747 [ #  # ][ #  # ]:          0 :         for(; itChar != aSupportedUnicodes.end(); ++itChar )
                 [ #  # ]
     748                 :            :         {
     749 [ #  # ][ #  # ]:          0 :             if( aSupportedRanges.empty()
                 [ #  # ]
     750 [ #  # ][ #  # ]:          0 :             || (aSupportedRanges.back() != *itChar) )
     751                 :            :             {
     752                 :            :                 // add new range beginning with current unicode
     753 [ #  # ][ #  # ]:          0 :                 aSupportedRanges.push_back( *itChar );
     754         [ #  # ]:          0 :                 aSupportedRanges.push_back( 0 );
     755                 :            :             }
     756                 :            : 
     757                 :            :             // extend existing range to include current unicode
     758 [ #  # ][ #  # ]:          0 :             aSupportedRanges.back() = *itChar + 1;
     759                 :            :         }
     760                 :            : 
     761                 :            :         // glyph mapping for non-unicode fonts not implemented
     762         [ #  # ]:          0 :         delete[] pStartGlyphs;
     763                 :          0 :         pStartGlyphs = NULL;
     764                 :          0 :         aGlyphIdArray.clear();
     765                 :            : 
     766                 :            :         // make a pCodePairs array using the vector from above
     767         [ #  # ]:          0 :         delete[] pCodePairs;
     768                 :          0 :         nRangeCount = aSupportedRanges.size() / 2;
     769         [ #  # ]:          0 :         if( nRangeCount <= 0 )
     770                 :          0 :             return false;
     771         [ #  # ]:          0 :         pCodePairs = new sal_uInt32[ nRangeCount * 2 ];
     772         [ #  # ]:          0 :         IntVector::const_iterator itInt = aSupportedRanges.begin();
     773 [ #  # ][ #  # ]:          0 :         for( pCP = pCodePairs; itInt != aSupportedRanges.end(); ++itInt )
                 [ #  # ]
     774 [ #  # ][ #  # ]:          0 :             *(pCP++) = *itInt;
                 [ #  # ]
     775                 :            :     }
     776                 :            : 
     777                 :            :     // prepare the glyphid-array if needed
     778                 :            :     // TODO: merge ranges if they are close enough?
     779                 :        264 :     sal_uInt16* pGlyphIds = NULL;
     780         [ +  - ]:        264 :     if( !aGlyphIdArray.empty())
     781                 :            :     {
     782         [ +  - ]:        264 :         pGlyphIds = new sal_uInt16[ aGlyphIdArray.size() ];
     783                 :        264 :         sal_uInt16* pOut = pGlyphIds;
     784         [ +  - ]:        264 :         U16Vector::const_iterator it = aGlyphIdArray.begin();
     785 [ +  - ][ +  + ]:      13286 :         while( it != aGlyphIdArray.end() )
     786 [ +  - ][ +  - ]:      13022 :             *(pOut++) = *(it++);
     787                 :            :     }
     788                 :            : 
     789                 :            :     // update the result struct
     790                 :        264 :     rResult.mpRangeCodes = pCodePairs;
     791                 :        264 :     rResult.mpStartGlyphs = pStartGlyphs;
     792                 :        264 :     rResult.mnRangeCount = nRangeCount;
     793                 :        264 :     rResult.mpGlyphIds = pGlyphIds;
     794                 :        264 :     return true;
     795                 :            : }
     796                 :            : 
     797                 :            : // =======================================================================
     798                 :            : 
     799                 :      10716 : FontCharMap::FontCharMap()
     800                 :      10716 : :   mpImpl( ImplFontCharMap::GetDefaultMap() )
     801                 :            : {
     802                 :      10716 :     mpImpl->AddReference();
     803                 :      10716 : }
     804                 :            : 
     805                 :            : // -----------------------------------------------------------------------
     806                 :            : 
     807                 :      10716 : FontCharMap::~FontCharMap()
     808                 :            : {
     809                 :      10716 :     mpImpl->DeReference();
     810                 :      10716 :     mpImpl = NULL;
     811                 :      10716 : }
     812                 :            : 
     813                 :            : // -----------------------------------------------------------------------
     814                 :            : 
     815                 :          0 : int FontCharMap::GetCharCount() const
     816                 :            : {
     817                 :          0 :     return mpImpl->GetCharCount();
     818                 :            : }
     819                 :            : 
     820                 :            : // -----------------------------------------------------------------------
     821                 :            : 
     822                 :          0 : int FontCharMap::CountCharsInRange( sal_uInt32 cMin, sal_uInt32 cMax ) const
     823                 :            : {
     824                 :          0 :     return mpImpl->CountCharsInRange( cMin, cMax );
     825                 :            : }
     826                 :            : 
     827                 :            : // -----------------------------------------------------------------------
     828                 :            : 
     829                 :      21432 : void FontCharMap::Reset( const ImplFontCharMap* pNewMap )
     830                 :            : {
     831                 :      21432 :     mpImpl->DeReference();
     832         [ +  + ]:      21432 :     if( pNewMap == NULL )
     833                 :      10716 :         mpImpl = ImplFontCharMap::GetDefaultMap();
     834         [ +  - ]:      10716 :     else if( pNewMap != mpImpl )
     835                 :      10716 :         mpImpl = pNewMap;
     836                 :      21432 :     mpImpl->AddReference();
     837                 :      21432 : }
     838                 :            : 
     839                 :            : // -----------------------------------------------------------------------
     840                 :            : 
     841                 :      10716 : sal_Bool FontCharMap::IsDefaultMap() const
     842                 :            : {
     843                 :      10716 :     return mpImpl->IsDefaultMap();
     844                 :            : }
     845                 :            : 
     846                 :            : // -----------------------------------------------------------------------
     847                 :            : 
     848                 :      44603 : sal_Bool FontCharMap::HasChar( sal_uInt32 cChar ) const
     849                 :            : {
     850                 :      44603 :     return mpImpl->HasChar( cChar );
     851                 :            : }
     852                 :            : 
     853                 :            : // -----------------------------------------------------------------------
     854                 :            : 
     855                 :       1655 : sal_uInt32 FontCharMap::GetFirstChar() const
     856                 :            : {
     857                 :       1655 :     return mpImpl->GetFirstChar();
     858                 :            : }
     859                 :            : 
     860                 :            : // -----------------------------------------------------------------------
     861                 :            : 
     862                 :          0 : sal_uInt32 FontCharMap::GetNextChar( sal_uInt32 cChar ) const
     863                 :            : {
     864                 :          0 :     return mpImpl->GetNextChar( cChar );
     865                 :            : }
     866                 :            : 
     867                 :            : // -----------------------------------------------------------------------
     868                 :            : 
     869                 :          0 : sal_uInt32 FontCharMap::GetPrevChar( sal_uInt32 cChar ) const
     870                 :            : {
     871                 :          0 :     return mpImpl->GetPrevChar( cChar );
     872                 :            : }
     873                 :            : 
     874                 :            : // -----------------------------------------------------------------------
     875                 :            : 
     876                 :          0 : int FontCharMap::GetIndexFromChar( sal_uInt32 cChar ) const
     877                 :            : {
     878                 :          0 :     return mpImpl->GetIndexFromChar( cChar );
     879                 :            : }
     880                 :            : 
     881                 :            : // -----------------------------------------------------------------------
     882                 :            : 
     883                 :          0 : sal_uInt32 FontCharMap::GetCharFromIndex( int nIndex ) const
     884                 :            : {
     885                 :          0 :     return mpImpl->GetCharFromIndex( nIndex );
     886                 :            : }
     887                 :            : 
     888                 :            : // =======================================================================
     889                 :            : 
     890                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10