LCOV - code coverage report
Current view: top level - libreoffice/vcl/headless - svptext.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 139 206 67.5 %
Date: 2012-12-27 Functions: 27 38 71.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <basegfx/range/b2drange.hxx>
      21             : #include <basegfx/range/b2ibox.hxx>
      22             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      23             : 
      24             : #include <basebmp/scanlineformats.hxx>
      25             : 
      26             : #include <tools/debug.hxx>
      27             : 
      28             : #include <outfont.hxx>
      29             : #include <impfont.hxx>
      30             : #include <rtl/instance.hxx>
      31             : 
      32             : #include "generic/geninst.h"
      33             : #include "generic/genpspgraphics.h"
      34             : #include "generic/glyphcache.hxx"
      35             : #include "headless/svpgdi.hxx"
      36             : #include "headless/svpbmp.hxx"
      37             : 
      38             : using namespace basegfx;
      39             : using namespace basebmp;
      40             : 
      41             : // ===========================================================================
      42             : 
      43          40 : class SvpGlyphPeer
      44             : :   public GlyphCachePeer
      45             : {
      46             : public:
      47          20 :     SvpGlyphPeer() {}
      48             : 
      49             :     BitmapDeviceSharedPtr GetGlyphBmp( ServerFont&, int nGlyphIndex,
      50             :                             sal_uInt32 nBmpFormat, B2IPoint& rTargetPos );
      51             : 
      52             : protected:
      53             :     virtual void    RemovingFont( ServerFont& );
      54             :     virtual void    RemovingGlyph( ServerFont&, GlyphData&, int nGlyphIndex );
      55             : 
      56       17408 :     class SvpGcpHelper
      57             :     {
      58             :     public:
      59             :         RawBitmap               maRawBitmap;
      60             :         BitmapDeviceSharedPtr   maBitmapDev;
      61             :     };
      62             : };
      63             : 
      64             : // ===========================================================================
      65             : 
      66          20 : class SvpGlyphCache : public GlyphCache
      67             : {
      68             : public:
      69          20 :     SvpGlyphCache( SvpGlyphPeer& rPeer ) : GlyphCache( rPeer) {}
      70        7582 :     SvpGlyphPeer& GetPeer() { return reinterpret_cast<SvpGlyphPeer&>( mrPeer ); }
      71             :     static SvpGlyphCache& GetInstance();
      72             : };
      73             : 
      74             : namespace
      75             : {
      76             :     struct GlyphCacheHolder
      77             :     {
      78             :     private:
      79             :         SvpGlyphPeer* m_pSvpGlyphPeer;
      80             :         SvpGlyphCache* m_pSvpGlyphCache;
      81             :     public:
      82          20 :         GlyphCacheHolder()
      83             :         {
      84          20 :             m_pSvpGlyphPeer = new SvpGlyphPeer();
      85          20 :             m_pSvpGlyphCache = new SvpGlyphCache( *m_pSvpGlyphPeer );
      86          20 :         }
      87          20 :         void release()
      88             :         {
      89          20 :             delete m_pSvpGlyphCache;
      90          20 :             delete m_pSvpGlyphPeer;
      91          20 :             m_pSvpGlyphCache = NULL;
      92          20 :             m_pSvpGlyphPeer = NULL;
      93          20 :         }
      94       46050 :         SvpGlyphCache& getGlyphCache()
      95             :         {
      96       46050 :             return *m_pSvpGlyphCache;
      97             :         }
      98          20 :         ~GlyphCacheHolder()
      99             :         {
     100          20 :             release();
     101          20 :         }
     102             :     };
     103             : 
     104             :     struct theGlyphCacheHolder :
     105             :         public rtl::Static<GlyphCacheHolder, theGlyphCacheHolder>
     106             :     {};
     107             : }
     108             : 
     109       46050 : SvpGlyphCache& SvpGlyphCache::GetInstance()
     110             : {
     111       46050 :     return theGlyphCacheHolder::get().getGlyphCache();
     112             : }
     113             : 
     114             : // ===========================================================================
     115             : 
     116       17149 : BitmapDeviceSharedPtr SvpGlyphPeer::GetGlyphBmp( ServerFont& rServerFont,
     117             :     int nGlyphIndex, sal_uInt32 nBmpFormat, B2IPoint& rTargetPos )
     118             : {
     119       17149 :     GlyphData& rGlyphData = rServerFont.GetGlyphData( nGlyphIndex );
     120       17149 :     SvpGcpHelper* pGcpHelper = (SvpGcpHelper*)rGlyphData.ExtDataRef().mpData;
     121             : 
     122             :     // nothing to do if the GlyphPeer hasn't allocated resources for the glyph
     123       17149 :     if( rGlyphData.ExtDataRef().meInfo != sal::static_int_cast<int>(nBmpFormat) )
     124             :     {
     125       17149 :         if( rGlyphData.ExtDataRef().meInfo == Format::NONE )
     126       17149 :             pGcpHelper = new SvpGcpHelper;
     127       17149 :         RawBitmap& rRawBitmap = pGcpHelper->maRawBitmap;
     128             : 
     129             :         // get glyph bitmap in matching format
     130       17149 :         bool bFound = false;
     131       17149 :         switch( nBmpFormat )
     132             :         {
     133             :             case Format::ONE_BIT_LSB_GREY:
     134          70 :                 bFound = rServerFont.GetGlyphBitmap1( nGlyphIndex, pGcpHelper->maRawBitmap );
     135          70 :                 break;
     136             :             case Format::EIGHT_BIT_GREY:
     137       17079 :                 bFound = rServerFont.GetGlyphBitmap8( nGlyphIndex, pGcpHelper->maRawBitmap );
     138       17079 :                 break;
     139             :             default:
     140             :                 OSL_FAIL( "SVP GCP::GetGlyphBmp(): illegal scanline format");
     141             :                 // fall back to black&white mask
     142           0 :                 nBmpFormat = Format::ONE_BIT_LSB_GREY;
     143           0 :                 bFound = false;
     144           0 :                 break;
     145             :         }
     146             : 
     147             :         // return .notdef glyph if needed
     148       17149 :         if( !bFound && (nGlyphIndex != 0) )
     149             :         {
     150         259 :             delete pGcpHelper;
     151         259 :             return GetGlyphBmp( rServerFont, 0, nBmpFormat, rTargetPos );
     152             :         }
     153             : 
     154             :         // construct alpha mask from raw bitmap
     155       16890 :         const B2IVector aSize( rRawBitmap.mnScanlineSize, rRawBitmap.mnHeight );
     156       16890 :         if( aSize.getX() && aSize.getY() )
     157             :         {
     158       15791 :             static PaletteMemorySharedVector aDummyPAL;
     159       15791 :             RawMemorySharedArray aRawPtr( rRawBitmap.mpBits );
     160       15791 :             pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, aRawPtr, aDummyPAL );
     161             :         }
     162             : 
     163       16890 :         rServerFont.SetExtended( nBmpFormat, (void*)pGcpHelper );
     164             :     }
     165             : 
     166       16890 :     rTargetPos += B2IPoint( pGcpHelper->maRawBitmap.mnXOffset, pGcpHelper->maRawBitmap.mnYOffset );
     167       16890 :     return pGcpHelper->maBitmapDev;
     168             : }
     169             : 
     170             : //--------------------------------------------------------------------------
     171             : 
     172         974 : void SvpGlyphPeer::RemovingFont( ServerFont& )
     173             : {
     174             :     // nothing to do: no font resources held in SvpGlyphPeer
     175         974 : }
     176             : 
     177             : //--------------------------------------------------------------------------
     178             : 
     179           0 : void SvpGlyphPeer::RemovingGlyph( ServerFont&, GlyphData& rGlyphData, int /*nGlyphIndex*/ )
     180             : {
     181           0 :     if( rGlyphData.ExtDataRef().mpData != Format::NONE )
     182             :     {
     183             :         // release the glyph related resources
     184             :         DBG_ASSERT( (rGlyphData.ExtDataRef().meInfo <= Format::MAX), "SVP::RG() invalid alpha format" );
     185           0 :         SvpGcpHelper* pGcpHelper = (SvpGcpHelper*)rGlyphData.ExtDataRef().mpData;
     186           0 :         delete[] pGcpHelper->maRawBitmap.mpBits;
     187           0 :         delete pGcpHelper;
     188             :     }
     189           0 : }
     190             : 
     191             : // ===========================================================================
     192             : 
     193             : // PspKernInfo allows on-demand-querying of psprint provided kerning info (#i29881#)
     194        1400 : class PspKernInfo : public ExtraKernInfo
     195             : {
     196             : public:
     197         805 :     PspKernInfo( int nFontId ) : ExtraKernInfo(nFontId) {}
     198             : protected:
     199             :     virtual void Initialize() const;
     200             : };
     201             : 
     202             : //--------------------------------------------------------------------------
     203             : 
     204           0 : void PspKernInfo::Initialize() const
     205             : {
     206           0 :     mbInitialized = true;
     207             : 
     208             :     // get the kerning pairs from psprint
     209           0 :     const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
     210             :     typedef std::list< psp::KernPair > PspKernPairs;
     211           0 :     const PspKernPairs& rKernPairs = rMgr.getKernPairs( mnFontId );
     212           0 :     if( rKernPairs.empty() )
     213           0 :         return;
     214             : 
     215           0 :     PspKernPairs::const_iterator it = rKernPairs.begin();
     216           0 :     for(; it != rKernPairs.end(); ++it )
     217             :     {
     218           0 :         ImplKernPairData aKernPair = { it->first, it->second, it->kern_x };
     219           0 :         maUnicodeKernPairs.insert( aKernPair );
     220             :     }
     221             : }
     222             : 
     223             : // ===========================================================================
     224             : 
     225       28483 : sal_uInt16 SvpSalGraphics::SetFont( FontSelectPattern* pIFSD, int nFallbackLevel )
     226             : {
     227             :     // release all no longer needed font resources
     228      479793 :     for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
     229             :     {
     230      451310 :         if( m_pServerFont[i] != NULL )
     231             :         {
     232             :             // old server side font is no longer referenced
     233       18673 :             SvpGlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] );
     234       18673 :             m_pServerFont[i] = NULL;
     235             :         }
     236             :     }
     237             : 
     238             :     // return early if there is no new font
     239       28483 :     if( !pIFSD )
     240        8711 :         return 0;
     241             : 
     242             :     // handle the request for a non-native X11-font => use the GlyphCache
     243       19772 :     ServerFont* pServerFont = SvpGlyphCache::GetInstance().CacheFont( *pIFSD );
     244       19772 :     if( !pServerFont )
     245           0 :         return SAL_SETFONT_BADFONT;
     246             : 
     247             :     // check selected font
     248       19772 :     if( !pServerFont->TestFont() )
     249             :     {
     250           0 :         SvpGlyphCache::GetInstance().UncacheFont( *pServerFont );
     251           0 :         return SAL_SETFONT_BADFONT;
     252             :     }
     253             : 
     254             :     // update SalGraphics font settings
     255       19772 :     m_pServerFont[ nFallbackLevel ] = pServerFont;
     256       19772 :     return SAL_SETFONT_USEDRAWTEXTARRAY;
     257             : }
     258             : 
     259             : // ---------------------------------------------------------------------------
     260             : 
     261        4720 : void SvpSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel )
     262             : {
     263        4720 :     if( nFallbackLevel >= MAX_FALLBACK )
     264        4720 :         return;
     265             : 
     266        4720 :     if( m_pServerFont[nFallbackLevel] != NULL )
     267             :     {
     268             :         long rDummyFactor;
     269        4720 :         m_pServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor );
     270             :     }
     271             : }
     272             : 
     273             : // ---------------------------------------------------------------------------
     274             : 
     275           0 : sal_uLong SvpSalGraphics::GetKernPairs( sal_uLong nPairs, ImplKernPairData* pKernPairs )
     276             : {
     277           0 :     sal_uLong nGotPairs = 0;
     278             : 
     279           0 :     if( m_pServerFont[0] != NULL )
     280             :     {
     281           0 :         ImplKernPairData* pTmpKernPairs = NULL;
     282           0 :         nGotPairs = m_pServerFont[0]->GetKernPairs( &pTmpKernPairs );
     283           0 :         for( sal_uLong i = 0; i < nPairs && i < nGotPairs; ++i )
     284           0 :             pKernPairs[ i ] = pTmpKernPairs[ i ];
     285           0 :         delete[] pTmpKernPairs;
     286             :     }
     287             : 
     288           0 :     return nGotPairs;
     289             : }
     290             : 
     291             : // ---------------------------------------------------------------------------
     292             : 
     293        2841 : const ImplFontCharMap* SvpSalGraphics::GetImplFontCharMap() const
     294             : {
     295        2841 :     if( !m_pServerFont[0] )
     296           0 :         return NULL;
     297             : 
     298        2841 :     const ImplFontCharMap* pIFCMap = m_pServerFont[0]->GetImplFontCharMap();
     299        2841 :     return pIFCMap;
     300             : }
     301             : 
     302           0 : bool SvpSalGraphics::GetImplFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
     303             : {
     304           0 :     if (!m_pServerFont[0])
     305           0 :         return false;
     306             : 
     307           0 :     return m_pServerFont[0]->GetFontCapabilities(rFontCapabilities);
     308             : }
     309             : 
     310             : // ---------------------------------------------------------------------------
     311             : 
     312          23 : void SvpSalGraphics::GetDevFontList( ImplDevFontList* pDevFontList )
     313             : {
     314          23 :     GlyphCache& rGC = SvpGlyphCache::GetInstance();
     315             : 
     316          23 :     psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
     317          23 :     psp::FastPrintFontInfo aInfo;
     318          23 :     ::std::list< psp::fontID > aList;
     319          23 :     rMgr.getFontList( aList );
     320          23 :     ::std::list< psp::fontID >::iterator it;
     321        2645 :     for( it = aList.begin(); it != aList.end(); ++it )
     322             :     {
     323        2622 :         if( !rMgr.getFontFastInfo( *it, aInfo ) )
     324           0 :             continue;
     325             : 
     326             :         // the GlyphCache must not bother with builtin fonts because
     327             :         // it cannot access or use them anyway
     328        2622 :         if( aInfo.m_eType == psp::fonttype::Builtin )
     329           0 :             continue;
     330             : 
     331             :         // normalize face number to the GlyphCache
     332        2622 :         int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
     333             : 
     334             :         // for fonts where extra kerning info can be provided on demand
     335             :         // an ExtraKernInfo object is supplied
     336        2622 :         const ExtraKernInfo* pExtraKernInfo = NULL;
     337        2622 :         if( aInfo.m_eType == psp::fonttype::Type1 )
     338         805 :             pExtraKernInfo = new PspKernInfo( *it );
     339             : 
     340             :         // inform GlyphCache about this font provided by the PsPrint subsystem
     341        2622 :         ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
     342        2622 :         aDFA.mnQuality += 4096;
     343        2622 :         const rtl::OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
     344        2622 :         rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA, pExtraKernInfo );
     345        2622 :    }
     346             : 
     347             :     // announce glyphcache fonts
     348          23 :     rGC.AnnounceFonts( pDevFontList );
     349             : 
     350             :     // register platform specific font substitutions if available
     351          23 :     SalGenericInstance::RegisterFontSubstitutors( pDevFontList );
     352             : 
     353          23 :     ImplGetSVData()->maGDIData.mbNativeFontConfig = true;
     354          23 : }
     355             : 
     356           0 : void SvpSalGraphics::ClearDevFontCache()
     357             : {
     358           0 :     GlyphCache& rGC = SvpGlyphCache::GetInstance();
     359           0 :     rGC.ClearFontCache();
     360           0 : }
     361             : 
     362             : // ---------------------------------------------------------------------------
     363             : 
     364           2 : void SvpSalGraphics::GetDevFontSubstList( OutputDevice* )
     365           2 : {}
     366             : 
     367             : // ---------------------------------------------------------------------------
     368             : 
     369           0 : bool SvpSalGraphics::AddTempDevFont( ImplDevFontList*,
     370             :     const OUString&, const OUString& )
     371             : {
     372           0 :     return false;
     373             : }
     374             : 
     375             : // ---------------------------------------------------------------------------
     376             : 
     377           0 : sal_Bool SvpSalGraphics::CreateFontSubset(
     378             :     const OUString& rToFile,
     379             :     const PhysicalFontFace* pFont,
     380             :     sal_Int32* pGlyphIDs,
     381             :     sal_uInt8* pEncoding,
     382             :     sal_Int32* pWidths,
     383             :     int nGlyphCount,
     384             :     FontSubsetInfo& rInfo
     385             :     )
     386             : {
     387             :     // in this context the pFont->GetFontId() is a valid PSP
     388             :     // font since they are the only ones left after the PDF
     389             :     // export has filtered its list of subsettable fonts (for
     390             :     // which this method was created). The correct way would
     391             :     // be to have the GlyphCache search for the PhysicalFontFace pFont
     392           0 :     psp::fontID aFont = pFont->GetFontId();
     393             : 
     394           0 :     psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
     395             :     bool bSuccess = rMgr.createFontSubset( rInfo,
     396             :                                  aFont,
     397             :                                  rToFile,
     398             :                                  pGlyphIDs,
     399             :                                  pEncoding,
     400             :                                  pWidths,
     401           0 :                                  nGlyphCount );
     402           0 :     return bSuccess;
     403             : }
     404             : 
     405             : // ---------------------------------------------------------------------------
     406             : 
     407           0 : const Ucs2SIntMap* SvpSalGraphics::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded )
     408             : {
     409             :     // in this context the pFont->GetFontId() is a valid PSP
     410             :     // font since they are the only ones left after the PDF
     411             :     // export has filtered its list of subsettable fonts (for
     412             :     // which this method was created). The correct way would
     413             :     // be to have the GlyphCache search for the PhysicalFontFace pFont
     414           0 :     psp::fontID aFont = pFont->GetFontId();
     415           0 :     return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
     416             : }
     417             : 
     418             : // ---------------------------------------------------------------------------
     419             : 
     420           0 : const void* SvpSalGraphics::GetEmbedFontData(
     421             :     const PhysicalFontFace* pFont,
     422             :     const sal_Ucs* pUnicodes,
     423             :     sal_Int32* pWidths,
     424             :     FontSubsetInfo& rInfo,
     425             :     long* pDataLen
     426             :     )
     427             : {
     428             :     // in this context the pFont->GetFontId() is a valid PSP
     429             :     // font since they are the only ones left after the PDF
     430             :     // export has filtered its list of subsettable fonts (for
     431             :     // which this method was created). The correct way would
     432             :     // be to have the GlyphCache search for the PhysicalFontFace pFont
     433           0 :     psp::fontID aFont = pFont->GetFontId();
     434           0 :     return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen );
     435             : }
     436             : 
     437             : // ---------------------------------------------------------------------------
     438             : 
     439           0 : void SvpSalGraphics::FreeEmbedFontData( const void* pData, long nLen )
     440             : {
     441           0 :     GenPspGraphics::DoFreeEmbedFontData( pData, nLen );
     442           0 : }
     443             : 
     444           0 : void SvpSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
     445             :                                    bool bVertical,
     446             :                                    Int32Vector& rWidths,
     447             :                                    Ucs2UIntMap& rUnicodeEnc )
     448             : {
     449             :     // in this context the pFont->GetFontId() is a valid PSP
     450             :     // font since they are the only ones left after the PDF
     451             :     // export has filtered its list of subsettable fonts (for
     452             :     // which this method was created). The correct way would
     453             :     // be to have the GlyphCache search for the PhysicalFontFace pFont
     454           0 :     psp::fontID aFont = pFont->GetFontId();
     455           0 :     GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
     456           0 : }
     457             : 
     458             : // ---------------------------------------------------------------------------
     459             : 
     460       26888 : sal_Bool SvpSalGraphics::GetGlyphBoundRect( sal_GlyphId nGlyphIndex, Rectangle& rRect )
     461             : {
     462       26888 :     int nLevel = nGlyphIndex >> GF_FONTSHIFT;
     463       26888 :     if( nLevel >= MAX_FALLBACK )
     464           0 :         return sal_False;
     465             : 
     466       26888 :     ServerFont* pSF = m_pServerFont[ nLevel ];
     467       26888 :     if( !pSF )
     468           0 :         return sal_False;
     469             : 
     470       26888 :     nGlyphIndex &= GF_IDXMASK;
     471       26888 :     const GlyphMetric& rGM = pSF->GetGlyphMetric( nGlyphIndex );
     472       26888 :     rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() );
     473       26888 :     return sal_True;
     474             : }
     475             : 
     476             : // ---------------------------------------------------------------------------
     477             : 
     478         119 : sal_Bool SvpSalGraphics::GetGlyphOutline( sal_GlyphId nGlyphIndex, B2DPolyPolygon& rPolyPoly )
     479             : {
     480         119 :     int nLevel = nGlyphIndex >> GF_FONTSHIFT;
     481         119 :     if( nLevel >= MAX_FALLBACK )
     482           0 :         return sal_False;
     483             : 
     484         119 :     const ServerFont* pSF = m_pServerFont[ nLevel ];
     485         119 :     if( !pSF )
     486           0 :         return sal_False;
     487             : 
     488         119 :     nGlyphIndex &= GF_IDXMASK;
     489         119 :     if( pSF->GetGlyphOutline( nGlyphIndex, rPolyPoly ) )
     490          73 :         return sal_True;
     491             : 
     492          46 :     return sal_False;
     493             : }
     494             : 
     495             : // ---------------------------------------------------------------------------
     496             : 
     497       56398 : SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs&, int nFallbackLevel )
     498             : {
     499       56398 :     GenericSalLayout* pLayout = NULL;
     500             : 
     501       56398 :     if( m_pServerFont[ nFallbackLevel ] )
     502       56398 :         pLayout = new ServerFontLayout( *m_pServerFont[ nFallbackLevel ] );
     503             : 
     504       56398 :     return pLayout;
     505             : }
     506             : 
     507             : // ---------------------------------------------------------------------------
     508             : 
     509        7582 : void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout )
     510             : {
     511             :     // iterate over all glyphs in the layout
     512        7582 :     Point aPos;
     513             :     sal_GlyphId nGlyphIndex;
     514        7582 :     SvpGlyphPeer& rGlyphPeer = SvpGlyphCache::GetInstance().GetPeer();
     515       32054 :     for( int nStart = 0; rSalLayout.GetNextGlyphs( 1, &nGlyphIndex, aPos, nStart ); )
     516             :     {
     517       16890 :         int nLevel = nGlyphIndex >> GF_FONTSHIFT;
     518             :         DBG_ASSERT( nLevel < MAX_FALLBACK, "SvpGDI: invalid glyph fallback level" );
     519       16890 :         ServerFont* pSF = m_pServerFont[ nLevel ];
     520       16890 :         if( !pSF )
     521           0 :             continue;
     522             : 
     523             :         // get the glyph's alpha mask and adjust the drawing position
     524       16890 :         nGlyphIndex &= GF_IDXMASK;
     525       16890 :         B2IPoint aDstPoint( aPos.X(), aPos.Y() );
     526             :         BitmapDeviceSharedPtr aAlphaMask
     527       16890 :             = rGlyphPeer.GetGlyphBmp( *pSF, nGlyphIndex, m_eTextFmt, aDstPoint );
     528       16890 :         if( !aAlphaMask )   // ignore empty glyphs
     529        1099 :             continue;
     530             : 
     531             :         // blend text color into target using the glyph's mask
     532       15791 :         const B2IBox aSrcRect( B2ITuple(0,0), aAlphaMask->getSize() );
     533       15791 :         const B2IBox aClipRect( aDstPoint, aAlphaMask->getSize() );
     534             : 
     535       15791 :         SvpSalGraphics::ClipUndoHandle aUndo( this );
     536       15791 :         if( !isClippedSetup( aClipRect, aUndo ) )
     537             :             m_aDevice->drawMaskedColor( m_aTextColor, aAlphaMask,
     538       15791 :                                         aSrcRect, aDstPoint, m_aClipMap );
     539       15791 :     }
     540        7582 : }
     541             : 
     542             : // ===========================================================================
     543             : 
     544             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10