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

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

Return to issue 85470