diff -ru vcl.precairo/inc/vcl/glyphcache.hxx vcl/inc/vcl/glyphcache.hxx --- vcl.precairo/inc/vcl/glyphcache.hxx 2008-01-21 15:29:34.000000000 +0000 +++ vcl/inc/vcl/glyphcache.hxx 2008-01-21 19:26:06.000000000 +0000 @@ -210,6 +210,9 @@ int GetExtInfo() { return mnExtInfo; } void* GetExtPointer() { return mpExtData; } + virtual void* GetFtFace() const { return 0; } + virtual int GetLoadFlags() const { return 0; } + protected: friend class GlyphCache; friend class ServerFontLayout; diff -ru vcl.precairo/source/glyphs/gcach_ftyp.hxx vcl/source/glyphs/gcach_ftyp.hxx --- vcl.precairo/source/glyphs/gcach_ftyp.hxx 2008-01-21 15:29:27.000000000 +0000 +++ vcl/source/glyphs/gcach_ftyp.hxx 2008-01-21 19:25:43.000000000 +0000 @@ -200,6 +200,9 @@ int GetEmUnits() const; const FT_Size_Metrics& GetMetricsFT() const { return maSizeFT->metrics; } + virtual void* GetFtFace() const { return maFaceFT; } + virtual int GetLoadFlags() const { return mnLoadFlags; } + protected: friend class GlyphCache; diff -ru vcl.precairo/unx/source/gdi/salgdi3.cxx vcl/unx/source/gdi/salgdi3.cxx --- vcl.precairo/unx/source/gdi/salgdi3.cxx 2008-01-21 15:29:33.000000000 +0000 +++ vcl/unx/source/gdi/salgdi3.cxx 2008-01-22 11:47:55.000000000 +0000 @@ -123,6 +123,22 @@ #include +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; +}; + using namespace rtl; // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -735,6 +751,181 @@ //-------------------------------------------------------------------------- +class CairoWrapper +{ +private: + bool mbIsValid; + + cairo_surface_t* (*mp_xlib_surface_create)(Display *, Drawable , Visual *, int , int ); + void (*mp_surface_destroy)(cairo_surface_t *); + cairo_t* (*mp_create)(cairo_surface_t *); + void (*mp_destroy)(cairo_t*); + cairo_font_face_t * (*mp_ft_font_face_create_for_ft_face)(FT_Face, int); + void (*mp_set_font_face)(cairo_t *, cairo_font_face_t *); + void (*mp_font_face_destroy)(cairo_font_face_t *); + void (*mp_matrix_init_scale)(cairo_matrix_t *, double, double); + void (*mp_set_font_matrix)(cairo_t *, const cairo_matrix_t *); + void (*mp_show_glyphs)(cairo_t *, const cairo_glyph_t *, int ); + + oslGenericFunction loadSymbol( const char* ); + CairoWrapper(); +public: + static CairoWrapper& get(); + bool isValid() const { return mbIsValid; } + + cairo_surface_t* xlib_surface_create(Display *pDisplay, Drawable drawable, Visual *pVisual, int width, int height) + { return (*mp_xlib_surface_create)(pDisplay, drawable, pVisual, 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); } + 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); } + 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_scale(cairo_matrix_t *matrix, double sx, double sy) + { (*mp_matrix_init_scale)(matrix, sx, sy); } + 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); } +}; + +static CairoWrapper* pOneInstance = NULL; + +CairoWrapper& CairoWrapper::get() +{ + if( ! pOneInstance ) + pOneInstance = new CairoWrapper(); + return *pOneInstance; +} + +oslGenericFunction CairoWrapper::loadSymbol( const char* pSymbol ) +{ + OUString aSym( OUString::createFromAscii( pSymbol ) ); + oslGenericFunction pSym = osl_getFunctionSymbol( NULL, aSym.pData ); +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "%s %s\n", pSymbol, pSym ? "found" : "not found" ); +#endif + return pSym; +} + +CairoWrapper::CairoWrapper() : mbIsValid(false) +{ + mp_xlib_surface_create = (cairo_surface_t* (*)(Display *, Drawable , Visual *, int , int )) + loadSymbol( "cairo_xlib_surface_create" ); + mp_surface_destroy = (void(*)(cairo_surface_t*)) + loadSymbol( "cairo_surface_destroy" ); + mp_create = (cairo_t*(*)(cairo_surface_t*)) + loadSymbol( "cairo_create" ); + mp_destroy = (void(*)(cairo_t*)) + loadSymbol( "cairo_destroy" ); + mp_ft_font_face_create_for_ft_face = (cairo_font_face_t * (*)(FT_Face, int)) + loadSymbol( "cairo_ft_font_face_create_for_ft_face" ); + mp_set_font_face = (void (*)(cairo_t *, cairo_font_face_t *)) + loadSymbol( "cairo_set_font_face" ); + mp_font_face_destroy = (void (*)(cairo_font_face_t *)) + loadSymbol( "cairo_font_face_destroy" ); + mp_matrix_init_scale = (void (*)(cairo_matrix_t *, double, double)) + loadSymbol( "cairo_matrix_init_scale" ); + mp_set_font_matrix = (void (*)(cairo_t *, const cairo_matrix_t *)) + loadSymbol( "cairo_set_font_matrix" ); + mp_show_glyphs = (void (*)(cairo_t *, const cairo_glyph_t *, int )) + loadSymbol( "cairo_show_glyphs" ); + + mbIsValid = + ( + mp_xlib_surface_create && + mp_surface_destroy && + mp_create && + mp_destroy && + mp_ft_font_face_create_for_ft_face && + mp_set_font_face && + mp_font_face_destroy && + mp_matrix_init_scale && + mp_set_font_matrix && + mp_show_glyphs + ); + if (!mbIsValid) + { +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "not all needed symbols were found in libfontconfig\n" ); +#endif + } +} + +void DrawCairoAAFontString( const X11SalGraphics& rGraphics, const ServerFontLayout& rLayout ) +{ + Display* pDisplay = rGraphics.GetXDisplay(); + Visual* pVisual = rGraphics.GetDisplay()->GetVisual( rGraphics.GetScreenNumber() ).GetVisual(); + Drawable hDrawable_ = rGraphics.GetDrawable(); + CairoWrapper &rCairo = CairoWrapper::get(); + + //start temp + + int width, height; + unsigned uDummy; + XLIB_Window wDummy; + unsigned int nDrawDepth; + ::XGetGeometry( pDisplay, hDrawable_, &wDummy, &width, &height, + &uDummy, &uDummy, &uDummy, &nDrawDepth ); + + width = height = 700; + + cairo_surface_t *surface = rCairo.xlib_surface_create (pDisplay, + hDrawable_, pVisual, width, height); + //end temp + + cairo_t *cr = rCairo.create (surface); + rCairo.surface_destroy (surface); + +// cairo_set_source_rgb (cr, 1,0,0); + + ServerFont& rFont = rLayout.GetServerFont(); + + cairo_font_face_t* font_face = + rCairo.ft_font_face_create_for_ft_face(rFont.GetFtFace(), rFont.GetLoadFlags()); + + rCairo.set_font_face(cr, font_face); + + cairo_matrix_t m; + const ImplFontSelectData& rFSD = rFont.GetFontSelData(); + int nWidth = rFSD.mnWidth ? rFSD.mnWidth : rFSD.mnHeight; + rCairo.matrix_init_scale(&m, nWidth, rFSD.mnHeight); + rCairo.set_font_matrix(cr, &m); + + Point aPos; + std::vector cairo_glyphs; + for( int nStart = 0;;) + { + sal_Int32 nGlyph; + int nGlyphs = rLayout.GetNextGlyphs( 1, &nGlyph, aPos, nStart ); + if( !nGlyphs ) + break; + + // #i51924# avoid 32->16bit coordinate truncation problem in X11 + // TODO: reevaluate once displays with >30000 pixels are available + if( aPos.X() >= 30000 || aPos.Y() >= 30000 ) + continue; + + cairo_glyph_t aGlyph; + aGlyph.index = nGlyph; + aGlyph.x = aPos.X(); + aGlyph.y = aPos.Y(); + cairo_glyphs.push_back(aGlyph); + } + + if (!cairo_glyphs.empty()) + rCairo.show_glyphs (cr, &cairo_glyphs[0], cairo_glyphs.size()); + + rCairo.font_face_destroy(font_face); + + rCairo.destroy (cr); +} + +//-------------------------------------------------------------------------- + void X11SalGraphics::DrawServerAAFontString( const ServerFontLayout& rLayout ) { Display* pDisplay = GetXDisplay(); @@ -1111,15 +1302,20 @@ // draw complex text ServerFont& rFont = rLayout.GetServerFont(); - X11GlyphPeer& rGlyphPeer = X11GlyphCache::GetInstance().GetPeer(); - if( rGlyphPeer.GetGlyphSet( rFont, m_nScreen ) ) - DrawServerAAFontString( rLayout ); + if (rFont.GetFtFace() && CairoWrapper::get().isValid()) + DrawCairoAAFontString( *this, rLayout ); + else + { + X11GlyphPeer& rGlyphPeer = X11GlyphCache::GetInstance().GetPeer(); + if( rGlyphPeer.GetGlyphSet( rFont, m_nScreen ) ) + DrawServerAAFontString( rLayout ); #ifndef MACOSX /* ignore X11 fonts on MACOSX */ - else if( !rGlyphPeer.ForcedAntialiasing( rFont, m_nScreen ) ) - DrawServerSimpleFontString( rLayout ); + else if( !rGlyphPeer.ForcedAntialiasing( rFont, m_nScreen ) ) + DrawServerSimpleFontString( rLayout ); #endif // MACOSX - else - DrawServerAAForcedString( rLayout ); + else + DrawServerAAForcedString( rLayout ); + } } //--------------------------------------------------------------------------