LCOV - code coverage report
Current view: top level - vcl/unx/generic/gdi - cairotextrender.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 178 306 58.2 %
Date: 2015-06-13 12:38:46 Functions: 19 31 61.3 %
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 "cairotextrender.hxx"
      21             : 
      22             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      23             : #include <vcl/settings.hxx>
      24             : #include <vcl/sysdata.hxx>
      25             : #include <vcl/svapp.hxx>
      26             : 
      27             : #include "generic/printergfx.hxx"
      28             : #include "generic/genpspgraphics.h"
      29             : #include "generic/geninst.h"
      30             : #include "generic/glyphcache.hxx"
      31             : #include "PhysicalFontFace.hxx"
      32             : #include "impfont.hxx"
      33             : 
      34             : #include <config_graphite.h>
      35             : #if ENABLE_GRAPHITE
      36             : #include <graphite_layout.hxx>
      37             : #include <graphite_serverfont.hxx>
      38             : #endif
      39             : 
      40             : #include <cairo.h>
      41             : #include <cairo-ft.h>
      42             : #include <cairo-xlib.h>
      43             : #include <cairo-xlib-xrender.h>
      44             : 
      45         208 : CairoTextRender::CairoTextRender()
      46         208 :     : mnTextColor(MAKE_SALCOLOR(0x00, 0x00, 0x00)) //black
      47             : {
      48        3536 :     for( int i = 0; i < MAX_FALLBACK; ++i )
      49        3328 :         mpServerFont[i] = NULL;
      50             : 
      51             : #if ENABLE_GRAPHITE
      52             :     // check if graphite fonts have been disabled
      53         208 :     static const char* pDisableGraphiteStr = getenv( "SAL_DISABLE_GRAPHITE" );
      54         208 :     bDisableGraphite_ = pDisableGraphiteStr && (pDisableGraphiteStr[0]!='0');
      55             : #endif
      56         208 : }
      57             : 
      58         518 : bool CairoTextRender::setFont( const FontSelectPattern *pEntry, int nFallbackLevel )
      59             : {
      60             :     // release all no longer needed font resources
      61        8806 :     for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
      62             :     {
      63        8288 :         if( mpServerFont[i] != NULL )
      64             :         {
      65             :             // old server side font is no longer referenced
      66         114 :             GlyphCache::GetInstance().UncacheFont( *mpServerFont[i] );
      67         114 :             mpServerFont[i] = NULL;
      68             :         }
      69             :     }
      70             : 
      71             :     // return early if there is no new font
      72         518 :     if( !pEntry )
      73         399 :         return false;
      74             : 
      75             :     // return early if this is not a valid font for this graphics
      76         119 :     if( !pEntry->mpFontData )
      77           0 :         return false;
      78             : 
      79             :     // handle the request for a non-native X11-font => use the GlyphCache
      80         119 :     ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
      81         119 :     if( pServerFont != NULL )
      82             :     {
      83             :         // ignore fonts with e.g. corrupted font files
      84         119 :         if( !pServerFont->TestFont() )
      85             :         {
      86           0 :             GlyphCache::GetInstance().UncacheFont( *pServerFont );
      87           0 :             return false;
      88             :         }
      89             : 
      90             :         // register to use the font
      91         119 :         mpServerFont[ nFallbackLevel ] = pServerFont;
      92             : 
      93             :         // apply font specific-hint settings
      94         119 :         ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry );
      95         119 :         pSFE->HandleFontOptions();
      96             : 
      97         119 :         return true;
      98             :     }
      99             : 
     100           0 :     return false;
     101             : }
     102             : 
     103             : ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize);
     104             : 
     105         119 : void ImplServerFontEntry::HandleFontOptions()
     106             : {
     107         119 :     if( !mpServerFont )
     108         136 :         return;
     109         102 :     if( !mbGotFontOptions )
     110             :     {
     111             :         // get and cache the font options
     112          37 :         mbGotFontOptions = true;
     113             :         mxFontOptions.reset(GetFCFontOptions( *maFontSelData.mpFontData,
     114          37 :             maFontSelData.mnHeight ));
     115             :     }
     116             :     // apply the font options
     117         102 :     mpServerFont->SetFontOptions(mxFontOptions);
     118             : }
     119             : 
     120         267 : CairoFontsCache::LRUFonts CairoFontsCache::maLRUFonts;
     121             : int CairoFontsCache::mnRefCount = 0;
     122             : 
     123         208 : CairoFontsCache::CairoFontsCache()
     124             : {
     125         208 :     ++mnRefCount;
     126         208 : }
     127             : 
     128         196 : CairoFontsCache::~CairoFontsCache()
     129             : {
     130         196 :     --mnRefCount;
     131         196 :     if (!mnRefCount && !maLRUFonts.empty())
     132             :     {
     133           0 :         LRUFonts::iterator aEnd = maLRUFonts.end();
     134           0 :         for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
     135           0 :             cairo_font_face_destroy(static_cast<cairo_font_face_t*>(aI->first));
     136             :     }
     137         196 : }
     138             : 
     139           1 : void CairoFontsCache::CacheFont(void *pFont, const CairoFontsCache::CacheId &rId)
     140             : {
     141           1 :     maLRUFonts.push_front( std::pair<void*, CairoFontsCache::CacheId>(pFont, rId) );
     142           1 :     if (maLRUFonts.size() > 8)
     143             :     {
     144           0 :         cairo_font_face_destroy(static_cast<cairo_font_face_t*>(maLRUFonts.back().first));
     145           0 :         maLRUFonts.pop_back();
     146             :     }
     147           1 : }
     148             : 
     149           3 : void* CairoFontsCache::FindCachedFont(const CairoFontsCache::CacheId &rId)
     150             : {
     151           3 :     LRUFonts::iterator aEnd = maLRUFonts.end();
     152           3 :     for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
     153           2 :         if (aI->second == rId)
     154           2 :             return aI->first;
     155           1 :     return NULL;
     156             : }
     157             : 
     158             : namespace
     159             : {
     160          54 :     bool hasRotation(int nRotation)
     161             :     {
     162          54 :       return nRotation != 0;
     163             :     }
     164             : 
     165           0 :     double toRadian(int nDegree10th)
     166             :     {
     167           0 :         return (3600 - (nDegree10th)) * M_PI / 1800.0;
     168             :     }
     169             : }
     170             : 
     171           3 : void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout )
     172             : {
     173           3 :     std::vector<cairo_glyph_t> cairo_glyphs;
     174           6 :     std::vector<int> glyph_extrarotation;
     175           3 :     cairo_glyphs.reserve( 256 );
     176             : 
     177           3 :     Point aPos;
     178             :     sal_GlyphId aGlyphId;
     179          63 :     for( int nStart = 0; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
     180             :     {
     181             :         cairo_glyph_t aGlyph;
     182          57 :         aGlyph.index = aGlyphId & GF_IDXMASK;
     183          57 :         aGlyph.x = aPos.X();
     184          57 :         aGlyph.y = aPos.Y();
     185          57 :         cairo_glyphs.push_back(aGlyph);
     186             : 
     187          57 :         switch (aGlyphId & GF_ROTMASK)
     188             :         {
     189             :             case GF_ROTL:    // left
     190           0 :                 glyph_extrarotation.push_back(1);
     191           0 :                 break;
     192             :             case GF_ROTR:    // right
     193           0 :                 glyph_extrarotation.push_back(-1);
     194           0 :                 break;
     195             :             default:
     196          57 :                 glyph_extrarotation.push_back(0);
     197          57 :                 break;
     198             :         }
     199             :     }
     200             : 
     201           3 :     if (cairo_glyphs.empty())
     202           0 :         return;
     203             : 
     204             :     /*
     205             :      * It might be ideal to cache surface and cairo context between calls and
     206             :      * only destroy it when the drawable changes, but to do that we need to at
     207             :      * least change the SalFrame etc impls to dtor the SalGraphics *before* the
     208             :      * destruction of the windows they reference
     209             :     */
     210           3 :     cairo_t *cr = getCairoContext();
     211           3 :     if (!cr)
     212             :     {
     213             :         SAL_WARN("vcl", "no cairo context for text");
     214           0 :         return;
     215             :     }
     216             : 
     217           3 :     if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions())
     218           3 :         cairo_set_font_options(cr, static_cast<const cairo_font_options_t*>(pOptions));
     219             : 
     220             :     double nDX, nDY;
     221           3 :     getSurfaceOffset(nDX, nDY);
     222           3 :     cairo_translate(cr, nDX, nDY);
     223             : 
     224           3 :     clipRegion(cr);
     225             : 
     226             :     cairo_set_source_rgb(cr,
     227           3 :         SALCOLOR_RED(mnTextColor)/255.0,
     228           3 :         SALCOLOR_GREEN(mnTextColor)/255.0,
     229           9 :         SALCOLOR_BLUE(mnTextColor)/255.0);
     230             : 
     231           3 :     ServerFont& rFont = rLayout.GetServerFont();
     232             : 
     233           3 :     FT_Face aFace = rFont.GetFtFace();
     234             :     CairoFontsCache::CacheId aId;
     235           3 :     aId.maFace = aFace;
     236           3 :     aId.mpOptions = rFont.GetFontOptions().get();
     237           3 :     aId.mbEmbolden = rFont.NeedsArtificialBold();
     238             : 
     239             :     cairo_matrix_t m;
     240           3 :     const FontSelectPattern& rFSD = rFont.GetFontSelData();
     241           3 :     int nHeight = rFSD.mnHeight;
     242           3 :     int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight;
     243             : 
     244           3 :     std::vector<int>::const_iterator aEnd = glyph_extrarotation.end();
     245           3 :     std::vector<int>::const_iterator aStart = glyph_extrarotation.begin();
     246           3 :     std::vector<int>::const_iterator aI = aStart;
     247           9 :     while (aI != aEnd)
     248             :     {
     249           3 :         int nGlyphRotation = *aI;
     250             : 
     251           3 :         std::vector<int>::const_iterator aNext = std::find_if(aI+1, aEnd, hasRotation);
     252             : 
     253           3 :         size_t nStartIndex = std::distance(aStart, aI);
     254           3 :         size_t nLen = std::distance(aI, aNext);
     255             : 
     256           3 :         aId.mbVerticalMetrics = nGlyphRotation != 0.0;
     257           3 :         cairo_font_face_t* font_face = static_cast<cairo_font_face_t*>(CairoFontsCache::FindCachedFont(aId));
     258           3 :         if (!font_face)
     259             :         {
     260           1 :             const ImplFontOptions *pOptions = rFont.GetFontOptions().get();
     261           1 :             void *pPattern = pOptions ? pOptions->GetPattern(aFace, aId.mbEmbolden, aId.mbVerticalMetrics) : NULL;
     262           1 :             if (pPattern)
     263           1 :                 font_face = cairo_ft_font_face_create_for_pattern(static_cast<FcPattern*>(pPattern));
     264           1 :             if (!font_face)
     265           0 :                 font_face = cairo_ft_font_face_create_for_ft_face(reinterpret_cast<FT_Face>(aFace), rFont.GetLoadFlags());
     266           1 :             CairoFontsCache::CacheFont(font_face, aId);
     267             :         }
     268           3 :         cairo_set_font_face(cr, font_face);
     269             : 
     270           3 :         cairo_set_font_size(cr, nHeight);
     271             : 
     272           3 :         cairo_matrix_init_identity(&m);
     273             : 
     274           3 :         if (rLayout.GetOrientation())
     275           0 :             cairo_matrix_rotate(&m, toRadian(rLayout.GetOrientation()));
     276             : 
     277           3 :         cairo_matrix_scale(&m, nWidth, nHeight);
     278             : 
     279           3 :         if (nGlyphRotation)
     280             :         {
     281           0 :             cairo_matrix_rotate(&m, toRadian(nGlyphRotation*900));
     282             : 
     283             :             cairo_matrix_t em_square;
     284           0 :             cairo_matrix_init_identity(&em_square);
     285           0 :             cairo_get_matrix(cr, &em_square);
     286             : 
     287             :             cairo_matrix_scale(&em_square, aFace->units_per_EM,
     288           0 :                 aFace->units_per_EM);
     289           0 :             cairo_set_matrix(cr, &em_square);
     290             : 
     291             :             cairo_font_extents_t font_extents;
     292           0 :             cairo_font_extents(cr, &font_extents);
     293             : 
     294           0 :             cairo_matrix_init_identity(&em_square);
     295           0 :             cairo_set_matrix(cr, &em_square);
     296             : 
     297             :             //gives the same positions as pre-cairo conversion, but I don't
     298             :             //like them
     299           0 :             double xdiff = 0.0;
     300           0 :             double ydiff = 0.0;
     301           0 :             if (nGlyphRotation == 1)
     302             :             {
     303           0 :                 ydiff = font_extents.ascent/nHeight;
     304           0 :                 xdiff = -font_extents.descent/nHeight;
     305             :             }
     306           0 :             else if (nGlyphRotation == -1)
     307             :             {
     308             :                 cairo_text_extents_t text_extents;
     309           0 :                 cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen,
     310           0 :                     &text_extents);
     311             : 
     312           0 :                 xdiff = -text_extents.x_advance/nHeight;
     313             :                 //to restore an apparent bug in the original X11 impl, replace
     314             :                 //nHeight with nWidth below
     315           0 :                 xdiff += font_extents.descent/nHeight;
     316             :             }
     317           0 :             cairo_matrix_translate(&m, xdiff, ydiff);
     318             :         }
     319             : 
     320           3 :         if (rFont.NeedsArtificialItalic())
     321             :         {
     322             :             cairo_matrix_t shear;
     323           0 :             cairo_matrix_init_identity(&shear);
     324           0 :             shear.xy = -shear.xx * 0x6000L / 0x10000L;
     325           0 :             cairo_matrix_multiply(&m, &shear, &m);
     326             :         }
     327             : 
     328           3 :         cairo_set_font_matrix(cr, &m);
     329           3 :         cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
     330             : 
     331             : #if OSL_DEBUG_LEVEL > 2
     332             :         //draw origin
     333             :         cairo_save (cr);
     334             :         cairo_rectangle (cr, cairo_glyphs[nStartIndex].x, cairo_glyphs[nStartIndex].y, 5, 5);
     335             :         cairo_set_source_rgba (cr, 1, 0, 0, 0.80);
     336             :         cairo_fill (cr);
     337             :         cairo_restore (cr);
     338             : #endif
     339             : 
     340           3 :         aI = aNext;
     341             :     }
     342             : 
     343           3 :     cairo_surface_flush(cairo_get_target(cr));
     344           3 :     drawSurface(cr);
     345           6 :     cairo_destroy(cr);
     346             : }
     347             : 
     348           0 : const FontCharMapPtr CairoTextRender::GetFontCharMap() const
     349             : {
     350           0 :     if( !mpServerFont[0] )
     351           0 :         return NULL;
     352             : 
     353           0 :     const FontCharMapPtr pFCMap = mpServerFont[0]->GetFontCharMap();
     354           0 :     return pFCMap;
     355             : }
     356             : 
     357           0 : bool CairoTextRender::GetFontCapabilities(vcl::FontCapabilities &rGetImplFontCapabilities) const
     358             : {
     359           0 :     if (!mpServerFont[0])
     360           0 :         return false;
     361           0 :     return mpServerFont[0]->GetFontCapabilities(rGetImplFontCapabilities);
     362             : }
     363             : 
     364             : // SalGraphics
     365             : 
     366         518 : sal_uInt16 CairoTextRender::SetFont( FontSelectPattern *pEntry, int nFallbackLevel )
     367             : {
     368         518 :     sal_uInt16 nRetVal = 0;
     369         518 :     if (!setFont(pEntry, nFallbackLevel))
     370         399 :         nRetVal |= SAL_SETFONT_BADFONT;
     371         518 :     if (mpServerFont[nFallbackLevel])
     372         119 :         nRetVal |= SAL_SETFONT_USEDRAWTEXTARRAY;
     373         518 :     return nRetVal;
     374             : }
     375             : 
     376             : void
     377           3 : CairoTextRender::SetTextColor( SalColor nSalColor )
     378             : {
     379           3 :     if( mnTextColor != nSalColor )
     380             :     {
     381           0 :         mnTextColor = nSalColor;
     382             :     }
     383           3 : }
     384             : 
     385           0 : bool CairoTextRender::AddTempDevFont( PhysicalFontCollection* pFontCollection,
     386             :                                      const OUString& rFileURL,
     387             :                                      const OUString& rFontName )
     388             : {
     389             :     // inform PSP font manager
     390           0 :     OUString aUSystemPath;
     391           0 :     OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFileURL, aUSystemPath ) );
     392           0 :     rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
     393           0 :     OString aOFileName( OUStringToOString( aUSystemPath, aEncoding ) );
     394           0 :     psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
     395           0 :     std::vector<psp::fontID> aFontIds = rMgr.addFontFile( aOFileName );
     396           0 :     if( aFontIds.empty() )
     397           0 :         return false;
     398             : 
     399           0 :     GlyphCache& rGC = getPlatformGlyphCache();
     400             : 
     401           0 :     for (std::vector<psp::fontID>::iterator aI = aFontIds.begin(), aEnd = aFontIds.end(); aI != aEnd; ++aI)
     402             :     {
     403             :         // prepare font data
     404           0 :         psp::FastPrintFontInfo aInfo;
     405           0 :         rMgr.getFontFastInfo( *aI, aInfo );
     406           0 :         aInfo.m_aFamilyName = rFontName;
     407             : 
     408             :         // inform glyph cache of new font
     409           0 :         ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
     410           0 :         aDFA.mnQuality += 5800;
     411             : 
     412           0 :         int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
     413             : 
     414           0 :         const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
     415           0 :         rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
     416           0 :     }
     417             : 
     418             :     // announce new font to device's font list
     419           0 :     rGC.AnnounceFonts( pFontCollection );
     420           0 :     return true;
     421             : }
     422             : 
     423           0 : void CairoTextRender::ClearDevFontCache()
     424             : {
     425           0 :     GlyphCache& rGC = getPlatformGlyphCache();
     426           0 :     rGC.ClearFontCache();
     427           0 : }
     428             : 
     429           3 : void CairoTextRender::GetDevFontList( PhysicalFontCollection* pFontCollection )
     430             : {
     431             :     // prepare the GlyphCache using psprint's font infos
     432           3 :     GlyphCache& rGC = getPlatformGlyphCache();
     433             : 
     434           3 :     psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
     435           3 :     ::std::list< psp::fontID > aList;
     436           3 :     ::std::list< psp::fontID >::iterator it;
     437           6 :     psp::FastPrintFontInfo aInfo;
     438           3 :     rMgr.getFontList( aList );
     439         708 :     for( it = aList.begin(); it != aList.end(); ++it )
     440             :     {
     441         705 :         if( !rMgr.getFontFastInfo( *it, aInfo ) )
     442           0 :             continue;
     443             : 
     444             :         // normalize face number to the GlyphCache
     445         705 :         int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
     446             : 
     447             :         // inform GlyphCache about this font provided by the PsPrint subsystem
     448         705 :         ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
     449         705 :         aDFA.mnQuality += 4096;
     450        1410 :         const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
     451         705 :         rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
     452         705 :    }
     453             : 
     454             :     // announce glyphcache fonts
     455           3 :     rGC.AnnounceFonts( pFontCollection );
     456             : 
     457             :     // register platform specific font substitutions if available
     458           3 :     SalGenericInstance::RegisterFontSubstitutors( pFontCollection );
     459             : 
     460           6 :     ImplGetSVData()->maGDIData.mbNativeFontConfig = true;
     461           3 : }
     462             : 
     463          37 : void cairosubcallback(void* pPattern)
     464             : {
     465          37 :     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
     466          37 :     const void* pFontOptions = rStyleSettings.GetCairoFontOptions();
     467          37 :     if( !pFontOptions )
     468          37 :         return;
     469             :     cairo_ft_font_options_substitute(static_cast<const cairo_font_options_t*>(pFontOptions),
     470          37 :         static_cast<FcPattern*>(pPattern));
     471             : }
     472             : 
     473          37 : ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize)
     474             : {
     475          37 :     psp::FastPrintFontInfo aInfo;
     476             : 
     477          37 :     aInfo.m_aFamilyName = rFontAttributes.GetFamilyName();
     478          37 :     aInfo.m_eItalic = rFontAttributes.GetSlant();
     479          37 :     aInfo.m_eWeight = rFontAttributes.GetWeight();
     480          37 :     aInfo.m_eWidth = rFontAttributes.GetWidthType();
     481             : 
     482          37 :     return psp::PrintFontManager::getFontOptions(aInfo, nSize, cairosubcallback);
     483             : }
     484             : 
     485             : void
     486          48 : CairoTextRender::GetFontMetric( ImplFontMetricData *pMetric, int nFallbackLevel )
     487             : {
     488          48 :     if( nFallbackLevel >= MAX_FALLBACK )
     489          48 :         return;
     490             : 
     491          48 :     if( mpServerFont[nFallbackLevel] != NULL )
     492             :     {
     493             :         long rDummyFactor;
     494          48 :         mpServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor );
     495             :     }
     496             : }
     497             : 
     498         256 : bool CairoTextRender::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect )
     499             : {
     500         256 :     const int nLevel = aGlyphId >> GF_FONTSHIFT;
     501         256 :     if( nLevel >= MAX_FALLBACK )
     502           0 :         return false;
     503             : 
     504         256 :     ServerFont* pSF = mpServerFont[ nLevel ];
     505         256 :     if( !pSF )
     506           0 :         return false;
     507             : 
     508         256 :     aGlyphId &= GF_IDXMASK;
     509         256 :     const GlyphMetric& rGM = pSF->GetGlyphMetric(aGlyphId);
     510         256 :     Rectangle aRect( rGM.GetOffset(), rGM.GetSize() );
     511             : 
     512         256 :     if ( pSF->mnCos != 0x10000 && pSF->mnSin != 0 )
     513             :     {
     514           0 :         double nCos = pSF->mnCos / 65536.0;
     515           0 :         double nSin = pSF->mnSin / 65536.0;
     516           0 :         rRect.Left() =  nCos*aRect.Left() + nSin*aRect.Top();
     517           0 :         rRect.Top()  = -nSin*aRect.Left() - nCos*aRect.Top();
     518             : 
     519           0 :         rRect.Right()  =  nCos*aRect.Right() + nSin*aRect.Bottom();
     520           0 :         rRect.Bottom() = -nSin*aRect.Right() - nCos*aRect.Bottom();
     521             :     }
     522             :     else
     523         256 :         rRect = aRect;
     524             : 
     525         256 :     return true;
     526             : }
     527             : 
     528           0 : bool CairoTextRender::GetGlyphOutline( sal_GlyphId aGlyphId,
     529             :     ::basegfx::B2DPolyPolygon& rPolyPoly )
     530             : {
     531           0 :     const int nLevel = aGlyphId >> GF_FONTSHIFT;
     532           0 :     if( nLevel >= MAX_FALLBACK )
     533           0 :         return false;
     534             : 
     535           0 :     ServerFont* pSF = mpServerFont[ nLevel ];
     536           0 :     if( !pSF )
     537           0 :         return false;
     538             : 
     539           0 :     aGlyphId &= GF_IDXMASK;
     540           0 :     if( pSF->GetGlyphOutline( aGlyphId, rPolyPoly ) )
     541           0 :         return true;
     542             : 
     543           0 :     return false;
     544             : }
     545             : 
     546         313 : SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
     547             : {
     548         313 :     SalLayout* pLayout = NULL;
     549             : 
     550         940 :     if( mpServerFont[ nFallbackLevel ]
     551        1251 :     && !(rArgs.mnFlags & SalLayoutFlags::DisableGlyphProcessing) )
     552             :     {
     553             : #if ENABLE_GRAPHITE
     554             :         // Is this a Graphite font?
     555         624 :         if (!bDisableGraphite_ &&
     556         312 :             GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
     557             :         {
     558           0 :             pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
     559             :         }
     560             :         else
     561             : #endif
     562         312 :             pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
     563             :     }
     564             : 
     565         313 :     return pLayout;
     566             : }
     567             : 
     568           0 : SystemFontData CairoTextRender::GetSysFontData( int nFallbackLevel ) const
     569             : {
     570           0 :     SystemFontData aSysFontData;
     571             : 
     572           0 :     if (nFallbackLevel >= MAX_FALLBACK) nFallbackLevel = MAX_FALLBACK - 1;
     573           0 :     if (nFallbackLevel < 0 ) nFallbackLevel = 0;
     574             : 
     575           0 :     if (mpServerFont[nFallbackLevel] != NULL)
     576             :     {
     577           0 :         ServerFont* rFont = mpServerFont[nFallbackLevel];
     578           0 :         aSysFontData.nFontId = rFont->GetFtFace();
     579           0 :         aSysFontData.nFontFlags = rFont->GetLoadFlags();
     580           0 :         aSysFontData.bFakeBold = rFont->NeedsArtificialBold();
     581           0 :         aSysFontData.bFakeItalic = rFont->NeedsArtificialItalic();
     582           0 :         aSysFontData.bAntialias = rFont->GetAntialiasAdvice();
     583           0 :         aSysFontData.bVerticalCharacterType = rFont->GetFontSelData().mbVertical;
     584             :     }
     585             : 
     586           0 :     return aSysFontData;
     587             : }
     588             : 
     589           0 : bool CairoTextRender::CreateFontSubset(
     590             :                                    const OUString& rToFile,
     591             :                                    const PhysicalFontFace* pFont,
     592             :                                    const sal_GlyphId* pGlyphIds,
     593             :                                    const sal_uInt8* pEncoding,
     594             :                                    sal_Int32* pWidths,
     595             :                                    int nGlyphCount,
     596             :                                    FontSubsetInfo& rInfo
     597             :                                    )
     598             : {
     599             :     // in this context the pFont->GetFontId() is a valid PSP
     600             :     // font since they are the only ones left after the PDF
     601             :     // export has filtered its list of subsettable fonts (for
     602             :     // which this method was created). The correct way would
     603             :     // be to have the GlyphCache search for the PhysicalFontFace pFont
     604           0 :     psp::fontID aFont = pFont->GetFontId();
     605             : 
     606           0 :     psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
     607             :     bool bSuccess = rMgr.createFontSubset( rInfo,
     608             :                                  aFont,
     609             :                                  rToFile,
     610             :                                  pGlyphIds,
     611             :                                  pEncoding,
     612             :                                  pWidths,
     613           0 :                                  nGlyphCount );
     614           0 :     return bSuccess;
     615             : }
     616             : 
     617           0 : const void* CairoTextRender::GetEmbedFontData( const PhysicalFontFace* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, size_t nLen, FontSubsetInfo& rInfo, long* pDataLen )
     618             : {
     619             :     // in this context the pFont->GetFontId() is a valid PSP
     620             :     // font since they are the only ones left after the PDF
     621             :     // export has filtered its list of subsettable fonts (for
     622             :     // which this method was created). The correct way would
     623             :     // be to have the GlyphCache search for the PhysicalFontFace pFont
     624           0 :     psp::fontID aFont = pFont->GetFontId();
     625           0 :     return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, nLen, rInfo, pDataLen );
     626             : }
     627             : 
     628           0 : void CairoTextRender::FreeEmbedFontData( const void* pData, long nLen )
     629             : {
     630           0 :     GenPspGraphics::DoFreeEmbedFontData( pData, nLen );
     631           0 : }
     632             : 
     633           0 : const Ucs2SIntMap* CairoTextRender::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded, std::set<sal_Unicode> const** ppPriority)
     634             : {
     635             :     // in this context the pFont->GetFontId() is a valid PSP
     636             :     // font since they are the only ones left after the PDF
     637             :     // export has filtered its list of subsettable fonts (for
     638             :     // which this method was created). The correct way would
     639             :     // be to have the GlyphCache search for the PhysicalFontFace pFont
     640           0 :     psp::fontID aFont = pFont->GetFontId();
     641           0 :     return GenPspGraphics::DoGetFontEncodingVector(aFont, pNonEncoded, ppPriority);
     642             : }
     643             : 
     644           0 : void CairoTextRender::GetGlyphWidths( const PhysicalFontFace* pFont,
     645             :                                    bool bVertical,
     646             :                                    Int32Vector& rWidths,
     647             :                                    Ucs2UIntMap& rUnicodeEnc )
     648             : {
     649             :     // in this context the pFont->GetFontId() is a valid PSP
     650             :     // font since they are the only ones left after the PDF
     651             :     // export has filtered its list of subsettable fonts (for
     652             :     // which this method was created). The correct way would
     653             :     // be to have the GlyphCache search for the PhysicalFontFace pFont
     654           0 :     psp::fontID aFont = pFont->GetFontId();
     655           0 :     GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
     656         801 : }
     657             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11