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

Generated by: LCOV version 1.10