summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/Library_vclplug_gen.mk2
-rw-r--r--vcl/inc/generic/glyphcache.hxx1
-rw-r--r--vcl/inc/graphite_serverfont.hxx2
-rw-r--r--vcl/inc/textrender.hxx81
-rw-r--r--vcl/inc/unx/cairotextrender.hxx128
-rw-r--r--vcl/inc/unx/salgdi.h44
-rw-r--r--vcl/unx/generic/gdi/cairotextrender.cxx659
-rw-r--r--vcl/unx/generic/gdi/salgdi.cxx13
-rw-r--r--vcl/unx/generic/gdi/salgdi3.cxx590
-rw-r--r--vcl/unx/generic/gdi/x11cairotextrender.cxx96
-rw-r--r--vcl/unx/generic/gdi/x11cairotextrender.hxx39
11 files changed, 1038 insertions, 617 deletions
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index d25eec6248c2..fe9f4f6ddb16 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 ba44ae8412b3..ddfc7a8ef965 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 0d533e00b7c2..7dfde21551bc 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 000000000000..b18b6300724b
--- /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 000000000000..7bc0b2f7a36e
--- /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 1e90e985d421..f79f6d97e054 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;
/* use to handle GraphicsExpose/NoExpose after XCopyArea & friends
* if pFrame is not NULL, corresponding Paint events are generated
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
new file mode 100644
index 000000000000..e4bee505e316
--- /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 c5dd0bedd54a..02598c3a0a63 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()
@@ -164,7 +155,7 @@ void X11SalGraphics::SetDrawable( Drawable aDrawable, SalX11Screen nXScreen )
aWin, m_nXScreen.getXScreen());
}
}
- 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 3cd42cdd09a9..3f47712e68ba 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 000000000000..3a21c390a357
--- /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 000000000000..eb4410250944
--- /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: */