View | Details | Raw Unified | Return to issue 85470
Collapse All | Expand All

(-)openoffice.org.orig/vcl/inc/vcl/glyphcache.hxx (+4 lines)
Lines 186-191 Link Here
186
    virtual const ::rtl::OString*   GetFontFileName() const { return NULL; }
186
    virtual const ::rtl::OString*   GetFontFileName() const { return NULL; }
187
    virtual int                 GetFontFaceNumber() const   { return 0; }
187
    virtual int                 GetFontFaceNumber() const   { return 0; }
188
    virtual bool                TestFont() const            { return true; }
188
    virtual bool                TestFont() const            { return true; }
189
    virtual void*               GetFtFace() const { return 0; }
190
    virtual int                 GetLoadFlags() const { return 0; }
191
    virtual bool                NeedsArtificialBold() const { return false; }
192
    virtual bool		        NeedsArtificialItalic() const { return false; }
189
193
190
    const ImplFontSelectData&   GetFontSelData() const      { return maFontSelData; }
194
    const ImplFontSelectData&   GetFontSelData() const      { return maFontSelData; }
191
195
(-)openoffice.org.orig/vcl/source/glyphs/gcach_ftyp.hxx (+4 lines)
Lines 181-186 Link Here
181
    virtual const ::rtl::OString* GetFontFileName() const { return mpFontInfo->GetFontFileName(); }
181
    virtual const ::rtl::OString* GetFontFileName() const { return mpFontInfo->GetFontFileName(); }
182
    virtual int                 GetFontFaceNum() const { return mpFontInfo->GetFaceNum(); }
182
    virtual int                 GetFontFaceNum() const { return mpFontInfo->GetFaceNum(); }
183
    virtual bool                TestFont() const;
183
    virtual bool                TestFont() const;
184
    virtual void*               GetFtFace() const { return maFaceFT; }
185
    virtual int               	GetLoadFlags() const { return mnLoadFlags; }
186
    virtual bool                NeedsArtificialBold() const { return mbArtBold; }
187
    virtual bool                NeedsArtificialItalic() const { return mbArtItalic; }
184
188
185
    virtual void                FetchFontMetric( ImplFontMetricData&, long& rFactor ) const;
189
    virtual void                FetchFontMetric( ImplFontMetricData&, long& rFactor ) const;
186
190
(-)openoffice.org.orig/vcl/unx/inc/salgdi.h (+1 lines)
Lines 198-203 Link Here
198
    void                    DrawServerSimpleFontString( const ServerFontLayout& );
198
    void                    DrawServerSimpleFontString( const ServerFontLayout& );
199
    void                    DrawServerAAFontString( const ServerFontLayout& );
199
    void                    DrawServerAAFontString( const ServerFontLayout& );
200
    bool                    DrawServerAAForcedString( const ServerFontLayout& );
200
    bool                    DrawServerAAForcedString( const ServerFontLayout& );
201
    void                    DrawCairoAAFontString( const ServerFontLayout& );
201
    
202
    
202
    void freeResources();
203
    void freeResources();
203
public:
204
public:
(-)openoffice.org.orig/vcl/unx/source/gdi/salgdi3.cxx (-7 / +379 lines)
Lines 123-128 Link Here
123
123
124
#include <hash_set>
124
#include <hash_set>
125
125
126
#include <X11/Xregion.h>
127
128
struct cairo_surface_t;
129
struct cairo_t;
130
struct cairo_font_face_t;
131
typedef void* FT_Face;
132
struct cairo_matrix_t {
133
    double xx; double yx;
134
    double xy; double yy;
135
    double x0; double y0;
136
};
137
struct cairo_glyph_t
138
{
139
    unsigned long index;
140
    double x;
141
    double y;
142
};
143
#ifdef EMBOLDHACK
144
struct FcPattern;
145
typedef sal_Char FcChar8;
146
struct FcBlanks;
147
typedef int FcBool;
148
struct FcConfig;
149
enum FcResult { FcResultMatch, FcResultNoMatch };
150
enum FcMatchKind { FcMatchPattern, FcMatchFont, FcMatchScan };
151
#endif
126
using namespace rtl;
152
using namespace rtl;
127
153
128
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
154
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Lines 734-739 Link Here
734
}
760
}
735
761
736
//--------------------------------------------------------------------------
762
//--------------------------------------------------------------------------
763
namespace {
764
#ifdef EMBOLDHACK
765
class EmboldenWrapper
766
{
767
private:
768
    bool mbIsValid;
769
770
    FcPattern * (*mp_FcFreeTypeQueryFace)(const FT_Face face, const FcChar8 *file, int
771
       id, FcBlanks *blanks);
772
    FcBool (*mp_FcPatternAddInteger)(FcPattern*,const char*,int);
773
    FcBool (*mp_FcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind);
774
    void (*mp_FcDefaultSubstitute)(FcPattern*);
775
    FcPattern * (*mp_FcFontMatch)(FcConfig *, FcPattern *, FcResult *);
776
    void (*mp_FcPatternDestroy)(FcPattern*);
777
778
    EmboldenWrapper();
779
public:
780
    static EmboldenWrapper& get();
781
    bool isValid() const { return mbIsValid; }
782
783
    FcPattern* FcFreeTypeQueryFace( const FT_Face face, const FcChar8 *pFile, int id, FcBlanks* pBlanks )
784
    { return mp_FcFreeTypeQueryFace( face, pFile, id, pBlanks ); }
785
    FcBool FcPatternAddInteger( FcPattern* pPattern, const char* pObject, int nValue )
786
    { return mp_FcPatternAddInteger( pPattern, pObject, nValue ); }
787
    FcBool FcConfigSubstitute( FcConfig* pConfig, FcPattern* pPattern, FcMatchKind eKind )
788
    { return mp_FcConfigSubstitute( pConfig, pPattern, eKind ); }
789
    void FcDefaultSubstitute( FcPattern* pPattern )
790
    { mp_FcDefaultSubstitute( pPattern ); }
791
    FcPattern* FcFontMatch( FcConfig* pConfig, FcPattern* pPattern, FcResult* pResult)
792
    { return mp_FcFontMatch( pConfig, pPattern, pResult); }
793
    void FcPatternDestroy( FcPattern* pPattern )
794
    { mp_FcPatternDestroy( pPattern ); }
795
};
796
#endif
797
798
class CairoWrapper
799
{
800
private:
801
    bool mbIsValid;
802
803
    cairo_surface_t* (*mp_xlib_surface_create)(Display *, Drawable , Visual *, int , int );
804
    void (*mp_surface_destroy)(cairo_surface_t *);
805
    cairo_t* (*mp_create)(cairo_surface_t *);
806
    void (*mp_destroy)(cairo_t*);
807
    void (*mp_clip)(cairo_t*);
808
    void (*mp_rectangle)(cairo_t*, double, double, double, double);
809
    cairo_font_face_t * (*mp_ft_font_face_create_for_ft_face)(FT_Face, int);
810
#ifdef EMBOLDHACK
811
    cairo_font_face_t * (*mp_ft_font_face_create_for_pattern)(FcPattern *);
812
#endif
813
    void (*mp_set_font_face)(cairo_t *, cairo_font_face_t *);
814
    void (*mp_font_face_destroy)(cairo_font_face_t *);
815
    void (*mp_matrix_init_identity)(cairo_matrix_t *);
816
    void (*mp_matrix_scale)(cairo_matrix_t *, double, double);
817
    void (*mp_matrix_rotate)(cairo_matrix_t *, double);
818
    void (*mp_set_font_matrix)(cairo_t *, const cairo_matrix_t *);
819
    void (*mp_show_glyphs)(cairo_t *, const cairo_glyph_t *, int );
820
    void (*mp_set_source_rgb)(cairo_t *, double , double , double );
821
822
#ifdef EMBOLDHACK
823
    bool canEmbolden() const { return EmboldenWrapper::get().isValid(); }
824
#else
825
    bool canEmbolden() const { return false; }
826
#endif
827
828
    CairoWrapper();
829
public:
830
    static CairoWrapper& get();
831
    bool isValid() const { return mbIsValid; }
832
    bool isCairoRenderable(const ServerFont& rFont);
833
834
    cairo_surface_t* xlib_surface_create(Display *pDisplay, Drawable drawable, Visual *pVisual, int width, int height)
835
        { return (*mp_xlib_surface_create)(pDisplay, drawable, pVisual, width, height); }
836
    void surface_destroy(cairo_surface_t *surface) { (*mp_surface_destroy)(surface); }
837
    cairo_t* create(cairo_surface_t *surface) { return (*mp_create)(surface); }
838
    void destroy(cairo_t *cr) { (*mp_destroy)(cr); }
839
    void clip(cairo_t *cr) { (*mp_clip)(cr); }
840
    void rectangle(cairo_t *cr, double x, double y, double width, double height) 
841
        { (*mp_rectangle)(cr, x, y, width, height); }
842
    cairo_font_face_t* ft_font_face_create_for_ft_face(FT_Face face, int load_flags)
843
        { return (*mp_ft_font_face_create_for_ft_face)(face, load_flags); }
844
#ifdef EMBOLDHACK
845
    cairo_font_face_t* ft_font_face_create_for_pattern(FcPattern *pattern)
846
        { return (*mp_ft_font_face_create_for_pattern)(pattern); }
847
#endif
848
    void set_font_face(cairo_t *cr, cairo_font_face_t *font_face)
849
        { (*mp_set_font_face)(cr, font_face); }
850
    void font_face_destroy(cairo_font_face_t *font_face)
851
        { (*mp_font_face_destroy)(font_face); }
852
    void matrix_init_identity(cairo_matrix_t *matrix)
853
        { (*mp_matrix_init_identity)(matrix); }
854
    void matrix_scale(cairo_matrix_t *matrix, double sx, double sy)
855
        { (*mp_matrix_scale)(matrix, sx, sy); }
856
    void matrix_rotate(cairo_matrix_t *matrix, double radians)
857
        { (*mp_matrix_rotate)(matrix, radians); }
858
    void set_font_matrix(cairo_t *cr, const cairo_matrix_t *matrix)
859
        { (*mp_set_font_matrix)(cr, matrix); }
860
    void show_glyphs(cairo_t *cr, const cairo_glyph_t *glyphs, int no_glyphs)
861
        { (*mp_show_glyphs)(cr, glyphs, no_glyphs); }
862
    void set_source_rgb(cairo_t *cr, double red, double green, double blue)
863
        { (*mp_set_source_rgb)(cr, red, green, blue); }
864
};
865
866
#ifdef EMBOLDHACK
867
868
static EmboldenWrapper* pEmbInstance = NULL;
869
870
EmboldenWrapper& EmboldenWrapper::get()
871
{
872
    if( ! pEmbInstance )
873
        pEmbInstance = new EmboldenWrapper();
874
    return *pEmbInstance;
875
}
876
877
EmboldenWrapper::EmboldenWrapper() : mbIsValid(false)
878
{
879
    mp_FcFreeTypeQueryFace = (FcPattern* (*)(const FT_Face, const FcChar8 *, int
880
       , FcBlanks *))
881
        osl_getAsciiFunctionSymbol(NULL, "FcFreeTypeQueryFace" );
882
    mp_FcPatternAddInteger = (FcBool (*)(FcPattern*,const char*,int))
883
        osl_getAsciiFunctionSymbol(NULL, "FcPatternAddInteger" );
884
    mp_FcConfigSubstitute = (FcBool (*)(FcConfig*,FcPattern*,FcMatchKind))
885
        osl_getAsciiFunctionSymbol(NULL, "FcConfigSubstitute" );
886
    mp_FcDefaultSubstitute = (void (*)(FcPattern*))
887
        osl_getAsciiFunctionSymbol(NULL, "FcDefaultSubstitute" );
888
    mp_FcFontMatch = (FcPattern* (*)(FcConfig *, FcPattern *, FcResult *))
889
        osl_getAsciiFunctionSymbol(NULL, "FcFontMatch" );
890
    mp_FcPatternDestroy = (void (*)(FcPattern*))
891
        osl_getAsciiFunctionSymbol(NULL, "FcPatternDestroy" );
892
893
    mbIsValid = 
894
        (
895
            mp_FcFreeTypeQueryFace &&
896
            mp_FcPatternAddInteger &&
897
            mp_FcConfigSubstitute &&
898
            mp_FcDefaultSubstitute &&
899
            mp_FcFontMatch &&
900
            mp_FcPatternDestroy
901
        );
902
    if (!mbIsValid)
903
    {
904
#if OSL_DEBUG_LEVEL > 1
905
        fprintf( stderr, "not all needed symbols were found to embolden\n" );
906
#endif
907
    }
908
}
909
#endif
910
911
static CairoWrapper* pCairoInstance = NULL;
912
913
CairoWrapper& CairoWrapper::get()
914
{
915
    if( ! pCairoInstance )
916
        pCairoInstance = new CairoWrapper();
917
    return *pCairoInstance;
918
}
919
920
CairoWrapper::CairoWrapper() : mbIsValid(false)
921
{
922
    static const char* pEnableCairoText = getenv( "SAL_ENABLE_CAIROTEXT" );
923
    if( !pEnableCairoText || (pEnableCairoText[0] == '0') )
924
        return;
925
926
    mp_xlib_surface_create = (cairo_surface_t* (*)(Display *, Drawable , Visual *, int , int )) 
927
        osl_getAsciiFunctionSymbol(NULL, "cairo_xlib_surface_create" );
928
    mp_surface_destroy = (void(*)(cairo_surface_t*)) 
929
        osl_getAsciiFunctionSymbol(NULL, "cairo_surface_destroy" );
930
    mp_create = (cairo_t*(*)(cairo_surface_t*)) 
931
        osl_getAsciiFunctionSymbol(NULL, "cairo_create" );
932
    mp_destroy = (void(*)(cairo_t*))
933
        osl_getAsciiFunctionSymbol(NULL, "cairo_destroy" );
934
    mp_clip = (void(*)(cairo_t*))
935
        osl_getAsciiFunctionSymbol(NULL, "cairo_clip" );
936
    mp_rectangle = (void(*)(cairo_t*, double, double, double, double))
937
        osl_getAsciiFunctionSymbol(NULL, "cairo_rectangle" );
938
    mp_ft_font_face_create_for_ft_face = (cairo_font_face_t * (*)(FT_Face, int))
939
        osl_getAsciiFunctionSymbol(NULL, "cairo_ft_font_face_create_for_ft_face" );
940
#ifdef EMBOLDHACK
941
    mp_ft_font_face_create_for_pattern = (cairo_font_face_t * (*)(FcPattern*))
942
        osl_getAsciiFunctionSymbol(NULL, "cairo_ft_font_face_create_for_pattern" );
943
#endif
944
    mp_set_font_face = (void (*)(cairo_t *, cairo_font_face_t *))
945
        osl_getAsciiFunctionSymbol(NULL, "cairo_set_font_face" );
946
    mp_font_face_destroy = (void (*)(cairo_font_face_t *))
947
        osl_getAsciiFunctionSymbol(NULL, "cairo_font_face_destroy" );
948
    mp_matrix_init_identity = (void (*)(cairo_matrix_t *))
949
        osl_getAsciiFunctionSymbol(NULL, "cairo_matrix_init_identity" );
950
    mp_matrix_scale = (void (*)(cairo_matrix_t *, double, double))
951
        osl_getAsciiFunctionSymbol(NULL, "cairo_matrix_scale" );
952
    mp_matrix_rotate = (void (*)(cairo_matrix_t *, double))
953
        osl_getAsciiFunctionSymbol(NULL, "cairo_matrix_rotate" );
954
    mp_set_font_matrix = (void (*)(cairo_t *, const cairo_matrix_t *))
955
        osl_getAsciiFunctionSymbol(NULL, "cairo_set_font_matrix" );
956
    mp_show_glyphs = (void (*)(cairo_t *, const cairo_glyph_t *, int ))
957
        osl_getAsciiFunctionSymbol(NULL, "cairo_show_glyphs" );
958
    mp_set_source_rgb = (void (*)(cairo_t *, double , double , double ))
959
        osl_getAsciiFunctionSymbol(NULL, "cairo_set_source_rgb" );
960
961
    mbIsValid = 
962
        (
963
            mp_xlib_surface_create &&
964
            mp_surface_destroy &&
965
            mp_create &&
966
            mp_destroy &&
967
            mp_clip &&
968
            mp_rectangle &&
969
            mp_ft_font_face_create_for_ft_face &&
970
#ifdef EMBOLDHACK
971
            mp_ft_font_face_create_for_pattern &&
972
#endif
973
            mp_set_font_face &&
974
            mp_font_face_destroy &&
975
            mp_matrix_init_identity &&
976
            mp_matrix_scale &&
977
            mp_matrix_rotate &&
978
            mp_set_font_matrix &&
979
            mp_show_glyphs &&
980
            mp_set_source_rgb
981
        );
982
    if (!mbIsValid)
983
    {
984
#if OSL_DEBUG_LEVEL > 1
985
        fprintf( stderr, "not all needed symbols were found\n" );
986
#endif
987
    }
988
}
989
990
bool CairoWrapper::isCairoRenderable(const ServerFont& rFont)
991
{
992
    return rFont.GetFtFace() && isValid() && 
993
        (rFont.NeedsArtificialBold() ? canEmbolden() : true);
994
}
995
996
} //namespace
997
998
void X11SalGraphics::DrawCairoAAFontString( const ServerFontLayout& rLayout )
999
{
1000
    Display* pDisplay = GetXDisplay();
1001
    Visual* pVisual = GetDisplay()->GetVisual( GetScreenNumber() ).GetVisual();
1002
    CairoWrapper &rCairo = CairoWrapper::get();
1003
1004
    cairo_surface_t *surface = rCairo.xlib_surface_create (pDisplay,
1005
	hDrawable_, pVisual, 1, 1);
1006
1007
    cairo_t *cr = rCairo.create (surface);
1008
    rCairo.surface_destroy (surface);
1009
1010
    if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
1011
    {
1012
	for (long i = 0; i < pClipRegion_->numRects; ++i)
1013
	{
1014
            rCairo.rectangle(cr, 
1015
                pClipRegion_->rects[i].x1, 
1016
                pClipRegion_->rects[i].y1,
1017
                pClipRegion_->rects[i].x2 - pClipRegion_->rects[i].x1,
1018
                pClipRegion_->rects[i].y2 - pClipRegion_->rects[i].y1);
1019
	}
1020
        rCairo.clip(cr);
1021
    }
1022
1023
    rCairo.set_source_rgb(cr, 
1024
        SALCOLOR_RED(nTextColor_)/255.0, 
1025
        SALCOLOR_GREEN(nTextColor_)/255.0,
1026
        SALCOLOR_BLUE(nTextColor_)/255.0);
1027
1028
    ServerFont& rFont = rLayout.GetServerFont();
1029
1030
    cairo_font_face_t* font_face;
1031
1032
#ifdef EMBOLDHACK
1033
    if (rFont.NeedsArtificialBold())
1034
    {
1035
	/*
1036
         Artificial Bold is a PITA as there's no way currently to do it through
1037
         the ft api of cairo that I can see, if one is added then we can prefer
1038
         that way of doing it to this, emboldening is pretty care, so we defer
1039
         looking for emboldening symbols until the first time it's checked for
1040
         in isCairoRenderable
1041
        */
1042
        EmboldenWrapper &rEmb = EmboldenWrapper::get();
1043
1044
        const ::rtl::OString *pFileName = rFont.GetFontFileName();
1045
        FcPattern *pattern = rEmb.FcFreeTypeQueryFace(rFont.GetFtFace(), 
1046
            pFileName->getStr(), rFont.GetFontFaceNumber(), NULL);
1047
        rEmb.FcPatternAddInteger(pattern, "weight", 200);
1048
        rEmb.FcConfigSubstitute(NULL, pattern, FcMatchPattern);
1049
   	rEmb.FcDefaultSubstitute(pattern);
1050
	FcPattern *resolved = rEmb.FcFontMatch(NULL, pattern, NULL);
1051
        rEmb.FcPatternDestroy(pattern);
1052
1053
        font_face = rCairo.ft_font_face_create_for_pattern(resolved);
1054
1055
        rEmb.FcPatternDestroy(resolved);
1056
    }
1057
    else
1058
#endif
1059
    {
1060
        font_face = 
1061
            rCairo.ft_font_face_create_for_ft_face((FT_Face)rFont.GetFtFace(), 
1062
                rFont.GetLoadFlags());
1063
    }
1064
1065
    rCairo.set_font_face(cr, font_face);
1066
1067
    cairo_matrix_t m;
1068
    const ImplFontSelectData& rFSD = rFont.GetFontSelData();
1069
    int nWidth = rFSD.mnWidth ? rFSD.mnWidth : rFSD.mnHeight;
1070
1071
    rCairo.matrix_init_identity(&m);
1072
1073
    if (rLayout.GetOrientation())
1074
        rCairo.matrix_rotate(&m, (3600 - rLayout.GetOrientation()) * M_PI / 1800.0);
1075
1076
    rCairo.matrix_scale(&m, nWidth, rFSD.mnHeight);
1077
    if (rFont.NeedsArtificialItalic())
1078
        m.xy = -m.xx * 0x6000L / 0x10000L;
1079
1080
    rCairo.set_font_matrix(cr, &m);
1081
1082
    std::vector<cairo_glyph_t> cairo_glyphs;
1083
    sal_Int32 nGlyph;
1084
    Point aPos;
1085
    int nStart = 0;
1086
    while (rLayout.GetNextGlyphs( 1, &nGlyph, aPos, nStart ))
1087
    {
1088
        cairo_glyph_t aGlyph;
1089
        aGlyph.index = nGlyph;
1090
        aGlyph.x = aPos.X();
1091
        aGlyph.y = aPos.Y();
1092
        cairo_glyphs.push_back(aGlyph);
1093
    }
1094
1095
    if (!cairo_glyphs.empty())
1096
        rCairo.show_glyphs (cr, &cairo_glyphs[0], cairo_glyphs.size());
1097
1098
    rCairo.font_face_destroy(font_face);
1099
1100
    rCairo.destroy (cr);
1101
}
1102
1103
//--------------------------------------------------------------------------
737
1104
738
void X11SalGraphics::DrawServerAAFontString( const ServerFontLayout& rLayout )
1105
void X11SalGraphics::DrawServerAAFontString( const ServerFontLayout& rLayout )
739
{
1106
{
Lines 1111-1125 Link Here
1111
    // draw complex text
1478
    // draw complex text
1112
    ServerFont& rFont = rLayout.GetServerFont();
1479
    ServerFont& rFont = rLayout.GetServerFont();
1113
1480
1114
    X11GlyphPeer& rGlyphPeer = X11GlyphCache::GetInstance().GetPeer();
1481
    if (CairoWrapper::get().isCairoRenderable(rFont))
1115
    if( rGlyphPeer.GetGlyphSet( rFont, m_nScreen ) )
1482
        DrawCairoAAFontString( rLayout );
1116
        DrawServerAAFontString( rLayout );
1483
    else
1484
    {
1485
        X11GlyphPeer& rGlyphPeer = X11GlyphCache::GetInstance().GetPeer();
1486
        if( rGlyphPeer.GetGlyphSet( rFont, m_nScreen ) )
1487
            DrawServerAAFontString( rLayout );
1117
#ifndef MACOSX        /* ignore X11 fonts on MACOSX */
1488
#ifndef MACOSX        /* ignore X11 fonts on MACOSX */
1118
    else if( !rGlyphPeer.ForcedAntialiasing( rFont, m_nScreen ) )
1489
        else if( !rGlyphPeer.ForcedAntialiasing( rFont, m_nScreen ) )
1119
        DrawServerSimpleFontString( rLayout );
1490
            DrawServerSimpleFontString( rLayout );
1120
#endif // MACOSX
1491
#endif // MACOSX
1121
    else
1492
        else
1122
        DrawServerAAForcedString( rLayout );
1493
            DrawServerAAForcedString( rLayout );
1494
    }
1123
}
1495
}
1124
1496
1125
//--------------------------------------------------------------------------
1497
//--------------------------------------------------------------------------

Return to issue 85470