[Libreoffice-commits] core.git: Branch 'feature/opengl-vcl' - 3 commits - vcl/inc vcl/Library_vclplug_gen.mk vcl/unx

Markus Mohrhard markus.mohrhard at collabora.co.uk
Wed Nov 5 21:34:46 PST 2014


 vcl/Library_vclplug_gen.mk                 |    2 
 vcl/inc/cairotextrender.hxx                |  128 +++++
 vcl/inc/generic/glyphcache.hxx             |    1 
 vcl/inc/graphite_serverfont.hxx            |    2 
 vcl/inc/textrender.hxx                     |   81 +++
 vcl/inc/unx/salgdi.h                       |   44 -
 vcl/unx/generic/gdi/cairotextrender.cxx    |  659 +++++++++++++++++++++++++++++
 vcl/unx/generic/gdi/salgdi.cxx             |   14 
 vcl/unx/generic/gdi/salgdi3.cxx            |  590 +------------------------
 vcl/unx/generic/gdi/x11cairotextrender.cxx |   96 ++++
 vcl/unx/generic/gdi/x11cairotextrender.hxx |   39 +
 11 files changed, 1040 insertions(+), 616 deletions(-)

New commits:
commit cbc14f4f2d32880f886eb26af9220eb8595f036c
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Thu Nov 6 06:33:45 2014 +0100

    forgot to init the variable for the text rendering
    
    Change-Id: I307a83e1b5564f0bb91dcb6c30a78f2bd560a911

diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index d8eef57..2960b63 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -55,6 +55,7 @@
 #include "textrender.hxx"
 #include "gdiimpl.hxx"
 #include "openglgdiimpl.hxx"
+#include "x11cairotextrender.hxx"
 
 #include "generic/printergfx.hxx"
 #include "xrender_peer.hxx"
@@ -64,6 +65,7 @@
 #include <vcl/opengl/OpenGLHelper.hxx>
 
 X11SalGraphics::X11SalGraphics():
+    mpTextRenderImpl(new X11CairoTextRender(false, *this)),
     m_pFrame(NULL),
     m_pVDev(NULL),
     m_pColormap(NULL),
@@ -87,6 +89,7 @@ X11SalGraphics::X11SalGraphics():
         mpImpl.reset(new OpenGLSalGraphicsImpl());
     else
         mpImpl.reset(new X11SalGraphicsImpl(*this));
+
 }
 
 X11SalGraphics::~X11SalGraphics()
commit bfdf26bb4da9b68c9459468dd1cea6765102d994
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Thu Nov 6 06:05:26 2014 +0100

    move the abstract cairo text render code out of the unx dir
    
    Change-Id: Ie40850916359637b983f2c303e875bc5bf041cb1

diff --git a/vcl/inc/unx/cairotextrender.hxx b/vcl/inc/cairotextrender.hxx
similarity index 100%
rename from vcl/inc/unx/cairotextrender.hxx
rename to vcl/inc/cairotextrender.hxx
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index e4bee50..5adbd87 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -17,7 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include "unx/cairotextrender.hxx"
+#include "cairotextrender.hxx"
 
 #include <basegfx/polygon/b2dpolypolygon.hxx>
 #include <vcl/settings.hxx>
diff --git a/vcl/unx/generic/gdi/x11cairotextrender.hxx b/vcl/unx/generic/gdi/x11cairotextrender.hxx
index eb44102..99688d1 100644
--- a/vcl/unx/generic/gdi/x11cairotextrender.hxx
+++ b/vcl/unx/generic/gdi/x11cairotextrender.hxx
@@ -17,7 +17,7 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-#include "unx/cairotextrender.hxx"
+#include "cairotextrender.hxx"
 
 #include "unx/saldata.hxx"
 #include "unx/saldisp.hxx"
commit 655cf68e3196a0b9de25738ba3cd723c0e9e8c22
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Tue Nov 4 04:29:13 2014 +0100

    extract cairo rendering and abstract platform bits
    
    The text rendering is now abstracted into the TextRender abstract class.
    Additionally we have now an abstracted cairo rendering class
    CairoTextRender which is a subclass of the TextRender class. The
    CairoTextRender class is still platform independent and needs to be
    subclassed to implement the few platform dependent methods.
    
    You can reuse the cairo based text rendering now by subclassing
    CairoTextRender for the platform that you need.
    
    Conflicts:
    	vcl/unx/generic/gdi/salgdi.cxx
    
    Change-Id: I8b07e3fe646a81563d308971d30e14a00fd921ad

diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index d25eec6..fe9f4f6 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -88,6 +88,8 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gen,\
     vcl/unx/generic/dtrans/X11_selection \
     vcl/unx/generic/dtrans/X11_service \
     vcl/unx/generic/dtrans/X11_transferable \
+    vcl/unx/generic/gdi/cairotextrender \
+    vcl/unx/generic/gdi/x11cairotextrender \
     vcl/unx/generic/gdi/gcach_xpeer \
 	vcl/unx/generic/gdi/gdiimpl \
     vcl/unx/generic/gdi/salbmp \
diff --git a/vcl/inc/generic/glyphcache.hxx b/vcl/inc/generic/glyphcache.hxx
index ba44ae8..ddfc7a8 100644
--- a/vcl/inc/generic/glyphcache.hxx
+++ b/vcl/inc/generic/glyphcache.hxx
@@ -205,6 +205,7 @@ private:
     friend class ServerFontLayout;
     friend class ImplServerFontEntry;
     friend class X11SalGraphics;
+    friend class CairoTextRender;
 
     void                        AddRef() const      { ++mnRefCount; }
     long                        GetRefCount() const { return mnRefCount; }
diff --git a/vcl/inc/graphite_serverfont.hxx b/vcl/inc/graphite_serverfont.hxx
index 0d533e0..7dfde21 100644
--- a/vcl/inc/graphite_serverfont.hxx
+++ b/vcl/inc/graphite_serverfont.hxx
@@ -26,6 +26,8 @@
 #ifndef _MSC_VER
 #include <graphite_layout.hxx>
 
+#include "generic/glyphcache.hxx"
+
 class PhysicalFontFace;
 
 // Modules
diff --git a/vcl/inc/textrender.hxx b/vcl/inc/textrender.hxx
new file mode 100644
index 0000000..b18b630
--- /dev/null
+++ b/vcl/inc/textrender.hxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_UNX_CAIROFONTIMPL_HXX
+#define INCLUDED_VCL_INC_UNX_CAIROFONTIMPL_HXX
+
+#include <tools/rational.hxx>
+#include <vcl/salgtype.hxx>
+#include <vcl/vclenum.hxx>
+#include <vcl/metric.hxx>
+
+#include "salgdi.hxx"
+#include "salglyphid.hxx"
+#include "fontsubset.hxx"
+
+class PspSalPrinter;
+class PspSalInfoPrinter;
+class ServerFont;
+class ImplLayoutArgs;
+class ServerFontLayout;
+class PhysicalFontCollection;
+class PhysicalFontFace;
+
+class TextRenderImpl
+{
+public:
+    virtual ~TextRenderImpl() {}
+
+    virtual void            SetTextColor( SalColor nSalColor ) = 0;
+    virtual sal_uInt16          SetFont( FontSelectPattern*, int nFallbackLevel ) = 0;
+    virtual void            GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) = 0;
+    virtual const FontCharMapPtr GetFontCharMap() const = 0;
+    virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const = 0;
+    virtual void            GetDevFontList( PhysicalFontCollection* ) = 0;
+    virtual void ClearDevFontCache() = 0;
+    virtual bool            AddTempDevFont( PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) = 0;
+    virtual bool            CreateFontSubset( const OUString& rToFile,
+                                              const PhysicalFontFace*,
+                                              sal_GlyphId* pGlyphIDs,
+                                              sal_uInt8* pEncoding,
+                                              sal_Int32* pWidths,
+                                              int nGlyphs,
+                                              FontSubsetInfo& rInfo
+                                              ) = 0;
+    virtual const Ucs2SIntMap* GetFontEncodingVector( const PhysicalFontFace*, const Ucs2OStrMap** ppNonEncoded ) = 0;
+    virtual const void* GetEmbedFontData( const PhysicalFontFace*,
+                                          const sal_Ucs* pUnicodes,
+                                          sal_Int32* pWidths,
+                                          FontSubsetInfo& rInfo,
+                                          long* pDataLen ) = 0;
+    virtual void            FreeEmbedFontData( const void* pData, long nDataLen ) = 0;
+    virtual void            GetGlyphWidths( const PhysicalFontFace*,
+                                            bool bVertical,
+                                            Int32Vector& rWidths,
+                                            Ucs2UIntMap& rUnicodeEnc ) = 0;
+    virtual bool            GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) = 0;
+    virtual bool            GetGlyphOutline( sal_GlyphId nIndex, ::basegfx::B2DPolyPolygon& ) = 0;
+    virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) = 0;
+    virtual void            DrawServerFontLayout( const ServerFontLayout& ) = 0;
+    virtual SystemFontData  GetSysFontData( int nFallbackLevel ) const = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/cairotextrender.hxx b/vcl/inc/unx/cairotextrender.hxx
new file mode 100644
index 0000000..7bc0b2f
--- /dev/null
+++ b/vcl/inc/unx/cairotextrender.hxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_UNX_CAIROTEXTRENDER_HXX
+#define INCLUDED_VCL_INC_UNX_CAIROTEXTRENDER_HXX
+
+#include "textrender.hxx"
+#include <vcl/region.hxx>
+#include <deque>
+
+typedef struct FT_FaceRec_* FT_Face;
+
+class PspSalPrinter;
+class PspSalInfoPrinter;
+class ServerFont;
+class GlyphCache;
+class ImplLayoutArgs;
+class ServerFontLayout;
+class PhysicalFontCollection;
+class PhysicalFontFace;
+struct _cairo_surface_t;
+typedef struct _cairo_surface cairo_surface_t;
+typedef struct _cairo cairo_t;
+
+class CairoFontsCache
+{
+public:
+    struct CacheId
+    {
+        FT_Face maFace;
+        const void *mpOptions;
+        bool mbEmbolden;
+        bool mbVerticalMetrics;
+        bool operator ==(const CacheId& rOther) const
+        {
+            return maFace == rOther.maFace &&
+                mpOptions == rOther.mpOptions &&
+                mbEmbolden == rOther.mbEmbolden &&
+                mbVerticalMetrics == rOther.mbVerticalMetrics;
+        }
+    };
+private:
+    static int mnRefCount;
+    typedef std::deque< std::pair<void *, CacheId> > LRUFonts;
+    static LRUFonts maLRUFonts;
+public:
+    CairoFontsCache();
+    static void  CacheFont(void *pFont, const CacheId &rId);
+    static void* FindCachedFont(const CacheId &rId);
+    ~CairoFontsCache();
+};
+
+class CairoTextRender : public TextRenderImpl
+{
+    bool mbPrinter;
+    ServerFont* mpServerFont[ MAX_FALLBACK ];
+
+    SalColor nTextColor_;
+    CairoFontsCache m_aCairoFontsCache;
+
+protected:
+    virtual GlyphCache& getPlatformGlyphCache() = 0;
+    virtual cairo_surface_t* getCairoSurface() = 0;
+
+bool setFont( const FontSelectPattern *pEntry, int nFallbackLevel );
+
+    virtual void clipRegion(cairo_t* cr) = 0;
+
+public:
+    CairoTextRender(bool bPrinter);
+
+
+    virtual void            SetTextColor( SalColor nSalColor ) SAL_OVERRIDE;
+    virtual sal_uInt16          SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE;
+    virtual void            GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE;
+    virtual const FontCharMapPtr GetFontCharMap() const SAL_OVERRIDE;
+    virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE;
+    virtual void            GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE;
+    virtual void ClearDevFontCache() SAL_OVERRIDE;
+    virtual bool            AddTempDevFont( PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) SAL_OVERRIDE;
+    virtual bool            CreateFontSubset( const OUString& rToFile,
+                                              const PhysicalFontFace*,
+                                              sal_GlyphId* pGlyphIDs,
+                                              sal_uInt8* pEncoding,
+                                              sal_Int32* pWidths,
+                                              int nGlyphs,
+                                              FontSubsetInfo& rInfo
+                                              ) SAL_OVERRIDE;
+    virtual const Ucs2SIntMap* GetFontEncodingVector( const PhysicalFontFace*, const Ucs2OStrMap** ppNonEncoded ) SAL_OVERRIDE;
+    virtual const void* GetEmbedFontData( const PhysicalFontFace*,
+                                          const sal_Ucs* pUnicodes,
+                                          sal_Int32* pWidths,
+                                          FontSubsetInfo& rInfo,
+                                          long* pDataLen ) SAL_OVERRIDE;
+    virtual void            FreeEmbedFontData( const void* pData, long nDataLen ) SAL_OVERRIDE;
+    virtual void            GetGlyphWidths( const PhysicalFontFace*,
+                                            bool bVertical,
+                                            Int32Vector& rWidths,
+                                            Ucs2UIntMap& rUnicodeEnc ) SAL_OVERRIDE;
+    virtual bool            GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) SAL_OVERRIDE;
+    virtual bool            GetGlyphOutline( sal_GlyphId nIndex, ::basegfx::B2DPolyPolygon& ) SAL_OVERRIDE;
+    virtual SalLayout*      GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) SAL_OVERRIDE;
+    virtual void            DrawServerFontLayout( const ServerFontLayout& ) SAL_OVERRIDE;
+    virtual SystemFontData  GetSysFontData( int nFallbackLevel ) const SAL_OVERRIDE;
+
+private:
+    bool            bDisableGraphite_;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h
index fcb4a9d..b4e05bc 100644
--- a/vcl/inc/unx/salgdi.h
+++ b/vcl/inc/unx/salgdi.h
@@ -52,48 +52,21 @@ class ServerFontLayout;
 class PhysicalFontCollection;
 class PhysicalFontFace;
 class SalGraphicsImpl;
+class TextRenderImpl;
 
 namespace basegfx {
     class B2DTrapezoid;
 }
 
-typedef struct FT_FaceRec_* FT_Face;
-
-class CairoFontsCache
-{
-public:
-    struct CacheId
-    {
-        FT_Face maFace;
-        const void *mpOptions;
-        bool mbEmbolden;
-        bool mbVerticalMetrics;
-        bool operator ==(const CacheId& rOther) const
-        {
-            return maFace == rOther.maFace &&
-                mpOptions == rOther.mpOptions &&
-                mbEmbolden == rOther.mbEmbolden &&
-                mbVerticalMetrics == rOther.mbVerticalMetrics;
-        }
-    };
-private:
-    static int mnRefCount;
-    typedef std::deque< std::pair<void *, CacheId> > LRUFonts;
-    static LRUFonts maLRUFonts;
-public:
-    CairoFontsCache();
-    static void  CacheFont(void *pFont, const CacheId &rId);
-    static void* FindCachedFont(const CacheId &rId);
-    ~CairoFontsCache();
-};
-
 class VCLPLUG_GEN_PUBLIC X11SalGraphics : public SalGraphics
 {
     friend class ServerFontLayout;
     friend class X11SalGraphicsImpl;
+    friend class X11CairoTextRender;
 
 private:
     boost::scoped_ptr<SalGraphicsImpl> mpImpl;
+    boost::scoped_ptr<TextRenderImpl> mpTextRenderImpl;
 
 protected:
     SalFrame*               m_pFrame; // the SalFrame which created this Graphics or NULL
@@ -105,18 +78,12 @@ protected:
     SalX11Screen    m_nXScreen;
     mutable XRenderPictFormat* m_pXRenderFormat;
     XID             m_aXRenderPicture;
-    CairoFontsCache m_aCairoFontsCache;
 
     Region          pPaintRegion_;
     Region          mpClipRegion;
 
     GC              pFontGC_;       // Font attributes
-    ServerFont*             mpServerFont[ MAX_FALLBACK ];
-
-    SalColor        nTextColor_;
-    Pixel           nTextPixel_;
-
-    bool            bDisableGraphite_;
+    Pixel nTextPixel_;
 
     Pixmap          hBrush_;        // Dither
 
@@ -140,7 +107,6 @@ protected:
                                 SalColor          nTransparentColor );
 
     GC                      GetFontGC();
-    bool                    setFont( const FontSelectPattern* pEntry, int nFallbackLevel );
 
 protected:
     void                    DrawPrinterString( const SalLayout& );
@@ -294,7 +260,7 @@ public:
                                            long nHeight, sal_uInt8 nTransparency ) SAL_OVERRIDE;
 
     virtual SystemGraphicsData GetGraphicsData() const SAL_OVERRIDE;
-    virtual SystemFontData     GetSysFontData( int nFallbacklevel ) const SAL_OVERRIDE;
+    virtual SystemFontData     GetSysFontData( int nFallbackLevel ) const SAL_OVERRIDE;
 
     virtual bool               SwapBuffers() SAL_OVERRIDE;
 
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
new file mode 100644
index 0000000..e4bee50
--- /dev/null
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -0,0 +1,659 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "unx/cairotextrender.hxx"
+
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/sysdata.hxx>
+
+#include "generic/printergfx.hxx"
+#include "generic/genpspgraphics.h"
+#include "generic/geninst.h"
+#include "PhysicalFontFace.hxx"
+#include "impfont.hxx"
+
+#include <config_graphite.h>
+#if ENABLE_GRAPHITE
+#include <graphite_layout.hxx>
+#include <graphite_serverfont.hxx>
+#endif
+
+#include <cairo.h>
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
+
+CairoTextRender::CairoTextRender(bool bPrinter):
+    mbPrinter(bPrinter),
+    nTextColor_(MAKE_SALCOLOR(0x00, 0x00, 0x00)) //black
+{
+    for( int i = 0; i < MAX_FALLBACK; ++i )
+        mpServerFont[i] = NULL;
+
+#if ENABLE_GRAPHITE
+    // check if graphite fonts have been disabled
+    static const char* pDisableGraphiteStr = getenv( "SAL_DISABLE_GRAPHITE" );
+    bDisableGraphite_ = pDisableGraphiteStr && (pDisableGraphiteStr[0]!='0');
+#endif
+}
+
+bool CairoTextRender::setFont( const FontSelectPattern *pEntry, int nFallbackLevel )
+{
+    // release all no longer needed font resources
+    for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
+    {
+        if( mpServerFont[i] != NULL )
+        {
+            // old server side font is no longer referenced
+            GlyphCache::GetInstance().UncacheFont( *mpServerFont[i] );
+            mpServerFont[i] = NULL;
+        }
+    }
+
+    // return early if there is no new font
+    if( !pEntry )
+        return false;
+
+    // return early if this is not a valid font for this graphics
+    if( !pEntry->mpFontData )
+        return false;
+
+    // handle the request for a non-native X11-font => use the GlyphCache
+    ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
+    if( pServerFont != NULL )
+    {
+        // ignore fonts with e.g. corrupted font files
+        if( !pServerFont->TestFont() )
+        {
+            GlyphCache::GetInstance().UncacheFont( *pServerFont );
+            return false;
+        }
+
+        // register to use the font
+        mpServerFont[ nFallbackLevel ] = pServerFont;
+
+        // apply font specific-hint settings if needed
+        // TODO: also disable it for reference devices
+        if( !mbPrinter )
+        {
+            ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry );
+            pSFE->HandleFontOptions();
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize);
+
+void ImplServerFontEntry::HandleFontOptions( void )
+{
+    if( !mpServerFont )
+        return;
+    if( !mbGotFontOptions )
+    {
+        // get and cache the font options
+        mbGotFontOptions = true;
+        mpFontOptions.reset(GetFCFontOptions( *maFontSelData.mpFontData,
+            maFontSelData.mnHeight ));
+    }
+    // apply the font options
+    mpServerFont->SetFontOptions( mpFontOptions );
+}
+
+CairoFontsCache::LRUFonts CairoFontsCache::maLRUFonts;
+int CairoFontsCache::mnRefCount = 0;
+
+CairoFontsCache::CairoFontsCache()
+{
+    ++mnRefCount;
+}
+
+CairoFontsCache::~CairoFontsCache()
+{
+    --mnRefCount;
+    if (!mnRefCount && !maLRUFonts.empty())
+    {
+        LRUFonts::iterator aEnd = maLRUFonts.end();
+        for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
+            cairo_font_face_destroy((cairo_font_face_t*)aI->first);
+    }
+}
+
+void CairoFontsCache::CacheFont(void *pFont, const CairoFontsCache::CacheId &rId)
+{
+    maLRUFonts.push_front( std::pair<void*, CairoFontsCache::CacheId>(pFont, rId) );
+    if (maLRUFonts.size() > 8)
+    {
+        cairo_font_face_destroy((cairo_font_face_t*)maLRUFonts.back().first);
+        maLRUFonts.pop_back();
+    }
+}
+
+void* CairoFontsCache::FindCachedFont(const CairoFontsCache::CacheId &rId)
+{
+    LRUFonts::iterator aEnd = maLRUFonts.end();
+    for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
+        if (aI->second == rId)
+            return aI->first;
+    return NULL;
+}
+
+namespace
+{
+    bool hasRotation(int nRotation)
+    {
+      return nRotation != 0;
+    }
+
+    double toRadian(int nDegree10th)
+    {
+        return (3600 - (nDegree10th)) * M_PI / 1800.0;
+    }
+}
+
+void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout )
+{
+    std::vector<cairo_glyph_t> cairo_glyphs;
+    std::vector<int> glyph_extrarotation;
+    cairo_glyphs.reserve( 256 );
+
+    Point aPos;
+    sal_GlyphId aGlyphId;
+    for( int nStart = 0; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
+    {
+        cairo_glyph_t aGlyph;
+        aGlyph.index = aGlyphId & GF_IDXMASK;
+        aGlyph.x = aPos.X();
+        aGlyph.y = aPos.Y();
+        cairo_glyphs.push_back(aGlyph);
+
+        switch (aGlyphId & GF_ROTMASK)
+        {
+            case GF_ROTL:    // left
+                glyph_extrarotation.push_back(1);
+                break;
+            case GF_ROTR:    // right
+                glyph_extrarotation.push_back(-1);
+                break;
+            default:
+                glyph_extrarotation.push_back(0);
+                break;
+        }
+    }
+
+    if (cairo_glyphs.empty())
+        return;
+
+    cairo_surface_t *surface = getCairoSurface();
+
+    DBG_ASSERT( surface!=NULL, "no cairo surface for text" );
+    if( !surface )
+        return;
+
+    /*
+     * It might be ideal to cache surface and cairo context between calls and
+     * only destroy it when the drawable changes, but to do that we need to at
+     * least change the SalFrame etc impls to dtor the SalGraphics *before* the
+     * destruction of the windows they reference
+    */
+    cairo_t *cr = cairo_create(surface);
+    cairo_surface_destroy(surface);
+
+    if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions())
+        cairo_set_font_options(cr, static_cast<const cairo_font_options_t*>(pOptions));
+
+    clipRegion(cr);
+
+    cairo_set_source_rgb(cr,
+        SALCOLOR_RED(nTextColor_)/255.0,
+        SALCOLOR_GREEN(nTextColor_)/255.0,
+        SALCOLOR_BLUE(nTextColor_)/255.0);
+
+    ServerFont& rFont = rLayout.GetServerFont();
+
+    FT_Face aFace = rFont.GetFtFace();
+    CairoFontsCache::CacheId aId;
+    aId.maFace = aFace;
+    aId.mpOptions = rFont.GetFontOptions().get();
+    aId.mbEmbolden = rFont.NeedsArtificialBold();
+
+    cairo_matrix_t m;
+    const FontSelectPattern& rFSD = rFont.GetFontSelData();
+    int nHeight = rFSD.mnHeight;
+    int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight;
+
+    std::vector<int>::const_iterator aEnd = glyph_extrarotation.end();
+    std::vector<int>::const_iterator aStart = glyph_extrarotation.begin();
+    std::vector<int>::const_iterator aI = aStart;
+    while (aI != aEnd)
+    {
+        int nGlyphRotation = *aI;
+
+        std::vector<int>::const_iterator aNext = std::find_if(aI+1, aEnd, hasRotation);
+
+        size_t nStartIndex = std::distance(aStart, aI);
+        size_t nLen = std::distance(aI, aNext);
+
+        aId.mbVerticalMetrics = nGlyphRotation != 0.0;
+        cairo_font_face_t* font_face = (cairo_font_face_t*)CairoFontsCache::FindCachedFont(aId);
+        if (!font_face)
+        {
+            const ImplFontOptions *pOptions = rFont.GetFontOptions().get();
+            void *pPattern = pOptions ? pOptions->GetPattern(aFace, aId.mbEmbolden, aId.mbVerticalMetrics) : NULL;
+            if (pPattern)
+                font_face = cairo_ft_font_face_create_for_pattern(reinterpret_cast<FcPattern*>(pPattern));
+            if (!font_face)
+                font_face = cairo_ft_font_face_create_for_ft_face(reinterpret_cast<FT_Face>(aFace), rFont.GetLoadFlags());
+            CairoFontsCache::CacheFont(font_face, aId);
+        }
+        cairo_set_font_face(cr, font_face);
+
+        cairo_set_font_size(cr, nHeight);
+
+        cairo_matrix_init_identity(&m);
+
+        if (rLayout.GetOrientation())
+            cairo_matrix_rotate(&m, toRadian(rLayout.GetOrientation()));
+
+        cairo_matrix_scale(&m, nWidth, nHeight);
+
+        if (nGlyphRotation)
+        {
+            cairo_matrix_rotate(&m, toRadian(nGlyphRotation*900));
+
+            cairo_matrix_t em_square;
+            cairo_matrix_init_identity(&em_square);
+            cairo_get_matrix(cr, &em_square);
+
+            cairo_matrix_scale(&em_square, aFace->units_per_EM,
+                aFace->units_per_EM);
+            cairo_set_matrix(cr, &em_square);
+
+            cairo_font_extents_t font_extents;
+            cairo_font_extents(cr, &font_extents);
+
+            cairo_matrix_init_identity(&em_square);
+            cairo_set_matrix(cr, &em_square);
+
+            //gives the same positions as pre-cairo conversion, but I don't
+            //like them
+            double xdiff = 0.0;
+            double ydiff = 0.0;
+            if (nGlyphRotation == 1)
+            {
+                ydiff = font_extents.ascent/nHeight;
+                xdiff = -font_extents.descent/nHeight;
+            }
+            else if (nGlyphRotation == -1)
+            {
+                cairo_text_extents_t text_extents;
+                cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen,
+                    &text_extents);
+
+                xdiff = -text_extents.x_advance/nHeight;
+                //to restore an apparent bug in the original X11 impl, replace
+                //nHeight with nWidth below
+                xdiff += font_extents.descent/nHeight;
+            }
+            cairo_matrix_translate(&m, xdiff, ydiff);
+        }
+
+        if (rFont.NeedsArtificialItalic())
+        {
+            cairo_matrix_t shear;
+            cairo_matrix_init_identity(&shear);
+            shear.xy = -shear.xx * 0x6000L / 0x10000L;
+            cairo_matrix_multiply(&m, &shear, &m);
+        }
+
+        cairo_set_font_matrix(cr, &m);
+        cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
+
+#if OSL_DEBUG_LEVEL > 2
+        //draw origin
+        cairo_save (cr);
+        cairo_rectangle (cr, cairo_glyphs[nStartIndex].x, cairo_glyphs[nStartIndex].y, 5, 5);
+        cairo_set_source_rgba (cr, 1, 0, 0, 0.80);
+        cairo_fill (cr);
+        cairo_restore (cr);
+#endif
+
+        aI = aNext;
+    }
+
+    cairo_destroy(cr);
+}
+
+const FontCharMapPtr CairoTextRender::GetFontCharMap() const
+{
+    if( !mpServerFont[0] )
+        return NULL;
+
+    const FontCharMapPtr pFCMap = mpServerFont[0]->GetFontCharMap();
+    return pFCMap;
+}
+
+bool CairoTextRender::GetFontCapabilities(vcl::FontCapabilities &rGetImplFontCapabilities) const
+{
+    if (!mpServerFont[0])
+        return false;
+    return mpServerFont[0]->GetFontCapabilities(rGetImplFontCapabilities);
+}
+
+// SalGraphics
+
+sal_uInt16 CairoTextRender::SetFont( FontSelectPattern *pEntry, int nFallbackLevel )
+{
+    sal_uInt16 nRetVal = 0;
+    if( !setFont( pEntry, nFallbackLevel ) )
+        nRetVal |= SAL_SETFONT_BADFONT;
+    if( mbPrinter || (mpServerFont[ nFallbackLevel ] != NULL) )
+        nRetVal |= SAL_SETFONT_USEDRAWTEXTARRAY;
+    return nRetVal;
+}
+
+void
+CairoTextRender::SetTextColor( SalColor nSalColor )
+{
+    if( nTextColor_ != nSalColor )
+    {
+        nTextColor_ = nSalColor;
+    }
+}
+
+bool CairoTextRender::AddTempDevFont( PhysicalFontCollection* pFontCollection,
+                                     const OUString& rFileURL,
+                                     const OUString& rFontName )
+{
+    // inform PSP font manager
+    OUString aUSystemPath;
+    OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFileURL, aUSystemPath ) );
+    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
+    OString aOFileName( OUStringToOString( aUSystemPath, aEncoding ) );
+    psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+    std::vector<psp::fontID> aFontIds = rMgr.addFontFile( aOFileName );
+    if( aFontIds.empty() )
+        return false;
+
+    GlyphCache& rGC = getPlatformGlyphCache();
+
+    for (std::vector<psp::fontID>::iterator aI = aFontIds.begin(), aEnd = aFontIds.end(); aI != aEnd; ++aI)
+    {
+        // prepare font data
+        psp::FastPrintFontInfo aInfo;
+        rMgr.getFontFastInfo( *aI, aInfo );
+        aInfo.m_aFamilyName = rFontName;
+
+        // inform glyph cache of new font
+        ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
+        aDFA.mnQuality += 5800;
+
+        int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
+
+        const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
+        rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
+    }
+
+    // announce new font to device's font list
+    rGC.AnnounceFonts( pFontCollection );
+    return true;
+}
+
+void CairoTextRender::ClearDevFontCache()
+{
+    GlyphCache& rGC = getPlatformGlyphCache();
+    rGC.ClearFontCache();
+}
+
+void CairoTextRender::GetDevFontList( PhysicalFontCollection* pFontCollection )
+{
+    // prepare the GlyphCache using psprint's font infos
+    GlyphCache& rGC = getPlatformGlyphCache();
+
+    psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+    ::std::list< psp::fontID > aList;
+    ::std::list< psp::fontID >::iterator it;
+    psp::FastPrintFontInfo aInfo;
+    rMgr.getFontList( aList );
+    for( it = aList.begin(); it != aList.end(); ++it )
+    {
+        if( !rMgr.getFontFastInfo( *it, aInfo ) )
+            continue;
+
+        // normalize face number to the GlyphCache
+        int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
+
+        // inform GlyphCache about this font provided by the PsPrint subsystem
+        ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
+        aDFA.mnQuality += 4096;
+        const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
+        rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
+   }
+
+    // announce glyphcache fonts
+    rGC.AnnounceFonts( pFontCollection );
+
+    // register platform specific font substitutions if available
+    SalGenericInstance::RegisterFontSubstitutors( pFontCollection );
+
+    ImplGetSVData()->maGDIData.mbNativeFontConfig = true;
+}
+
+void cairosubcallback(void* pPattern)
+{
+    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+    const void* pFontOptions = rStyleSettings.GetCairoFontOptions();
+    if( !pFontOptions )
+        return;
+    cairo_ft_font_options_substitute(static_cast<const cairo_font_options_t*>(pFontOptions),
+        static_cast<FcPattern*>(pPattern));
+}
+
+ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize)
+{
+    psp::FastPrintFontInfo aInfo;
+
+    aInfo.m_aFamilyName = rFontAttributes.GetFamilyName();
+    aInfo.m_eItalic = rFontAttributes.GetSlant();
+    aInfo.m_eWeight = rFontAttributes.GetWeight();
+    aInfo.m_eWidth = rFontAttributes.GetWidthType();
+
+    const psp::PrintFontManager& rPFM = psp::PrintFontManager::get();
+    return rPFM.getFontOptions(aInfo, nSize, cairosubcallback);
+}
+
+void
+CairoTextRender::GetFontMetric( ImplFontMetricData *pMetric, int nFallbackLevel )
+{
+    if( nFallbackLevel >= MAX_FALLBACK )
+        return;
+
+    if( mpServerFont[nFallbackLevel] != NULL )
+    {
+        long rDummyFactor;
+        mpServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor );
+    }
+}
+
+bool CairoTextRender::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect )
+{
+    const int nLevel = aGlyphId >> GF_FONTSHIFT;
+    if( nLevel >= MAX_FALLBACK )
+        return false;
+
+    ServerFont* pSF = mpServerFont[ nLevel ];
+    if( !pSF )
+        return false;
+
+    aGlyphId &= GF_IDXMASK;
+    const GlyphMetric& rGM = pSF->GetGlyphMetric(aGlyphId);
+    Rectangle aRect( rGM.GetOffset(), rGM.GetSize() );
+
+    if ( pSF->mnCos != 0x10000 && pSF->mnSin != 0 )
+    {
+        double nCos = pSF->mnCos / 65536.0;
+        double nSin = pSF->mnSin / 65536.0;
+        rRect.Left() =  nCos*aRect.Left() + nSin*aRect.Top();
+        rRect.Top()  = -nSin*aRect.Left() - nCos*aRect.Top();
+
+        rRect.Right()  =  nCos*aRect.Right() + nSin*aRect.Bottom();
+        rRect.Bottom() = -nSin*aRect.Right() - nCos*aRect.Bottom();
+    }
+    else
+        rRect = aRect;
+
+    return true;
+}
+
+bool CairoTextRender::GetGlyphOutline( sal_GlyphId aGlyphId,
+    ::basegfx::B2DPolyPolygon& rPolyPoly )
+{
+    const int nLevel = aGlyphId >> GF_FONTSHIFT;
+    if( nLevel >= MAX_FALLBACK )
+        return false;
+
+    ServerFont* pSF = mpServerFont[ nLevel ];
+    if( !pSF )
+        return false;
+
+    aGlyphId &= GF_IDXMASK;
+    if( pSF->GetGlyphOutline( aGlyphId, rPolyPoly ) )
+        return true;
+
+    return false;
+}
+
+SalLayout* CairoTextRender::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
+{
+    SalLayout* pLayout = NULL;
+
+    if( mpServerFont[ nFallbackLevel ]
+    && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) )
+    {
+#if ENABLE_GRAPHITE
+        // Is this a Graphite font?
+        if (!bDisableGraphite_ &&
+            GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
+        {
+            pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
+        }
+        else
+#endif
+            pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
+    }
+
+    return pLayout;
+}
+
+SystemFontData CairoTextRender::GetSysFontData( int nFallbackLevel ) const
+{
+    SystemFontData aSysFontData;
+    aSysFontData.nSize = sizeof( SystemFontData );
+    aSysFontData.nFontId = 0;
+
+    if (nFallbackLevel >= MAX_FALLBACK) nFallbackLevel = MAX_FALLBACK - 1;
+    if (nFallbackLevel < 0 ) nFallbackLevel = 0;
+
+    if (mpServerFont[nFallbackLevel] != NULL)
+    {
+        ServerFont* rFont = mpServerFont[nFallbackLevel];
+        aSysFontData.nFontId = rFont->GetFtFace();
+        aSysFontData.nFontFlags = rFont->GetLoadFlags();
+        aSysFontData.bFakeBold = rFont->NeedsArtificialBold();
+        aSysFontData.bFakeItalic = rFont->NeedsArtificialItalic();
+        aSysFontData.bAntialias = rFont->GetAntialiasAdvice();
+        aSysFontData.bVerticalCharacterType = rFont->GetFontSelData().mbVertical;
+    }
+
+    return aSysFontData;
+}
+
+bool CairoTextRender::CreateFontSubset(
+                                   const OUString& rToFile,
+                                   const PhysicalFontFace* pFont,
+                                   sal_GlyphId* pGlyphIds,
+                                   sal_uInt8* pEncoding,
+                                   sal_Int32* pWidths,
+                                   int nGlyphCount,
+                                   FontSubsetInfo& rInfo
+                                   )
+{
+    // in this context the pFont->GetFontId() is a valid PSP
+    // font since they are the only ones left after the PDF
+    // export has filtered its list of subsettable fonts (for
+    // which this method was created). The correct way would
+    // be to have the GlyphCache search for the PhysicalFontFace pFont
+    psp::fontID aFont = pFont->GetFontId();
+
+    psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
+    bool bSuccess = rMgr.createFontSubset( rInfo,
+                                 aFont,
+                                 rToFile,
+                                 pGlyphIds,
+                                 pEncoding,
+                                 pWidths,
+                                 nGlyphCount );
+    return bSuccess;
+}
+
+const void* CairoTextRender::GetEmbedFontData( const PhysicalFontFace* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen )
+{
+    // in this context the pFont->GetFontId() is a valid PSP
+    // font since they are the only ones left after the PDF
+    // export has filtered its list of subsettable fonts (for
+    // which this method was created). The correct way would
+    // be to have the GlyphCache search for the PhysicalFontFace pFont
+    psp::fontID aFont = pFont->GetFontId();
+    return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen );
+}
+
+void CairoTextRender::FreeEmbedFontData( const void* pData, long nLen )
+{
+    GenPspGraphics::DoFreeEmbedFontData( pData, nLen );
+}
+
+const Ucs2SIntMap* CairoTextRender::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded )
+{
+    // in this context the pFont->GetFontId() is a valid PSP
+    // font since they are the only ones left after the PDF
+    // export has filtered its list of subsettable fonts (for
+    // which this method was created). The correct way would
+    // be to have the GlyphCache search for the PhysicalFontFace pFont
+    psp::fontID aFont = pFont->GetFontId();
+    return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
+}
+
+void CairoTextRender::GetGlyphWidths( const PhysicalFontFace* pFont,
+                                   bool bVertical,
+                                   Int32Vector& rWidths,
+                                   Ucs2UIntMap& rUnicodeEnc )
+{
+    // in this context the pFont->GetFontId() is a valid PSP
+    // font since they are the only ones left after the PDF
+    // export has filtered its list of subsettable fonts (for
+    // which this method was created). The correct way would
+    // be to have the GlyphCache search for the PhysicalFontFace pFont
+    psp::fontID aFont = pFont->GetFontId();
+    GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx
index 50014d5..d8eef57 100644
--- a/vcl/unx/generic/gdi/salgdi.cxx
+++ b/vcl/unx/generic/gdi/salgdi.cxx
@@ -52,6 +52,7 @@
 
 #include "salgdiimpl.hxx"
 #include "unx/x11windowprovider.hxx"
+#include "textrender.hxx"
 #include "gdiimpl.hxx"
 #include "openglgdiimpl.hxx"
 
@@ -74,7 +75,6 @@ X11SalGraphics::X11SalGraphics():
     pPaintRegion_(NULL),
     mpClipRegion(NULL),
     pFontGC_(NULL),
-    nTextColor_(MAKE_SALCOLOR(0x00, 0x00, 0x00)), //black
     nTextPixel_(0),
     hBrush_(None),
     bWindow_(false),
@@ -87,15 +87,6 @@ X11SalGraphics::X11SalGraphics():
         mpImpl.reset(new OpenGLSalGraphicsImpl());
     else
         mpImpl.reset(new X11SalGraphicsImpl(*this));
-
-    for( int i = 0; i < MAX_FALLBACK; ++i )
-        mpServerFont[i] = NULL;
-
-#if ENABLE_GRAPHITE
-    // check if graphite fonts have been disabled
-    static const char* pDisableGraphiteStr = getenv( "SAL_DISABLE_GRAPHITE" );
-    bDisableGraphite_   = pDisableGraphiteStr && (pDisableGraphiteStr[0]!='0');
-#endif
 }
 
 X11SalGraphics::~X11SalGraphics()
@@ -157,7 +148,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
         }
 
         mpImpl->Init( m_pFrame );
-        nTextPixel_     = GetPixel( nTextColor_ );
+        // TODO: moggi: FIXME nTextPixel_     = GetPixel( nTextColor_ );
     }
 }
 
diff --git a/vcl/unx/generic/gdi/salgdi3.cxx b/vcl/unx/generic/gdi/salgdi3.cxx
index 3cd42cd..3f47712 100644
--- a/vcl/unx/generic/gdi/salgdi3.cxx
+++ b/vcl/unx/generic/gdi/salgdi3.cxx
@@ -36,7 +36,6 @@
 #include <osl/module.hxx>
 #include <rtl/tencinfo.h>
 #include <sal/alloca.h>
-#include <tools/debug.hxx>
 #include <tools/stream.hxx>
 #include <vcl/settings.hxx>
 #include <vcl/sysdata.hxx>
@@ -59,31 +58,9 @@
 #include "unx/salgdi.h"
 #include "unx/salunx.h"
 #include "unx/salvd.h"
+#include "textrender.hxx"
 #include "xrender_peer.hxx"
 
-#include <config_graphite.h>
-#if ENABLE_GRAPHITE
-#include <graphite_layout.hxx>
-#include <graphite_serverfont.hxx>
-#endif
-
-#include <cairo.h>
-#include <cairo-ft.h>
-#include <cairo-xlib.h>
-#include <cairo-xlib-xrender.h>
-
-struct BOX
-{
-    short x1, x2, y1, y2;
-};
-struct _XRegion
-{
-    long size;
-    long numRects;
-    BOX *rects;
-    BOX extents;
-};
-
 // X11SalGraphics
 
 GC
@@ -113,569 +90,80 @@ X11SalGraphics::GetFontGC()
     return pFontGC_;
 }
 
-bool X11SalGraphics::setFont( const FontSelectPattern *pEntry, int nFallbackLevel )
-{
-    // release all no longer needed font resources
-    for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i )
-    {
-        if( mpServerFont[i] != NULL )
-        {
-            // old server side font is no longer referenced
-            GlyphCache::GetInstance().UncacheFont( *mpServerFont[i] );
-            mpServerFont[i] = NULL;
-        }
-    }
-
-    // return early if there is no new font
-    if( !pEntry )
-        return false;
-
-    // return early if this is not a valid font for this graphics
-    if( !pEntry->mpFontData )
-        return false;
-
-    // handle the request for a non-native X11-font => use the GlyphCache
-    ServerFont* pServerFont = GlyphCache::GetInstance().CacheFont( *pEntry );
-    if( pServerFont != NULL )
-    {
-        // ignore fonts with e.g. corrupted font files
-        if( !pServerFont->TestFont() )
-        {
-            GlyphCache::GetInstance().UncacheFont( *pServerFont );
-            return false;
-        }
-
-        // register to use the font
-        mpServerFont[ nFallbackLevel ] = pServerFont;
-
-        // apply font specific-hint settings if needed
-        // TODO: also disable it for reference devices
-        if( !bPrinter_ )
-        {
-            ImplServerFontEntry* pSFE = static_cast<ImplServerFontEntry*>( pEntry->mpFontEntry );
-            pSFE->HandleFontOptions();
-        }
-
-        return true;
-    }
-
-    return false;
-}
-
 ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize);
 
-void ImplServerFontEntry::HandleFontOptions( void )
-{
-    if( !mpServerFont )
-        return;
-    if( !mbGotFontOptions )
-    {
-        // get and cache the font options
-        mbGotFontOptions = true;
-        mpFontOptions.reset(GetFCFontOptions( *maFontSelData.mpFontData,
-            maFontSelData.mnHeight ));
-    }
-    // apply the font options
-    mpServerFont->SetFontOptions( mpFontOptions );
-}
-
-CairoFontsCache::LRUFonts CairoFontsCache::maLRUFonts;
-int CairoFontsCache::mnRefCount = 0;
-
-CairoFontsCache::CairoFontsCache()
-{
-    ++mnRefCount;
-}
-
-CairoFontsCache::~CairoFontsCache()
-{
-    --mnRefCount;
-    if (!mnRefCount && !maLRUFonts.empty())
-    {
-        LRUFonts::iterator aEnd = maLRUFonts.end();
-        for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
-            cairo_font_face_destroy((cairo_font_face_t*)aI->first);
-    }
-}
-
-void CairoFontsCache::CacheFont(void *pFont, const CairoFontsCache::CacheId &rId)
-{
-    maLRUFonts.push_front( std::pair<void*, CairoFontsCache::CacheId>(pFont, rId) );
-    if (maLRUFonts.size() > 8)
-    {
-        cairo_font_face_destroy((cairo_font_face_t*)maLRUFonts.back().first);
-        maLRUFonts.pop_back();
-    }
-}
-
-void* CairoFontsCache::FindCachedFont(const CairoFontsCache::CacheId &rId)
-{
-    LRUFonts::iterator aEnd = maLRUFonts.end();
-    for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
-        if (aI->second == rId)
-            return aI->first;
-    return NULL;
-}
-
-namespace
-{
-    bool hasRotation(int nRotation)
-    {
-      return nRotation != 0;
-    }
-
-    double toRadian(int nDegree10th)
-    {
-        return (3600 - (nDegree10th)) * M_PI / 1800.0;
-    }
-}
-
 void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
 {
-    std::vector<cairo_glyph_t> cairo_glyphs;
-    std::vector<int> glyph_extrarotation;
-    cairo_glyphs.reserve( 256 );
-
-    Point aPos;
-    sal_GlyphId aGlyphId;
-    for( int nStart = 0; rLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); )
-    {
-        cairo_glyph_t aGlyph;
-        aGlyph.index = aGlyphId & GF_IDXMASK;
-        aGlyph.x = aPos.X();
-        aGlyph.y = aPos.Y();
-        cairo_glyphs.push_back(aGlyph);
-
-        switch (aGlyphId & GF_ROTMASK)
-        {
-            case GF_ROTL:    // left
-                glyph_extrarotation.push_back(1);
-                break;
-            case GF_ROTR:    // right
-                glyph_extrarotation.push_back(-1);
-                break;
-            default:
-                glyph_extrarotation.push_back(0);
-                break;
-        }
-    }
-
-    if (cairo_glyphs.empty())
-        return;
-
-    // find a XRenderPictFormat compatible with the Drawable
-    XRenderPictFormat* pVisualFormat = GetXRenderFormat();
-
-    Display* pDisplay = GetXDisplay();
-
-    cairo_surface_t *surface;
-
-    if (pVisualFormat)
-    {
-        surface = cairo_xlib_surface_create_with_xrender_format (
-                        pDisplay, hDrawable_,
-                        ScreenOfDisplay(pDisplay, m_nXScreen.getXScreen()),
-                        pVisualFormat, SAL_MAX_INT16, SAL_MAX_INT16);
-    }
-    else
-    {
-        surface = cairo_xlib_surface_create(pDisplay, hDrawable_,
-            GetVisual().visual, SAL_MAX_INT16, SAL_MAX_INT16);
-    }
-
-    DBG_ASSERT( surface!=NULL, "no cairo surface for text" );
-    if( !surface )
-        return;
-
-    /*
-     * It might be ideal to cache surface and cairo context between calls and
-     * only destroy it when the drawable changes, but to do that we need to at
-     * least change the SalFrame etc impls to dtor the SalGraphics *before* the
-     * destruction of the windows they reference
-    */
-    cairo_t *cr = cairo_create(surface);
-    cairo_surface_destroy(surface);
-
-    if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions())
-        cairo_set_font_options(cr, static_cast<const cairo_font_options_t*>(pOptions));
-
-    if( mpClipRegion && !XEmptyRegion( mpClipRegion ) )
-    {
-        for (long i = 0; i < mpClipRegion->numRects; ++i)
-        {
-            cairo_rectangle(cr,
-                mpClipRegion->rects[i].x1,
-                mpClipRegion->rects[i].y1,
-                mpClipRegion->rects[i].x2 - mpClipRegion->rects[i].x1,
-                mpClipRegion->rects[i].y2 - mpClipRegion->rects[i].y1);
-        }
-        cairo_clip(cr);
-    }
-
-    cairo_set_source_rgb(cr,
-        SALCOLOR_RED(nTextColor_)/255.0,
-        SALCOLOR_GREEN(nTextColor_)/255.0,
-        SALCOLOR_BLUE(nTextColor_)/255.0);
-
-    ServerFont& rFont = rLayout.GetServerFont();
-
-    FT_Face aFace = rFont.GetFtFace();
-    CairoFontsCache::CacheId aId;
-    aId.maFace = aFace;
-    aId.mpOptions = rFont.GetFontOptions().get();
-    aId.mbEmbolden = rFont.NeedsArtificialBold();
-
-    cairo_matrix_t m;
-    const FontSelectPattern& rFSD = rFont.GetFontSelData();
-    int nHeight = rFSD.mnHeight;
-    int nWidth = rFSD.mnWidth ? rFSD.mnWidth : nHeight;
-
-    std::vector<int>::const_iterator aEnd = glyph_extrarotation.end();
-    std::vector<int>::const_iterator aStart = glyph_extrarotation.begin();
-    std::vector<int>::const_iterator aI = aStart;
-    while (aI != aEnd)
-    {
-        int nGlyphRotation = *aI;
-
-        std::vector<int>::const_iterator aNext = std::find_if(aI+1, aEnd, hasRotation);
-
-        size_t nStartIndex = std::distance(aStart, aI);
-        size_t nLen = std::distance(aI, aNext);
-
-        aId.mbVerticalMetrics = nGlyphRotation != 0.0;
-        cairo_font_face_t* font_face = (cairo_font_face_t*)CairoFontsCache::FindCachedFont(aId);
-        if (!font_face)
-        {
-            const ImplFontOptions *pOptions = rFont.GetFontOptions().get();
-            void *pPattern = pOptions ? pOptions->GetPattern(aFace, aId.mbEmbolden, aId.mbVerticalMetrics) : NULL;
-            if (pPattern)
-                font_face = cairo_ft_font_face_create_for_pattern(reinterpret_cast<FcPattern*>(pPattern));
-            if (!font_face)
-                font_face = cairo_ft_font_face_create_for_ft_face(reinterpret_cast<FT_Face>(aFace), rFont.GetLoadFlags());
-            CairoFontsCache::CacheFont(font_face, aId);
-        }
-        cairo_set_font_face(cr, font_face);
-
-        cairo_set_font_size(cr, nHeight);
-
-        cairo_matrix_init_identity(&m);
-
-        if (rLayout.GetOrientation())
-            cairo_matrix_rotate(&m, toRadian(rLayout.GetOrientation()));
-
-        cairo_matrix_scale(&m, nWidth, nHeight);
-
-        if (nGlyphRotation)
-        {
-            cairo_matrix_rotate(&m, toRadian(nGlyphRotation*900));
-
-            cairo_matrix_t em_square;
-            cairo_matrix_init_identity(&em_square);
-            cairo_get_matrix(cr, &em_square);
-
-            cairo_matrix_scale(&em_square, aFace->units_per_EM,
-                aFace->units_per_EM);
-            cairo_set_matrix(cr, &em_square);
-
-            cairo_font_extents_t font_extents;
-            cairo_font_extents(cr, &font_extents);
-
-            cairo_matrix_init_identity(&em_square);
-            cairo_set_matrix(cr, &em_square);
-
-            //gives the same positions as pre-cairo conversion, but I don't
-            //like them
-            double xdiff = 0.0;
-            double ydiff = 0.0;
-            if (nGlyphRotation == 1)
-            {
-                ydiff = font_extents.ascent/nHeight;
-                xdiff = -font_extents.descent/nHeight;
-            }
-            else if (nGlyphRotation == -1)
-            {
-                cairo_text_extents_t text_extents;
-                cairo_glyph_extents(cr, &cairo_glyphs[nStartIndex], nLen,
-                    &text_extents);
-
-                xdiff = -text_extents.x_advance/nHeight;
-                //to restore an apparent bug in the original X11 impl, replace
-                //nHeight with nWidth below
-                xdiff += font_extents.descent/nHeight;
-            }
-            cairo_matrix_translate(&m, xdiff, ydiff);
-        }
-
-        if (rFont.NeedsArtificialItalic())
-        {
-            cairo_matrix_t shear;
-            cairo_matrix_init_identity(&shear);
-            shear.xy = -shear.xx * 0x6000L / 0x10000L;
-            cairo_matrix_multiply(&m, &shear, &m);
-        }
-
-        cairo_set_font_matrix(cr, &m);
-        cairo_show_glyphs(cr, &cairo_glyphs[nStartIndex], nLen);
-
-#if OSL_DEBUG_LEVEL > 2
-        //draw origin
-        cairo_save (cr);
-        cairo_rectangle (cr, cairo_glyphs[nStartIndex].x, cairo_glyphs[nStartIndex].y, 5, 5);
-        cairo_set_source_rgba (cr, 1, 0, 0, 0.80);
-        cairo_fill (cr);
-        cairo_restore (cr);
-#endif
-
-        aI = aNext;
-    }
-
-    cairo_destroy(cr);
+    mpTextRenderImpl->DrawServerFontLayout(rLayout);
 }
 
 const FontCharMapPtr X11SalGraphics::GetFontCharMap() const
 {
-    if( !mpServerFont[0] )
-        return NULL;
-
-    const FontCharMapPtr pFCMap = mpServerFont[0]->GetFontCharMap();
-    return pFCMap;
+    return mpTextRenderImpl->GetFontCharMap();
 }
 
 bool X11SalGraphics::GetFontCapabilities(vcl::FontCapabilities &rGetImplFontCapabilities) const
 {
-    if (!mpServerFont[0])
-        return false;
-    return mpServerFont[0]->GetFontCapabilities(rGetImplFontCapabilities);
+    return mpTextRenderImpl->GetFontCapabilities(rGetImplFontCapabilities);
 }
 
 // SalGraphics
 
 sal_uInt16 X11SalGraphics::SetFont( FontSelectPattern *pEntry, int nFallbackLevel )
 {
-    sal_uInt16 nRetVal = 0;
-    if( !setFont( pEntry, nFallbackLevel ) )
-        nRetVal |= SAL_SETFONT_BADFONT;
-    if( bPrinter_ || (mpServerFont[ nFallbackLevel ] != NULL) )
-        nRetVal |= SAL_SETFONT_USEDRAWTEXTARRAY;
-    return nRetVal;
+    return mpTextRenderImpl->SetFont(pEntry, nFallbackLevel);
 }
 
 void
 X11SalGraphics::SetTextColor( SalColor nSalColor )
 {
-    if( nTextColor_ != nSalColor )
-    {
-        nTextColor_     = nSalColor;
-        nTextPixel_     = GetPixel( nSalColor );
-        bFontGC_        = false;
-    }
+    mpTextRenderImpl->SetTextColor(nSalColor);
+    nTextPixel_     = GetPixel( nSalColor );
+    bFontGC_        = false;
 }
 
 bool X11SalGraphics::AddTempDevFont( PhysicalFontCollection* pFontCollection,
                                      const OUString& rFileURL,
                                      const OUString& rFontName )
 {
-    // inform PSP font manager
-    OUString aUSystemPath;
-    OSL_VERIFY( !osl::FileBase::getSystemPathFromFileURL( rFileURL, aUSystemPath ) );
-    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
-    OString aOFileName( OUStringToOString( aUSystemPath, aEncoding ) );
-    psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
-    std::vector<psp::fontID> aFontIds = rMgr.addFontFile( aOFileName );
-    if( aFontIds.empty() )
-        return false;
-
-    GlyphCache& rGC = X11GlyphCache::GetInstance();
-
-    for (std::vector<psp::fontID>::iterator aI = aFontIds.begin(), aEnd = aFontIds.end(); aI != aEnd; ++aI)
-    {
-        // prepare font data
-        psp::FastPrintFontInfo aInfo;
-        rMgr.getFontFastInfo( *aI, aInfo );
-        aInfo.m_aFamilyName = rFontName;
-
-        // inform glyph cache of new font
-        ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
-        aDFA.mnQuality += 5800;
-
-        int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
-
-        const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
-        rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
-    }
-
-    // announce new font to device's font list
-    rGC.AnnounceFonts( pFontCollection );
-    return true;
+    return mpTextRenderImpl->AddTempDevFont(pFontCollection, rFileURL, rFontName);
 }
 
 void X11SalGraphics::ClearDevFontCache()
 {
-    X11GlyphCache& rGC = X11GlyphCache::GetInstance();
-    rGC.ClearFontCache();
+    mpTextRenderImpl->ClearDevFontCache();
 }
 
 void X11SalGraphics::GetDevFontList( PhysicalFontCollection* pFontCollection )
 {
-    // prepare the GlyphCache using psprint's font infos
-    X11GlyphCache& rGC = X11GlyphCache::GetInstance();
-
-    psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
-    ::std::list< psp::fontID > aList;
-    ::std::list< psp::fontID >::iterator it;
-    psp::FastPrintFontInfo aInfo;
-    rMgr.getFontList( aList );
-    for( it = aList.begin(); it != aList.end(); ++it )
-    {
-        if( !rMgr.getFontFastInfo( *it, aInfo ) )
-            continue;
-
-        // normalize face number to the GlyphCache
-        int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID );
-
-        // inform GlyphCache about this font provided by the PsPrint subsystem
-        ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo );
-        aDFA.mnQuality += 4096;
-        const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID );
-        rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA );
-   }
-
-    // announce glyphcache fonts
-    rGC.AnnounceFonts( pFontCollection );
-
-    // register platform specific font substitutions if available
-    SalGenericInstance::RegisterFontSubstitutors( pFontCollection );
-
-    ImplGetSVData()->maGDIData.mbNativeFontConfig = true;
-}
-
-void cairosubcallback(void* pPattern)
-{
-    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
-    const void* pFontOptions = rStyleSettings.GetCairoFontOptions();
-    if( !pFontOptions )
-        return;
-    cairo_ft_font_options_substitute(static_cast<const cairo_font_options_t*>(pFontOptions),
-        static_cast<FcPattern*>(pPattern));
-}
-
-ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize)
-{
-    psp::FastPrintFontInfo aInfo;
-
-    aInfo.m_aFamilyName = rFontAttributes.GetFamilyName();
-    aInfo.m_eItalic = rFontAttributes.GetSlant();
-    aInfo.m_eWeight = rFontAttributes.GetWeight();
-    aInfo.m_eWidth = rFontAttributes.GetWidthType();
-
-    const psp::PrintFontManager& rPFM = psp::PrintFontManager::get();
-    return rPFM.getFontOptions(aInfo, nSize, cairosubcallback);
+    mpTextRenderImpl->GetDevFontList(pFontCollection);
 }
 
 void
 X11SalGraphics::GetFontMetric( ImplFontMetricData *pMetric, int nFallbackLevel )
 {
-    if( nFallbackLevel >= MAX_FALLBACK )
-        return;
-
-    if( mpServerFont[nFallbackLevel] != NULL )
-    {
-        long rDummyFactor;
-        mpServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor );
-    }
+    mpTextRenderImpl->GetFontMetric(pMetric, nFallbackLevel);
 }
 
 bool X11SalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect )
 {
-    const int nLevel = aGlyphId >> GF_FONTSHIFT;
-    if( nLevel >= MAX_FALLBACK )
-        return false;
-
-    ServerFont* pSF = mpServerFont[ nLevel ];
-    if( !pSF )
-        return false;
-
-    aGlyphId &= GF_IDXMASK;
-    const GlyphMetric& rGM = pSF->GetGlyphMetric(aGlyphId);
-    Rectangle aRect( rGM.GetOffset(), rGM.GetSize() );
-
-    if ( pSF->mnCos != 0x10000 && pSF->mnSin != 0 )
-    {
-        double nCos = pSF->mnCos / 65536.0;
-        double nSin = pSF->mnSin / 65536.0;
-        rRect.Left() =  nCos*aRect.Left() + nSin*aRect.Top();
-        rRect.Top()  = -nSin*aRect.Left() - nCos*aRect.Top();
-
-        rRect.Right()  =  nCos*aRect.Right() + nSin*aRect.Bottom();
-        rRect.Bottom() = -nSin*aRect.Right() - nCos*aRect.Bottom();
-    }
-    else
-        rRect = aRect;
-
-    return true;
+    return mpTextRenderImpl->GetGlyphBoundRect(aGlyphId, rRect);
 }
 
 bool X11SalGraphics::GetGlyphOutline( sal_GlyphId aGlyphId,
     ::basegfx::B2DPolyPolygon& rPolyPoly )
 {
-    const int nLevel = aGlyphId >> GF_FONTSHIFT;
-    if( nLevel >= MAX_FALLBACK )
-        return false;
-
-    ServerFont* pSF = mpServerFont[ nLevel ];
-    if( !pSF )
-        return false;
-
-    aGlyphId &= GF_IDXMASK;
-    if( pSF->GetGlyphOutline( aGlyphId, rPolyPoly ) )
-        return true;
-
-    return false;
+    return mpTextRenderImpl->GetGlyphOutline(aGlyphId, rPolyPoly);
 }
 
 SalLayout* X11SalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel )
 {
-    SalLayout* pLayout = NULL;
-
-    if( mpServerFont[ nFallbackLevel ]
-    && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) )
-    {
-#if ENABLE_GRAPHITE
-        // Is this a Graphite font?
-        if (!bDisableGraphite_ &&
-            GraphiteServerFontLayout::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel]))
-        {
-            pLayout = new GraphiteServerFontLayout(*mpServerFont[nFallbackLevel]);
-        }
-        else
-#endif
-            pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] );
-    }
-
-    return pLayout;
+    return mpTextRenderImpl->GetTextLayout(rArgs, nFallbackLevel);
 }
 
-SystemFontData X11SalGraphics::GetSysFontData( int nFallbacklevel ) const
+SystemFontData X11SalGraphics::GetSysFontData( int nFallbackLevel ) const
 {
-    SystemFontData aSysFontData;
-    aSysFontData.nSize = sizeof( SystemFontData );
-    aSysFontData.nFontId = 0;
-
-    if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1;
-    if (nFallbacklevel < 0 ) nFallbacklevel = 0;
-
-    if (mpServerFont[nFallbacklevel] != NULL)
-    {
-        ServerFont* rFont = mpServerFont[nFallbacklevel];
-        aSysFontData.nFontId = rFont->GetFtFace();
-        aSysFontData.nFontFlags = rFont->GetLoadFlags();
-        aSysFontData.bFakeBold = rFont->NeedsArtificialBold();
-        aSysFontData.bFakeItalic = rFont->NeedsArtificialItalic();
-        aSysFontData.bAntialias = rFont->GetAntialiasAdvice();
-        aSysFontData.bVerticalCharacterType = rFont->GetFontSelData().mbVertical;
-    }
-
-    return aSysFontData;
+    return mpTextRenderImpl->GetSysFontData(nFallbackLevel);
 }
 
 bool X11SalGraphics::CreateFontSubset(
@@ -688,49 +176,23 @@ bool X11SalGraphics::CreateFontSubset(
                                    FontSubsetInfo& rInfo
                                    )
 {
-    // in this context the pFont->GetFontId() is a valid PSP
-    // font since they are the only ones left after the PDF
-    // export has filtered its list of subsettable fonts (for
-    // which this method was created). The correct way would
-    // be to have the GlyphCache search for the PhysicalFontFace pFont
-    psp::fontID aFont = pFont->GetFontId();
-
-    psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
-    bool bSuccess = rMgr.createFontSubset( rInfo,
-                                 aFont,
-                                 rToFile,
-                                 pGlyphIds,
-                                 pEncoding,
-                                 pWidths,
-                                 nGlyphCount );
-    return bSuccess;
+    return mpTextRenderImpl->CreateFontSubset(rToFile, pFont,
+            pGlyphIds, pEncoding, pWidths, nGlyphCount, rInfo);
 }
 
 const void* X11SalGraphics::GetEmbedFontData( const PhysicalFontFace* pFont, const sal_Ucs* pUnicodes, sal_Int32* pWidths, FontSubsetInfo& rInfo, long* pDataLen )
 {
-    // in this context the pFont->GetFontId() is a valid PSP
-    // font since they are the only ones left after the PDF
-    // export has filtered its list of subsettable fonts (for
-    // which this method was created). The correct way would
-    // be to have the GlyphCache search for the PhysicalFontFace pFont
-    psp::fontID aFont = pFont->GetFontId();
-    return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, rInfo, pDataLen );
+    return mpTextRenderImpl->GetEmbedFontData(pFont, pUnicodes, pWidths, rInfo, pDataLen);
 }
 
 void X11SalGraphics::FreeEmbedFontData( const void* pData, long nLen )
 {
-    GenPspGraphics::DoFreeEmbedFontData( pData, nLen );
+    mpTextRenderImpl->FreeEmbedFontData(pData, nLen);
 }
 
 const Ucs2SIntMap* X11SalGraphics::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded )
 {
-    // in this context the pFont->GetFontId() is a valid PSP
-    // font since they are the only ones left after the PDF
-    // export has filtered its list of subsettable fonts (for
-    // which this method was created). The correct way would
-    // be to have the GlyphCache search for the PhysicalFontFace pFont
-    psp::fontID aFont = pFont->GetFontId();
-    return GenPspGraphics::DoGetFontEncodingVector( aFont, pNonEncoded );
+    return mpTextRenderImpl->GetFontEncodingVector(pFont, pNonEncoded);
 }
 
 void X11SalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
@@ -738,13 +200,7 @@ void X11SalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont,
                                    Int32Vector& rWidths,
                                    Ucs2UIntMap& rUnicodeEnc )
 {
-    // in this context the pFont->GetFontId() is a valid PSP
-    // font since they are the only ones left after the PDF
-    // export has filtered its list of subsettable fonts (for
-    // which this method was created). The correct way would
-    // be to have the GlyphCache search for the PhysicalFontFace pFont
-    psp::fontID aFont = pFont->GetFontId();
-    GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc );
+    mpTextRenderImpl->GetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/x11cairotextrender.cxx b/vcl/unx/generic/gdi/x11cairotextrender.cxx
new file mode 100644
index 0000000..3a21c39
--- /dev/null
+++ b/vcl/unx/generic/gdi/x11cairotextrender.cxx
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "x11cairotextrender.hxx"
+#include "unx/saldata.hxx"
+#include "unx/saldisp.hxx"
+
+#include "gcach_xpeer.hxx"
+
+#include <cairo.h>
+#include <cairo-ft.h>
+
+#include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
+
+struct BOX
+{
+    short x1, x2, y1, y2;
+};
+struct _XRegion
+{
+    long size;
+    long numRects;
+    BOX *rects;
+    BOX extents;
+};
+
+X11CairoTextRender::X11CairoTextRender(bool bPrinter, X11SalGraphics& rParent):
+    CairoTextRender(bPrinter),
+    mrParent(rParent)
+{
+}
+
+GlyphCache& X11CairoTextRender::getPlatformGlyphCache()
+{
+    return X11GlyphCache::GetInstance();
+}
+
+cairo_surface_t* X11CairoTextRender::getCairoSurface()
+{
+    // find a XRenderPictFormat compatible with the Drawable
+    XRenderPictFormat* pVisualFormat = mrParent.GetXRenderFormat();
+
+    Display* pDisplay = mrParent.GetXDisplay();
+
+    cairo_surface_t* surface = NULL;
+    if (pVisualFormat)
+    {
+        surface = cairo_xlib_surface_create_with_xrender_format (
+                        pDisplay, mrParent.hDrawable_,
+                        ScreenOfDisplay(pDisplay, mrParent.m_nXScreen.getXScreen()),
+                        pVisualFormat, SAL_MAX_INT16, SAL_MAX_INT16);
+    }
+    else
+    {
+        surface = cairo_xlib_surface_create(pDisplay, mrParent.hDrawable_,
+            mrParent.GetVisual().visual, SAL_MAX_INT16, SAL_MAX_INT16);
+    }
+
+    return surface;
+}
+
+void X11CairoTextRender::clipRegion(cairo_t* cr)
+{
+    Region pClipRegion = mrParent.mpClipRegion;
+    if( pClipRegion && !XEmptyRegion( pClipRegion ) )
+    {
+        for (long i = 0; i < pClipRegion->numRects; ++i)
+        {
+            cairo_rectangle(cr,
+                pClipRegion->rects[i].x1,
+                pClipRegion->rects[i].y1,
+                pClipRegion->rects[i].x2 - pClipRegion->rects[i].x1,
+                pClipRegion->rects[i].y2 - pClipRegion->rects[i].y1);
+        }
+        cairo_clip(cr);
+    }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/gdi/x11cairotextrender.hxx b/vcl/unx/generic/gdi/x11cairotextrender.hxx
new file mode 100644
index 0000000..eb44102
--- /dev/null
+++ b/vcl/unx/generic/gdi/x11cairotextrender.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "unx/cairotextrender.hxx"
+
+#include "unx/saldata.hxx"
+#include "unx/saldisp.hxx"
+
+#include "unx/salgdi.h"
+
+class X11CairoTextRender : public CairoTextRender
+{
+private:
+    X11SalGraphics& mrParent;
+public:
+    X11CairoTextRender(bool bPrinter, X11SalGraphics& rParent);
+
+    virtual GlyphCache& getPlatformGlyphCache() SAL_OVERRIDE;
+    virtual cairo_surface_t* getCairoSurface() SAL_OVERRIDE;
+    virtual void clipRegion(cairo_t* cr) SAL_OVERRIDE;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list