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

Generated by: LCOV version 1.10