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

Generated by: LCOV version 1.10