summaryrefslogtreecommitdiffstats
path: root/vcl/unx/generic/gdi/salgdi3.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/unx/generic/gdi/salgdi3.cxx')
-rw-r--r--vcl/unx/generic/gdi/salgdi3.cxx325
1 files changed, 102 insertions, 223 deletions
diff --git a/vcl/unx/generic/gdi/salgdi3.cxx b/vcl/unx/generic/gdi/salgdi3.cxx
index dce2e5ccb793..4934ed7f83fa 100644
--- a/vcl/unx/generic/gdi/salgdi3.cxx
+++ b/vcl/unx/generic/gdi/salgdi3.cxx
@@ -78,28 +78,21 @@
#include "salframe.hxx"
#include "outdev.h"
-
-
#ifdef ENABLE_GRAPHITE
#include <graphite_layout.hxx>
#include <graphite_serverfont.hxx>
#endif
-struct cairo_surface_t;
-struct cairo_t;
-struct cairo_font_face_t;
-typedef void* FT_Face;
-struct cairo_matrix_t {
- double xx; double yx;
- double xy; double yy;
- double x0; double y0;
-};
-struct cairo_glyph_t
-{
- unsigned long index;
- double x;
- double y;
-};
+#ifdef SYSTEM_CAIRO
+#include <cairo.h>
+#include <cairo-ft.h>
+#include <cairo-xlib-xrender.h>
+#else
+#include <cairo/cairo.h>
+#include <cairo/cairo-ft.h>
+#include <cairo/cairo-xlib-xrender.h>
+#endif
+
struct BOX
{
short x1, x2, y1, y2;
@@ -249,179 +242,12 @@ void ImplServerFontEntry::HandleFontOptions( void )
//--------------------------------------------------------------------------
-namespace {
-
-class CairoWrapper
-{
-private:
- osl::Module mpCairoLib;
-
- cairo_surface_t* (*mp_xlib_surface_create_with_xrender_format)(Display *, Drawable , Screen *, XRenderPictFormat *, int , int );
- void (*mp_surface_destroy)(cairo_surface_t *);
- cairo_t* (*mp_create)(cairo_surface_t *);
- void (*mp_destroy)(cairo_t*);
- void (*mp_clip)(cairo_t*);
- void (*mp_rectangle)(cairo_t*, double, double, double, double);
- cairo_font_face_t * (*mp_ft_font_face_create_for_ft_face)(FT_Face, int);
- cairo_font_face_t * (*mp_ft_font_face_create_for_pattern)(void*);
- void (*mp_set_font_face)(cairo_t *, cairo_font_face_t *);
- void (*mp_font_face_destroy)(cairo_font_face_t *);
- void (*mp_matrix_init_identity)(cairo_matrix_t *);
- void (*mp_matrix_scale)(cairo_matrix_t *, double, double);
- void (*mp_matrix_rotate)(cairo_matrix_t *, double);
- void (*mp_set_font_matrix)(cairo_t *, const cairo_matrix_t *);
- void (*mp_show_glyphs)(cairo_t *, const cairo_glyph_t *, int );
- void (*mp_set_source_rgb)(cairo_t *, double , double , double );
- void (*mp_set_font_options)(cairo_t *, const void *);
- void (*mp_ft_font_options_substitute)(const void*, void*);
-
- bool canEmbolden() const { return mp_ft_font_face_create_for_pattern != NULL; }
-
- CairoWrapper();
-public:
- static CairoWrapper& get();
- bool isValid() const { return (mpCairoLib != NULL); }
- bool isCairoRenderable(const ServerFont& rFont);
-
- cairo_surface_t* xlib_surface_create_with_xrender_format(Display *pDisplay, Drawable drawable, Screen *pScreen, XRenderPictFormat *pFormat, int width, int height)
- { return (*mp_xlib_surface_create_with_xrender_format)(pDisplay, drawable, pScreen, pFormat, width, height); }
- void surface_destroy(cairo_surface_t *surface) { (*mp_surface_destroy)(surface); }
- cairo_t* create(cairo_surface_t *surface) { return (*mp_create)(surface); }
- void destroy(cairo_t *cr) { (*mp_destroy)(cr); }
- void clip(cairo_t *cr) { (*mp_clip)(cr); }
- void rectangle(cairo_t *cr, double x, double y, double width, double height)
- { (*mp_rectangle)(cr, x, y, width, height); }
- cairo_font_face_t* ft_font_face_create_for_ft_face(FT_Face face, int load_flags)
- { return (*mp_ft_font_face_create_for_ft_face)(face, load_flags); }
- cairo_font_face_t* ft_font_face_create_for_pattern(void *pattern)
- {
- return mp_ft_font_face_create_for_pattern
- ? (*mp_ft_font_face_create_for_pattern)(pattern)
- : NULL;
- }
- void set_font_face(cairo_t *cr, cairo_font_face_t *font_face)
- { (*mp_set_font_face)(cr, font_face); }
- void font_face_destroy(cairo_font_face_t *font_face)
- { (*mp_font_face_destroy)(font_face); }
- void matrix_init_identity(cairo_matrix_t *matrix)
- { (*mp_matrix_init_identity)(matrix); }
- void matrix_scale(cairo_matrix_t *matrix, double sx, double sy)
- { (*mp_matrix_scale)(matrix, sx, sy); }
- void matrix_rotate(cairo_matrix_t *matrix, double radians)
- { (*mp_matrix_rotate)(matrix, radians); }
- void set_font_matrix(cairo_t *cr, const cairo_matrix_t *matrix)
- { (*mp_set_font_matrix)(cr, matrix); }
- void show_glyphs(cairo_t *cr, const cairo_glyph_t *glyphs, int no_glyphs)
- { (*mp_show_glyphs)(cr, glyphs, no_glyphs); }
- void set_source_rgb(cairo_t *cr, double red, double green, double blue)
- { (*mp_set_source_rgb)(cr, red, green, blue); }
- void set_font_options(cairo_t *cr, const void *options)
- { (*mp_set_font_options)(cr, options); }
- void ft_font_options_substitute(const void *options, void *pattern)
- { (*mp_ft_font_options_substitute)(options, pattern); }
-};
-
-static CairoWrapper* pCairoInstance = NULL;
-
-CairoWrapper& CairoWrapper::get()
-{
- if( ! pCairoInstance )
- pCairoInstance = new CairoWrapper();
- return *pCairoInstance;
-}
-
-CairoWrapper::CairoWrapper()
+namespace
{
- static const char* pDisableCairoText = getenv( "SAL_DISABLE_CAIROTEXT" );
- if( pDisableCairoText && (pDisableCairoText[0] != '0') )
- return;
-
- int nDummy;
- if( !XQueryExtension( GetX11SalData()->GetDisplay()->GetDisplay(), "RENDER", &nDummy, &nDummy, &nDummy ) )
- return;
-
- OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( "libcairo.so.2" ));
- if ( !mpCairoLib.load( aLibName, SAL_LOADMODULE_DEFAULT ) )
- return;
-
-#ifdef DEBUG
- // check cairo version
- int (*p_version)();
- p_version = (int(*)()) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_version" );
- const int nVersion = p_version ? (*p_version)() : 0;
- fprintf( stderr, "CAIRO version=%d\n", nVersion );
-#endif
-
- mp_xlib_surface_create_with_xrender_format = (cairo_surface_t* (*)(Display *, Drawable , Screen *, XRenderPictFormat *, int , int ))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_xlib_surface_create_with_xrender_format" );
- mp_surface_destroy = (void(*)(cairo_surface_t*))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_surface_destroy" );
- mp_create = (cairo_t*(*)(cairo_surface_t*))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_create" );
- mp_destroy = (void(*)(cairo_t*))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_destroy" );
- mp_clip = (void(*)(cairo_t*))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_clip" );
- mp_rectangle = (void(*)(cairo_t*, double, double, double, double))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_rectangle" );
- mp_ft_font_face_create_for_ft_face = (cairo_font_face_t * (*)(FT_Face, int))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_ft_font_face_create_for_ft_face" );
- mp_ft_font_face_create_for_pattern = (cairo_font_face_t * (*)(void*))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_ft_font_face_create_for_pattern" );
- mp_set_font_face = (void (*)(cairo_t *, cairo_font_face_t *))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_set_font_face" );
- mp_font_face_destroy = (void (*)(cairo_font_face_t *))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_font_face_destroy" );
- mp_matrix_init_identity = (void (*)(cairo_matrix_t *))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_matrix_init_identity" );
- mp_matrix_scale = (void (*)(cairo_matrix_t *, double, double))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_matrix_scale" );
- mp_matrix_rotate = (void (*)(cairo_matrix_t *, double))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_matrix_rotate" );
- mp_set_font_matrix = (void (*)(cairo_t *, const cairo_matrix_t *))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_set_font_matrix" );
- mp_show_glyphs = (void (*)(cairo_t *, const cairo_glyph_t *, int ))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_show_glyphs" );
- mp_set_source_rgb = (void (*)(cairo_t *, double , double , double ))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_set_source_rgb" );
- mp_set_font_options = (void (*)(cairo_t *, const void *options ))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_set_font_options" );
- mp_ft_font_options_substitute = (void (*)(const void *, void *))
- osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_ft_font_options_substitute" );
-
- if( !(
- mp_xlib_surface_create_with_xrender_format &&
- mp_surface_destroy &&
- mp_create &&
- mp_destroy &&
- mp_clip &&
- mp_rectangle &&
- mp_ft_font_face_create_for_ft_face &&
- mp_set_font_face &&
- mp_font_face_destroy &&
- mp_matrix_init_identity &&
- mp_matrix_scale &&
- mp_matrix_rotate &&
- mp_set_font_matrix &&
- mp_show_glyphs &&
- mp_set_source_rgb &&
- mp_set_font_options &&
- mp_ft_font_options_substitute
- ) )
+ bool isCairoRenderable(const ServerFont& rFont)
{
- mpCairoLib.unload();
-#if OSL_DEBUG_LEVEL > 1
- fprintf( stderr, "not all needed symbols were found\n" );
-#endif
+ return rFont.GetFtFace();
}
-}
-
-bool CairoWrapper::isCairoRenderable(const ServerFont& rFont)
-{
- return rFont.GetFtFace() && isValid() && rFont.GetAntialiasAdvice() &&
- (rFont.NeedsArtificialBold() ? canEmbolden() : true);
-}
-
} //namespace
CairoFontsCache::LRUFonts CairoFontsCache::maLRUFonts;
@@ -437,10 +263,9 @@ CairoFontsCache::~CairoFontsCache()
--mnRefCount;
if (!mnRefCount && !maLRUFonts.empty())
{
- CairoWrapper &rCairo = CairoWrapper::get();
LRUFonts::iterator aEnd = maLRUFonts.end();
for (LRUFonts::iterator aI = maLRUFonts.begin(); aI != aEnd; ++aI)
- rCairo.font_face_destroy((cairo_font_face_t*)aI->first);
+ cairo_font_face_destroy((cairo_font_face_t*)aI->first);
}
}
@@ -449,8 +274,7 @@ void CairoFontsCache::CacheFont(void *pFont, const CairoFontsCache::CacheId &rId
maLRUFonts.push_front( std::pair<void*, CairoFontsCache::CacheId>(pFont, rId) );
if (maLRUFonts.size() > 8)
{
- CairoWrapper &rCairo = CairoWrapper::get();
- rCairo.font_face_destroy((cairo_font_face_t*)maLRUFonts.back().first);
+ cairo_font_face_destroy((cairo_font_face_t*)maLRUFonts.back().first);
maLRUFonts.pop_back();
}
}
@@ -464,9 +288,18 @@ void* CairoFontsCache::FindCachedFont(const CairoFontsCache::CacheId &rId)
return NULL;
}
+namespace
+{
+ bool hasRotation(int nRotation)
+ {
+ return nRotation != 0;
+ }
+}
+
void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
{
std::vector<cairo_glyph_t> cairo_glyphs;
+ std::vector<int> glyph_extrarotation;
cairo_glyphs.reserve( 256 );
Point aPos;
@@ -478,6 +311,19 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
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(900);
+ break;
+ case GF_ROTR: // right
+ glyph_extrarotation.push_back(-900);
+ break;
+ default:
+ glyph_extrarotation.push_back(0);
+ break;
+ }
}
if (cairo_glyphs.empty())
@@ -489,11 +335,9 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
if( !pVisualFormat )
return;
- CairoWrapper &rCairo = CairoWrapper::get();
-
Display* pDisplay = GetXDisplay();
- cairo_surface_t *surface = rCairo.xlib_surface_create_with_xrender_format (pDisplay,
+ cairo_surface_t *surface = cairo_xlib_surface_create_with_xrender_format (pDisplay,
hDrawable_, ScreenOfDisplay(pDisplay, m_nScreen), pVisualFormat, SAL_MAX_INT16, SAL_MAX_INT16);
/*
@@ -502,26 +346,26 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
* least change the SalFrame etc impls to dtor the SalGraphics *before* the
* destruction of the windows they reference
*/
- cairo_t *cr = rCairo.create(surface);
- rCairo.surface_destroy(surface);
+ cairo_t *cr = cairo_create(surface);
+ cairo_surface_destroy(surface);
if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions())
- rCairo.set_font_options( cr, pOptions);
+ 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)
{
- rCairo.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_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);
}
- rCairo.clip(cr);
+ cairo_clip(cr);
}
- rCairo.set_source_rgb(cr,
+ cairo_set_source_rgb(cr,
SALCOLOR_RED(nTextColor_)/255.0,
SALCOLOR_GREEN(nTextColor_)/255.0,
SALCOLOR_BLUE(nTextColor_)/255.0);
@@ -541,30 +385,67 @@ void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
const ImplFontOptions *pOptions = rFont.GetFontOptions().get();
void *pPattern = pOptions ? pOptions->GetPattern(pFace, aId.mbEmbolden) : NULL;
if (pPattern)
- font_face = rCairo.ft_font_face_create_for_pattern(pPattern);
+ font_face = cairo_ft_font_face_create_for_pattern(reinterpret_cast<FcPattern*>(pPattern));
if (!font_face)
- font_face = rCairo.ft_font_face_create_for_ft_face(pFace, rFont.GetLoadFlags());
+ font_face = cairo_ft_font_face_create_for_ft_face(reinterpret_cast<FT_Face>(pFace), rFont.GetLoadFlags());
m_aCairoFontsCache.CacheFont(font_face, aId);
}
- rCairo.set_font_face(cr, font_face);
+ cairo_set_font_face(cr, font_face);
cairo_matrix_t m;
const ImplFontSelectData& rFSD = rFont.GetFontSelData();
- int nWidth = rFSD.mnWidth ? rFSD.mnWidth : rFSD.mnHeight;
+ 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);
+
+ cairo_matrix_init_identity(&m);
+
+ if (rFont.NeedsArtificialItalic())
+ m.xy = -m.xx * 0x6000L / 0x10000L;
+
+ if (rLayout.GetOrientation())
+ cairo_matrix_rotate(&m, (3600 - rLayout.GetOrientation()) * M_PI / 1800.0);
- rCairo.matrix_init_identity(&m);
+ cairo_matrix_scale(&m, nWidth, nHeight);
- if (rLayout.GetOrientation())
- rCairo.matrix_rotate(&m, (3600 - rLayout.GetOrientation()) * M_PI / 1800.0);
+ if (nGlyphRotation)
+ {
+ cairo_matrix_rotate(&m, (3600 - nGlyphRotation) * M_PI / 1800.0);
+
+ cairo_font_extents_t extents;
+ cairo_font_extents(cr, &extents);
+ //gives the same positions as pre-cairo conversion, but I don't like them
+ double xdiff = -extents.descent/(extents.height+extents.descent);
+ cairo_matrix_translate(&m, xdiff, 1);
+ }
- rCairo.matrix_scale(&m, nWidth, rFSD.mnHeight);
- if (rFont.NeedsArtificialItalic())
- m.xy = -m.xx * 0x6000L / 0x10000L;
+ cairo_set_font_matrix(cr, &m);
+ size_t nStartIndex = std::distance(aStart, aI);
+ size_t nLen = std::distance(aI, aNext);
+ 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
- rCairo.set_font_matrix(cr, &m);
- rCairo.show_glyphs(cr, &cairo_glyphs[0], cairo_glyphs.size());
- rCairo.destroy(cr);
+ aI = aNext;
+ }
+
+ cairo_destroy(cr);
}
//--------------------------------------------------------------------------
@@ -924,7 +805,7 @@ void X11SalGraphics::DrawServerFontLayout( const ServerFontLayout& rLayout )
ServerFont& rFont = rLayout.GetServerFont();
const bool bVertical = rFont.GetFontSelData().mbVertical;
- if( !bVertical && CairoWrapper::get().isCairoRenderable(rFont) )
+ if( !bVertical && isCairoRenderable(rFont) )
DrawCairoAAFontString( rLayout );
else
{
@@ -1083,16 +964,14 @@ void X11SalGraphics::GetDevFontSubstList( OutputDevice* )
// ----------------------------------------------------------------------------
-void cairosubcallback( void* pPattern )
+void cairosubcallback(void* pPattern)
{
- CairoWrapper& rCairo = CairoWrapper::get();
- if( !rCairo.isValid() )
- return;
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
const void* pFontOptions = rStyleSettings.GetCairoFontOptions();
if( !pFontOptions )
return;
- rCairo.ft_font_options_substitute( pFontOptions, pPattern );
+ cairo_ft_font_options_substitute(static_cast<const cairo_font_options_t*>(pFontOptions),
+ static_cast<FcPattern*>(pPattern));
}
ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize)