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

(-)OOE680_m6.fontconfig/vcl/inc/vcl/outdev.h (-1 / +1 lines)
Lines 213-219 Link Here
213
                             const Font& rFont, const Size& rSize, ImplFontSubstEntry* pDevSpecific );
213
                             const Font& rFont, const Size& rSize, ImplFontSubstEntry* pDevSpecific );
214
    ImplFontEntry*      GetFallback( ImplDevFontList* pFontList,
214
    ImplFontEntry*      GetFallback( ImplDevFontList* pFontList,
215
                                     const Font& rFont, const Size& rSize,
215
                                     const Font& rFont, const Size& rSize,
216
                                     int nFallbackLevel );
216
                                     int nFallbackLevel, std::vector<sal_Unicode> &rMissingGlyphs );
217
    void                Release( ImplFontEntry* );
217
    void                Release( ImplFontEntry* );
218
    void                Invalidate();
218
    void                Invalidate();
219
};
219
};
(-)OOE680_m6.fontconfig/vcl/inc/vcl/outfont.hxx (+15 lines)
Lines 230-235 Link Here
230
    ImplDevFontListData*    FindFontFamily( const String& rFontName ) const;
230
    ImplDevFontListData*    FindFontFamily( const String& rFontName ) const;
231
    ImplDevFontListData*    ImplFindByFont( ImplFontSelectData&, bool bPrinter, ImplFontSubstEntry* pDevSpecificSubst ) const;
231
    ImplDevFontListData*    ImplFindByFont( ImplFontSelectData&, bool bPrinter, ImplFontSubstEntry* pDevSpecificSubst ) const;
232
    ImplDevFontListData*    ImplFindBySearchName( const String& ) const;
232
    ImplDevFontListData*    ImplFindBySearchName( const String& ) const;
233
    ImplDevFontListData*    ImplGetFontconfigSubstitute( ImplFontSelectData &rFontSelData, ImplFontSubstEntry* pDevSpecific );
233
234
234
    bool                    HasFallbacks() const;
235
    bool                    HasFallbacks() const;
235
    void                    SetFallbacks( ImplDevFontListData**, int nCount );
236
    void                    SetFallbacks( ImplDevFontListData**, int nCount );
Lines 333-338 Link Here
333
                        ImplFontEntry( const ImplFontSelectData& );
334
                        ImplFontEntry( const ImplFontSelectData& );
334
    virtual             ~ImplFontEntry() {}
335
    virtual             ~ImplFontEntry() {}
335
336
337
    // cache of Unicode characters and replacement font names
338
    typedef ::std::hash_map<sal_Unicode,String> UnicodeFallbackList;
339
    UnicodeFallbackList maUnicodeFallbackList;
340
336
public: // TODO: make data members private
341
public: // TODO: make data members private
337
    ImplFontSelectData  maFontSelData;      // FontSelectionData
342
    ImplFontSelectData  maFontSelData;      // FontSelectionData
338
    ImplFontMetricData  maMetric;           // Font Metric
343
    ImplFontMetricData  maMetric;           // Font Metric
Lines 343-348 Link Here
343
    short               mnOwnOrientation;   // text angle if lower layers don't rotate text themselves
348
    short               mnOwnOrientation;   // text angle if lower layers don't rotate text themselves
344
    short               mnOrientation;      // text angle in 3600 system
349
    short               mnOrientation;      // text angle in 3600 system
345
    bool                mbInit;             // true if maMetric member is valid
350
    bool                mbInit;             // true if maMetric member is valid
351
352
    void                AddFallbackForUnicode( sal_Unicode ch, String fallback )
353
                            { maUnicodeFallbackList[ch] = fallback; }
354
    String              GetFallbackForUnicode( sal_Unicode ch )
355
                            {
356
                                UnicodeFallbackList::const_iterator it = maUnicodeFallbackList.find( ch );
357
                                if ( it != maUnicodeFallbackList.end() )
358
                                    return (*it).second;
359
                                return String();
360
                            }
346
};
361
};
347
362
348
363
(-)OOE680_m6.fontconfig/vcl/inc/vcl/sallayout.hxx (+1 lines)
Lines 101-106 Link Here
101
    bool    GetRun( int* nMinRunPos, int* nEndRunPos, bool* bRTL ) const;
101
    bool    GetRun( int* nMinRunPos, int* nEndRunPos, bool* bRTL ) const;
102
    bool    GetNextPos( int* nCharPos, bool* bRTL );
102
    bool    GetNextPos( int* nCharPos, bool* bRTL );
103
    bool    PosIsInRun( int nCharPos ) const;
103
    bool    PosIsInRun( int nCharPos ) const;
104
    bool    PosIsInAnyRun( int nCharPos ) const;
104
};
105
};
105
106
106
// -----------------
107
// -----------------
(-)OOE680_m6.fontconfig/vcl/source/gdi/outdev3.cxx (-95 / +272 lines)
Lines 168-173 Link Here
168
#include <memory>
168
#include <memory>
169
#include <algorithm>
169
#include <algorithm>
170
170
171
#include <psprint/fontmanager.hxx>
172
#include <i18npool/mslangid.hxx>
173
171
// =======================================================================
174
// =======================================================================
172
175
173
DBG_NAMEEX( OutputDevice )
176
DBG_NAMEEX( OutputDevice )
Lines 2659-2664 Link Here
2659
    }
2662
    }
2660
}
2663
}
2661
2664
2665
2666
// -----------------------------------------------------------------------
2667
2668
String GetFcSubstitute(const ImplFontSelectData &rFontSelData, std::vector<sal_Unicode> &rGlyphs)
2669
{
2670
    std::vector<String> aNames;
2671
    if( rFontSelData.GetFamilyName().Len() )
2672
    {
2673
        sal_uInt16 nIndex = 0;
2674
	String aTempName;
2675
        do
2676
        {
2677
                aTempName = GetNextFontToken(rFontSelData.GetFamilyName(), nIndex);
2678
		aNames.push_back(aTempName);
2679
        }
2680
        while (nIndex != STRING_NOTFOUND);
2681
    }
2682
2683
    ByteString aLangAttrib = MsLangId::convertLanguageToIsoByteString( rFontSelData.meLanguage );
2684
2685
    psp::italic::type eItalic = psp::italic::Unknown;
2686
    if( rFontSelData.GetSlant() != ITALIC_DONTKNOW )
2687
    {
2688
        switch( rFontSelData.GetSlant() )
2689
        {
2690
            case ITALIC_NORMAL:  eItalic = psp::italic::Italic; break;
2691
            case ITALIC_OBLIQUE: eItalic = psp::italic::Oblique; break;
2692
            default:
2693
                break;
2694
        }
2695
    }
2696
2697
    psp::weight::type eWeight = psp::weight::Unknown;
2698
    if( rFontSelData.GetWeight() != WEIGHT_DONTKNOW )
2699
    {
2700
        switch( rFontSelData.GetWeight() )
2701
        {
2702
            case WEIGHT_THIN:		eWeight = psp::weight::Thin; break;
2703
            case WEIGHT_ULTRALIGHT:	eWeight = psp::weight::UltraLight; break;
2704
            case WEIGHT_LIGHT:		eWeight = psp::weight::Light; break;
2705
            case WEIGHT_SEMILIGHT:	eWeight = psp::weight::SemiLight; break;
2706
            case WEIGHT_NORMAL:		eWeight = psp::weight::Normal; break;
2707
            case WEIGHT_MEDIUM:		eWeight = psp::weight::Medium; break;
2708
            case WEIGHT_SEMIBOLD:	eWeight = psp::weight::SemiBold; break;
2709
            case WEIGHT_BOLD:		eWeight = psp::weight::Bold; break;
2710
            case WEIGHT_ULTRABOLD:	eWeight = psp::weight::UltraBold; break;
2711
            case WEIGHT_BLACK:		eWeight = psp::weight::Black; break;
2712
            default:
2713
                break;
2714
        }
2715
    }
2716
2717
    psp::width::type eWidth = psp::width::Unknown;
2718
    if( rFontSelData.GetWidthType() != WIDTH_DONTKNOW )
2719
    {
2720
        switch( rFontSelData.GetWidthType() )
2721
        {
2722
            case WIDTH_ULTRA_CONDENSED:	eWidth = psp::width::UltraCondensed; break;
2723
            case WIDTH_EXTRA_CONDENSED: eWidth = psp::width::ExtraCondensed; break;
2724
            case WIDTH_CONDENSED:	eWidth = psp::width::Condensed; break;
2725
            case WIDTH_SEMI_CONDENSED:	eWidth = psp::width::SemiCondensed; break;
2726
            case WIDTH_NORMAL:		eWidth = psp::width::Normal; break;
2727
            case WIDTH_SEMI_EXPANDED:	eWidth = psp::width::SemiExpanded; break;
2728
            case WIDTH_EXPANDED:	eWidth = psp::width::Expanded; break;
2729
            case WIDTH_EXTRA_EXPANDED:	eWidth = psp::width::ExtraExpanded; break;
2730
            case WIDTH_ULTRA_EXPANDED:	eWidth = psp::width::UltraExpanded; break;
2731
            default:
2732
                break;
2733
        }
2734
    }
2735
2736
    psp::pitch::type ePitch = psp::pitch::Unknown;
2737
    if( rFontSelData.GetPitch() != PITCH_DONTKNOW )
2738
    {
2739
        switch(  rFontSelData.GetPitch() )
2740
        {
2741
            case PITCH_FIXED:    ePitch=psp::pitch::Fixed; break;
2742
            case PITCH_VARIABLE: ePitch=psp::pitch::Variable; break;
2743
            default:
2744
                break;
2745
        }
2746
    }
2747
2748
    const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
2749
    return rMgr.Substitute(aNames, rGlyphs, aLangAttrib, eItalic, eWeight, eWidth, ePitch);
2750
}
2751
2752
// -----------------------------------------------------------------------
2753
2754
ImplDevFontListData *ImplDevFontList::ImplGetFontconfigSubstitute( ImplFontSelectData &rFontSelData, ImplFontSubstEntry* pDevSpecific )
2755
{
2756
    // We dont' actually want to talk to Fontconfig at all for symbol fonts
2757
    if (rFontSelData.IsSymbolFont())
2758
        return 0;
2759
    // StarSymbol is a unicode font, but it still deserves the symbol flag
2760
    if( 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "starsymbol", 10)
2761
        ||  0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
2762
        return 0;
2763
2764
    std::vector<sal_Unicode> aDummy;
2765
    String aName(GetFcSubstitute(rFontSelData, aDummy));
2766
    if (!aName.Len())
2767
        return 0;
2768
2769
    String aUserName(aName);
2770
    ImplGetEnglishSearchFontName( aName );
2771
    ImplFontSubstitute( aName, FONT_SUBSTITUTE_ALWAYS, pDevSpecific );
2772
    ImplDevFontListData *pFontFamily = ImplFindBySearchName( aName );
2773
    if (pFontFamily)
2774
        rFontSelData.maTargetName = aUserName;
2775
2776
    return pFontFamily;
2777
}
2778
2779
2662
// -----------------------------------------------------------------------
2780
// -----------------------------------------------------------------------
2663
2781
2664
ImplFontEntry* ImplFontCache::Get( ImplDevFontList* pFontList,
2782
ImplFontEntry* ImplFontCache::Get( ImplDevFontList* pFontList,
Lines 2696-2703 Link Here
2696
2814
2697
    if( !pEntry ) // no direct cache hit
2815
    if( !pEntry ) // no direct cache hit
2698
    {
2816
    {
2699
        // find the best matching logical font family and update font selector accordingly
2817
        pFontFamily = pFontList->ImplGetFontconfigSubstitute( aFontSelData, pDevSpecific );
2700
        pFontFamily = pFontList->ImplFindByFont( aFontSelData, mbPrinter, pDevSpecific );
2818
        if (!pFontFamily)
2819
        {
2820
            // find the best matching logical font family and update font selector accordingly
2821
            pFontFamily = pFontList->ImplFindByFont( aFontSelData, mbPrinter, pDevSpecific );
2822
        }
2701
        DBG_ASSERT( (pFontFamily != NULL), "ImplFontCache::Get() No logical font found!" );
2823
        DBG_ASSERT( (pFontFamily != NULL), "ImplFontCache::Get() No logical font found!" );
2702
        if( pFontFamily )
2824
        if( pFontFamily )
2703
            aFontSelData.maSearchName = pFontFamily->GetSearchName();
2825
            aFontSelData.maSearchName = pFontFamily->GetSearchName();
Lines 3024-3138 Link Here
3024
// -----------------------------------------------------------------------
3146
// -----------------------------------------------------------------------
3025
3147
3026
ImplFontEntry* ImplFontCache::GetFallback( ImplDevFontList* pFontList,
3148
ImplFontEntry* ImplFontCache::GetFallback( ImplDevFontList* pFontList,
3027
    const Font& rOrigFont, const Size& rSize, int nFallbackLevel )
3149
     const Font& rOrigFont, const Size& rSize, int nFallbackLevel,
3150
     std::vector<sal_Unicode> &rMissingGlyphs )
3028
{
3151
{
3029
    // make sure the fontlist knows it's fallbacks
3152
    ImplFontEntry*      pFallbackFont = NULL;
3030
    if( !pFontList->HasFallbacks() )
3153
    bool                cached = false;
3154
    bool                new_entry = false;
3155
    bool                symbolFont = false;
3156
    ImplFontEntry*      pOrigFontEntry = Get( pFontList, rOrigFont, rSize, NULL );
3157
    ImplFontSelectData  aSelData( rOrigFont, rOrigFont.GetName(), rSize );
3158
    sal_uInt16          nToken = 0;
3159
    String              aOrigFontName( GetNextFontToken(rOrigFont.GetName(), nToken) );
3160
3161
    
3162
    const FontNameAttr* fontAttr = FontSubstConfiguration::get()->getSubstInfo( aOrigFontName );
3163
3164
    // We dont' actually want to talk to Fontconfig at all for symbol fonts
3165
    if ( pFontList && fontAttr && (fontAttr->Type & IMPL_FONT_ATTR_SYMBOL) )
3031
    {
3166
    {
3032
        // normalized family names of fonts suited for glyph fallback
3167
        if ( fontAttr->Substitutions.size() )
3033
        // if a font is available related fonts can be ignored
3034
        // TODO: implement dynamic lists
3035
        static const char* aGlyphFallbackList[] = {
3036
            // empty strings separate the names of unrelated fonts
3037
            "eudc", "",
3038
            "arialunicodems", "cyberbit", "code2000", "",
3039
            "andalesansui", "",
3040
            "starsymbol", "opensymbol", "",
3041
            "msmincho", "fzmingti", "fzheiti", "ipamincho", "sazanamimincho", "kochimincho", "",
3042
            "sunbatang", "sundotum", "baekmukdotum", "gulim", "batang", "dotum", "",
3043
            "hgmincholightj", "msunglightsc", "msunglighttc", "hymyeongjolightk", "",
3044
            "tahoma", "timesnewroman", "lucidatypewriter", "lucidasans", "nimbussansl", "",
3045
            "shree", "mangal", "raavi", "shruti", "tunga", "latha", "",
3046
            "shayyalmt", "naskmt", "",
3047
            "david", "nachlieli", "lucidagrande", "",
3048
            "norasi", "angsanaupc", "",
3049
            "khmerossystem", "",
3050
	    "phetsarathot", "",
3051
            0
3052
        };
3053
3054
        bool bHasEudc = false;
3055
        int nMaxLevel = 0;
3056
        int nBestQuality = 0;
3057
        ImplDevFontListData** pFallbackList = NULL;
3058
        for( const char** ppNames = &aGlyphFallbackList[0];; ++ppNames )
3059
        {
3168
        {
3060
            // advance to next sub-list when end-of-sublist marker
3169
            ::std::vector< String >::const_iterator it = fontAttr->Substitutions.begin();
3061
            if( !**ppNames )    // #i46456# check for empty string, i.e., deref string itself not only ptr to it
3170
            while ( it != fontAttr->Substitutions.end() )
3062
            {
3171
            {
3063
                if( nBestQuality > 0 )
3172
                // Since *it is the "search name" like "standardsymbolsl"
3064
                    if( ++nMaxLevel >= MAX_FALLBACK )
3173
                // we have to find the Family Name (Standard Symbols L) for Fontconfig
3065
                        break;
3174
                ImplDevFontListData* pFontFamily = pFontList->FindFontFamily( *it );
3066
                if( !ppNames[1] )
3175
                if (pFontFamily)
3176
                {
3177
                    aSelData.maSearchName = pFontFamily->GetFamilyName();
3067
                    break;
3178
                    break;
3068
                nBestQuality = 0;
3179
                }
3069
                continue;
3180
                ++it;
3070
            }
3181
            }
3182
        }
3183
        symbolFont = true;
3184
        cached = true;
3185
    }
3071
3186
3072
            // test if the glyph fallback candidate font is available and scalable
3187
    std::vector<sal_Unicode> aGlyphs(rMissingGlyphs);
3073
            String aTokenName( *ppNames, RTL_TEXTENCODING_UTF8 );
3074
            ImplDevFontListData* pFallbackFont = pFontList->FindFontFamily( aTokenName );
3075
            if( !pFallbackFont )
3076
                continue;
3077
            if( !pFallbackFont->IsScalable() )
3078
                continue;
3079
3188
3080
            // keep the best font of the glyph fallback sub-list
3189
    // Try cached fallbacks first
3081
            if( nBestQuality < pFallbackFont->GetMinQuality() )
3190
    if ( !symbolFont && !rMissingGlyphs.empty() )
3082
            {
3191
    {
3083
                nBestQuality = pFallbackFont->GetMinQuality();
3192
        aSelData.maSearchName = pOrigFontEntry->GetFallbackForUnicode( rMissingGlyphs[0] );
3084
                // store available glyph fallback fonts
3193
        if ( aSelData.maSearchName.Len() )
3085
                if( !pFallbackList )
3194
            cached = true;
3086
                    pFallbackList = new ImplDevFontListData*[ MAX_FALLBACK ];
3195
    }
3087
                pFallbackList[ nMaxLevel ] = pFallbackFont;
3088
                if( !bHasEudc && !nMaxLevel )
3089
                    bHasEudc = (0 == strncmp( *ppNames, "eudc", 5 ));
3090
            }
3091
        }
3092
3196
3093
        // sort the list of fonts for glyph fallback by quality (highest first)
3197
    if ( !cached )
3094
        // #i33947# keep the EUDC font at the front of the list
3198
    {
3095
        // an insertion sort is good enough for this short list
3199
        String aName;
3096
        const int nSortStart = bHasEudc ? 1 : 0;
3200
        if (nFallbackLevel != MAX_FALLBACK -1)
3097
        for( int i = nSortStart+1, j; i < nMaxLevel; ++i )
3201
            aName = GetFcSubstitute( aSelData, aGlyphs );
3098
        {
3202
        else
3099
            ImplDevFontListData* pTestFont = pFallbackList[ i ];
3203
        {
3100
            int nTestQuality = pTestFont->GetMinQuality();
3204
            /* 
3101
            for( j = i; --j >= nSortStart; )
3205
                There is no font that can handle this, to be safe let's set a font 
3102
                if( nTestQuality > pFallbackList[j]->GetMinQuality() )
3206
                which has a known working .notdef glyph
3103
                    pFallbackList[ j+1 ] = pFallbackList[ j ];
3207
            */
3104
                else
3208
            const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
3105
                    break;
3209
            std::vector<sal_Unicode> aDummy;
3106
            pFallbackList[ j+1 ] = pTestFont;
3210
            std::vector<String> aNames;
3107
        }
3211
            aNames.push_back(String(RTL_CONSTASCII_USTRINGPARAM("Sazanami Gothic")));
3212
            aName = rMgr.Substitute(aNames, aDummy, ByteString(),
3213
                psp::italic::Unknown, psp::weight::Unknown, psp::width::Unknown, psp::pitch::Unknown);
3214
            if (aName != String(RTL_CONSTASCII_USTRINGPARAM("Sazanami Gothic")))
3215
            {
3216
                aNames.clear();
3217
                aNames.push_back(OUString(RTL_CONSTASCII_USTRINGPARAM("DejaVu LGC Sans")));
3218
                aName = rMgr.Substitute(aNames, aDummy, ByteString(),
3219
                    psp::italic::Unknown, psp::weight::Unknown, psp::width::Unknown, psp::pitch::Unknown);
3220
            }
3221
        }
3222
        if (aName.Len())
3223
            aSelData.maSearchName = aName;
3224
    }
3108
3225
3109
#if defined(HDU_DEBUG)
3226
    if (!rMissingGlyphs.empty())
3110
        for( int i = 0; i < nMaxLevel; ++i )
3227
    {
3228
        std::vector<sal_Unicode>::const_iterator aEnd = aGlyphs.end();
3229
        for (std::vector<sal_Unicode>::const_iterator aI = aGlyphs.begin(); aI != aEnd; ++aI)
3111
        {
3230
        {
3112
            ImplDevFontListData* pFont = pFallbackList[ i ];
3231
            std::vector<sal_Unicode>::iterator aNewEnd = 
3113
            ByteString aFontName( pFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 );
3232
                std::remove(rMissingGlyphs.begin(), rMissingGlyphs.end(), *aI);
3114
            fprintf( stderr, "GlyphFallbackFont[%d] (quality=%05d): \"%s\"\n",
3233
            if (aNewEnd != rMissingGlyphs.end())
3115
                i, pFont->GetMinQuality(), aFontName.GetBuffer() );
3234
                rMissingGlyphs.erase(aNewEnd);
3235
            //In this case only the first missing symbol has been taken into account and is
3236
            //known safe to replace
3237
            if (cached || symbolFont)
3238
                break;
3116
        }
3239
        }
3117
#endif
3118
3119
        pFontList->SetFallbacks( pFallbackList, nMaxLevel );
3120
    }
3240
    }
3121
3241
3122
    Font aFallbackFont = rOrigFont;
3242
    // Check our font instance cache first, if not found then
3123
3243
    // add this ImplFontSelectData to the cache along with its ImplFontEntry
3124
    // nFallbackLevel==0 => original font without device specific substitution
3244
    FontInstanceList::const_iterator it = maFontInstanceList.find( aSelData );
3125
    // nFallbackLevel>=1 => use a font from the glyph fallback font list
3245
    if (it != maFontInstanceList.end())
3126
    if( nFallbackLevel>=1 )
3246
        pFallbackFont = (*it).second;
3247
    else
3127
    {
3248
    {
3128
        ImplDevFontListData* pFallbackData = pFontList->GetFallback( nFallbackLevel-1 );
3249
        // find the best matching physical font face
3129
        if( !pFallbackData )
3250
        ImplDevFontListData* pFontFamily = pFontList->FindFontFamily( aSelData.maSearchName );
3130
            return NULL;
3251
        if (pFontFamily)
3252
        {
3253
            ImplFontData* pFontData = pFontFamily->FindBestFontFace( aSelData );
3131
3254
3132
        aFallbackFont.SetName( pFallbackData->GetSearchName() );
3255
            // create a new logical font instance from this physical font face
3256
            aSelData.mpFontData = pFontData;
3257
            pFallbackFont = pFontData->CreateFontInstance( aSelData );
3258
3259
            // if we found a different symbol font we need a symbol conversion table
3260
            if( pFontData->IsSymbolFont() )
3261
                if( aSelData.maTargetName != aSelData.maSearchName )
3262
                    pFallbackFont->mpConversion = ImplGetRecodeData( aSelData.maTargetName, aSelData.maSearchName );
3263
            // add the new entry to the cache
3264
            maFontInstanceList[ aSelData ] = pFallbackFont;
3265
            new_entry = true;
3266
        }
3267
        else
3268
        {
3269
            ByteString l( aSelData.maSearchName, RTL_TEXTENCODING_UTF8 );
3270
            //fprintf (stderr, "--- Couldn't get FontFamily for '%s'\n", l.GetBuffer());
3271
        }
3133
    }
3272
    }
3134
3273
3135
    ImplFontEntry* pFallbackFont = Get( pFontList, aFallbackFont, rSize, NULL );
3274
    // Cache the fallback font for each of the missing Unicode chars
3275
    if ( !symbolFont && aSelData.maSearchName.Len() )
3276
    {
3277
        std::vector<sal_Unicode>::const_iterator aEnd = aGlyphs.end();
3278
        for (std::vector<sal_Unicode>::const_iterator aI = aGlyphs.begin(); aI != aEnd; ++aI)
3279
        {
3280
            #if 0
3281
            if (!pOrigFontEntry->GetFallbackForUnicode(*aI).Len())
3282
                pOrigFontEntry->AddFallbackForUnicode(*aI, aSelData.maSearchName);
3283
            #endif
3284
        }
3285
    }
3136
3286
3137
    if( pFallbackFont && !pFallbackFont->mbInit )
3287
    if( pFallbackFont && !pFallbackFont->mbInit )
3138
    {
3288
    {
Lines 3142-3147 Link Here
3142
        pFallbackFont->maMetric.maStyleName = String();
3270
        pFallbackFont->maMetric.maStyleName = String();
3143
    }
3271
    }
3144
3272
3273
    if ( pFallbackFont && !new_entry )
3274
    {
3275
        // increase the font instance's reference count
3276
        if( !pFallbackFont->mnRefCount++ )
3277
            --mnRef0Count;
3278
    }
3279
3280
#if 0
3281
    sal_uInt16 nTok = 0;
3282
    ByteString n( GetNextFontToken(rOrigFont.GetName(), nTok), RTL_TEXTENCODING_UTF8);
3283
    ByteString m;
3284
    if (pFallbackFont)
3285
    {
3286
        nTok = 0;
3287
        ByteString tS( GetNextFontToken(pFallbackFont->maFontSelData.mpFontData->GetFamilyName(), nTok), RTL_TEXTENCODING_UTF8 );
3288
        m.Assign( tS );
3289
    }
3290
    fprintf (stderr, "Glyph fallback '%s'->'%s' %s\n", n.GetBuffer(), pFallbackFont ? m.GetBuffer() : "none",
3291
                new_entry ? "(new)" : "(cached)");
3292
#endif
3293
3145
    return pFallbackFont;
3294
    return pFallbackFont;
3146
}
3295
}
3147
3296
Lines 6099-6105 Link Here
6099
    // do glyph fallback if needed
6248
    // do glyph fallback if needed
6100
    // #105768# avoid fallback for very small font sizes
6249
    // #105768# avoid fallback for very small font sizes
6101
    if( aLayoutArgs.NeedFallback() )
6250
    if( aLayoutArgs.NeedFallback() )
6102
        if( mpFontEntry && (mpFontEntry->maFontSelData.mnHeight >= 6) )
6251
        if( mpFontEntry && (mpFontEntry->maFontSelData.mnHeight >= 3) )
6103
            pSalLayout = ImplGlyphFallbackLayout( pSalLayout, aLayoutArgs );
6252
            pSalLayout = ImplGlyphFallbackLayout( pSalLayout, aLayoutArgs );
6104
6253
6105
    // position, justify, etc. the layout
6254
    // position, justify, etc. the layout
Lines 6143-6148 Link Here
6143
        rLayoutArgs.ResetPos();
6292
        rLayoutArgs.ResetPos();
6144
    }
6293
    }
6145
#endif
6294
#endif
6295
    int nCharPos = -1;
6296
    bool bRTL = false;
6297
    std::vector<sal_Unicode> aGlyphs;
6298
    while (rLayoutArgs.GetNextPos( &nCharPos, &bRTL))
6299
        aGlyphs.push_back(rLayoutArgs.mpStr[ nCharPos ]);
6300
    rLayoutArgs.ResetPos();
6146
6301
6147
    ImplFontSelectData aFontSelData = mpFontEntry->maFontSelData;
6302
    ImplFontSelectData aFontSelData = mpFontEntry->maFontSelData;
6148
    Size aFontSize( aFontSelData.mnWidth, aFontSelData.mnHeight );
6303
    Size aFontSize( aFontSelData.mnWidth, aFontSelData.mnHeight );
Lines 6159-6165 Link Here
6159
    {
6314
    {
6160
        // find a font family suited for glyph fallback
6315
        // find a font family suited for glyph fallback
6161
        ImplFontEntry* pFallbackFont = mpFontCache->GetFallback( mpFontList,
6316
        ImplFontEntry* pFallbackFont = mpFontCache->GetFallback( mpFontList,
6162
            maFont, aFontSize, nFallbackLevel-nDevSpecificFallback );
6317
            maFont, aFontSize, nFallbackLevel-nDevSpecificFallback, aGlyphs );
6163
        if( !pFallbackFont )
6318
        if( !pFallbackFont )
6164
            break;
6319
            break;
6165
6320
(-)OOE680_m6.fontconfig/vcl/source/gdi/sallayout.cxx (-2 / +44 lines)
Lines 456-461 Link Here
456
    return true;
456
    return true;
457
}
457
}
458
458
459
bool ImplLayoutRuns::PosIsInAnyRun( int nCharPos ) const
460
{
461
    bool bRet = false;
462
    int nRunIndex = mnRunIndex;
463
464
    ImplLayoutRuns *pThis = const_cast<ImplLayoutRuns*>(this);
465
466
    pThis->ResetPos();
467
468
    for (size_t i = 0; i < maRuns.size(); i+=2)
469
    {
470
        if ((bRet = PosIsInRun( nCharPos )))
471
            break;
472
        pThis->NextRun();
473
    }
474
475
    pThis->mnRunIndex = nRunIndex;
476
    return bRet;
477
}
478
479
459
// -----------------------------------------------------------------------
480
// -----------------------------------------------------------------------
460
481
461
bool ImplLayoutRuns::GetNextPos( int* nCharPos, bool* bRightToLeft )
482
bool ImplLayoutRuns::GetNextPos( int* nCharPos, bool* bRightToLeft )
Lines 1694-1700 Link Here
1694
    {
1715
    {
1695
        // find best fallback level
1716
        // find best fallback level
1696
        for( n = 0; n < nLevel; ++n )
1717
        for( n = 0; n < nLevel; ++n )
1697
            if( nValid[n] && !maFallbackRuns[n].PosIsInRun( nActiveCharPos ) )
1718
            if( nValid[n] && !maFallbackRuns[n].PosIsInAnyRun( nActiveCharPos ) )
1698
                // fallback level n wins when it requested no further fallback
1719
                // fallback level n wins when it requested no further fallback
1699
                break;
1720
                break;
1700
        int nFBLevel = n;
1721
        int nFBLevel = n;
Lines 1716-1722 Link Here
1716
        if( n > 0 )
1737
        if( n > 0 )
1717
        {
1738
        {
1718
            // drop the NotDef glyphs in the base layout run if a fallback run exists
1739
            // drop the NotDef glyphs in the base layout run if a fallback run exists
1719
            while( maFallbackRuns[ n-1 ].PosIsInRun( nCharPos[0] ) )
1740
            while ( 
1741
                    (maFallbackRuns[ n-1 ].PosIsInRun( nCharPos[0] ) ) &&
1742
                    (!maFallbackRuns[ n ].PosIsInAnyRun( nCharPos[0] ) )
1743
                  )
1720
            {
1744
            {
1721
                mpLayouts[0]->DropGlyph( nStartOld[0] );
1745
                mpLayouts[0]->DropGlyph( nStartOld[0] );
1722
                nStartOld[0] = nStartNew[0];
1746
                nStartOld[0] = nStartNew[0];
Lines 1736-1741 Link Here
1736
1760
1737
            // proceed to next glyph
1761
            // proceed to next glyph
1738
            nStartOld[n] = nStartNew[n];
1762
            nStartOld[n] = nStartNew[n];
1763
            int nOrigCharPos = nCharPos[n];
1739
            nValid[n] = mpLayouts[n]->GetNextGlyphs( 1, &nDummy, aPos,
1764
            nValid[n] = mpLayouts[n]->GetNextGlyphs( 1, &nDummy, aPos,
1740
                nStartNew[n], &nGlyphAdv[n], &nCharPos[n] );
1765
                nStartNew[n], &nGlyphAdv[n], &nCharPos[n] );
1741
1766
Lines 1748-1753 Link Here
1748
                break;
1773
                break;
1749
            }
1774
            }
1750
1775
1776
            //If the next character is one which belongs to the next level, then we
1777
            //are finished here for now, and we'll pick up after the next level has
1778
            //been processed
1779
            if ((n+1 < nLevel) && (nCharPos[n] != nOrigCharPos))
1780
            {
1781
                if (nOrigCharPos < nCharPos[n])
1782
                {
1783
                    if (nCharPos[n+1] > nOrigCharPos && (nCharPos[n+1] < nCharPos[n]))
1784
                        break;
1785
                }
1786
                else if (nOrigCharPos > nCharPos[n])
1787
                {
1788
                    if (nCharPos[n+1] > nCharPos[n] && (nCharPos[n+1] < nOrigCharPos))
1789
                        break;
1790
                }
1791
            }
1792
1751
            // break at end of layout run
1793
            // break at end of layout run
1752
            if( n > 0 )
1794
            if( n > 0 )
1753
            {
1795
            {
(-)OOE680_m6.fontconfig/vcl/source/glyphs/gcach_layout.cxx (+12 lines)
Lines 402-407 Link Here
402
402
403
// -----------------------------------------------------------------------
403
// -----------------------------------------------------------------------
404
404
405
static bool lcl_CharIsJoiner(sal_Unicode cChar)
406
{
407
	return ((cChar == 0x200C) || (cChar == 0x200D));
408
}
409
405
bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rArgs )
410
bool IcuLayoutEngine::operator()( ServerFontLayout& rLayout, ImplLayoutArgs& rArgs )
406
{
411
{
407
    LEUnicode* pIcuChars;
412
    LEUnicode* pIcuChars;
Lines 514-520 Link Here
514
            if( !nGlyphIndex )
519
            if( !nGlyphIndex )
515
            {
520
            {
516
                if( nCharPos >= 0 )
521
                if( nCharPos >= 0 )
522
                {
517
                    rArgs.NeedFallback( nCharPos, bRightToLeft );
523
                    rArgs.NeedFallback( nCharPos, bRightToLeft );
524
                    if ( (nCharPos > 0) && lcl_CharIsJoiner(rArgs.mpStr[nCharPos-1]) )
525
                        rArgs.NeedFallback( nCharPos-1, bRightToLeft );
526
                    else if ( (nCharPos + 1 < nEndRunPos) && lcl_CharIsJoiner(rArgs.mpStr[nCharPos+1]) )
527
                        rArgs.NeedFallback( nCharPos+1, bRightToLeft );
528
                }
529
518
                if( SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags )
530
                if( SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags )
519
                    continue;
531
                    continue;
520
            }
532
            }
(-)OOE680_m6.fontconfig/vcl/source/window/window.cxx (+5 lines)
Lines 201-206 Link Here
201
#endif
201
#endif
202
202
203
#include <vcl/pdfextoutdevdata.hxx>
203
#include <vcl/pdfextoutdevdata.hxx>
204
#include <psprint/fontmanager.hxx>
204
#include "vcl/lazydelete.hxx"
205
#include "vcl/lazydelete.hxx"
205
206
206
using namespace rtl;
207
using namespace rtl;
Lines 347-352 Link Here
347
348
348
bool Window::ImplCheckUIFont( const Font& rFont )
349
bool Window::ImplCheckUIFont( const Font& rFont )
349
{
350
{
351
    const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
352
    if (rMgr.hasFontconfig())
353
        return true;
354
350
    String aTestText;
355
    String aTestText;
351
    aTestText.Append( Button::GetStandardText( BUTTON_OK ) );
356
    aTestText.Append( Button::GetStandardText( BUTTON_OK ) );
352
    aTestText.Append( Button::GetStandardText( BUTTON_CANCEL ) );
357
    aTestText.Append( Button::GetStandardText( BUTTON_CANCEL ) );
(-)OOE680_m6.fontconfig/vcl/util/makefile.mk (-1 / +1 lines)
Lines 182-188 Link Here
182
182
183
.IF "$(USE_BUILTIN_RASTERIZER)"!=""
183
.IF "$(USE_BUILTIN_RASTERIZER)"!=""
184
    LIB1FILES +=    $(SLB)$/glyphs.lib
184
    LIB1FILES +=    $(SLB)$/glyphs.lib
185
    SHL1STDLIBS+=   $(FREETYPELIB)
185
    SHL1STDLIBS+=   $(FREETYPELIB) -lpsp$(VERSION)$(DLLPOSTFIX)
186
.ENDIF # USE_BUILTIN_RASTERIZER
186
.ENDIF # USE_BUILTIN_RASTERIZER
187
187
188
SHL1LIBS=   $(LIB1TARGET)
188
SHL1LIBS=   $(LIB1TARGET)
(-)OOE680_m6.fontconfig/psprint/inc/psprint/fontmanager.hxx (-1 / +13 lines)
Lines 49-54 Link Here
49
#ifndef _PSPRINT_HELPER_HXX_
49
#ifndef _PSPRINT_HELPER_HXX_
50
#include <psprint/helper.hxx>
50
#include <psprint/helper.hxx>
51
#endif
51
#endif
52
#ifndef _STRING_HXX
53
#include <tools/string.hxx>
54
#endif
52
55
53
#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
56
#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
54
#include <com/sun/star/lang/Locale.hpp>
57
#include <com/sun/star/lang/Locale.hpp>
Lines 413-419 Link Here
413
    std::hash_multimap< sal_Unicode, sal_uInt8 >	m_aUnicodeToAdobecode;
416
    std::hash_multimap< sal_Unicode, sal_uInt8 >	m_aUnicodeToAdobecode;
414
    std::hash_multimap< sal_uInt8, sal_Unicode >	m_aAdobecodeToUnicode;
417
    std::hash_multimap< sal_uInt8, sal_Unicode >	m_aAdobecodeToUnicode;
415
418
416
    mutable FontCache*							m_pFontCache;
419
    std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > m_aFontconfigNameToLocalized;
420
421
    mutable FontCache*                                                        m_pFontCache;
422
    bool m_bFontconfigSuccess;
423
417
    mutable std::vector< fontID >               m_aOverrideFonts;
424
    mutable std::vector< fontID >               m_aOverrideFonts;
418
        
425
        
419
    rtl::OString getAfmFile( PrintFont* pFont ) const;
426
    rtl::OString getAfmFile( PrintFont* pFont ) const;
Lines 737-742 Link Here
737
    false else
744
    false else
738
     */
745
     */
739
    bool matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale );
746
    bool matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale );
747
748
    String Substitute(const std::vector<String> &rNames, std::vector<sal_Unicode> &rGlyphs, 
749
        const ByteString &rLangAttrib, italic::type eItalic, weight::type eWeight, 
750
        width::type eWidth, pitch::type ePitch) const;
751
    bool hasFontconfig() const { return m_bFontconfigSuccess; }
740
};
752
};
741
753
742
} // namespace
754
} // namespace
(-)OOE680_m6.fontconfig/psprint/source/fontmanager/fontcache.cxx (-1 / +1 lines)
Lines 682-690 Link Here
682
        FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
682
        FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
683
        if( entry != dir->second.m_aEntries.end() )
683
        if( entry != dir->second.m_aEntries.end() )
684
        {
684
        {
685
            bSuccess = true;
686
            for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
685
            for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
687
            {
686
            {
687
                bSuccess = true;
688
                PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
688
                PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
689
                rNewFonts.push_back( pFont );
689
                rNewFonts.push_back( pFont );
690
            }
690
            }
(-)OOE680_m6.fontconfig/psprint/source/fontmanager/fontconfig.cxx (-67 / +343 lines)
Lines 47-56 Link Here
47
typedef void FcObjectSet;
47
typedef void FcObjectSet;
48
typedef void FcPattern;
48
typedef void FcPattern;
49
typedef void FcFontSet;
49
typedef void FcFontSet;
50
typedef void FcCharSet;
50
typedef int FcResult;
51
typedef int FcResult;
51
typedef int FcBool;
52
typedef int FcBool;
52
typedef int FcMatchKind;
53
typedef int FcMatchKind;
53
typedef char FcChar8;
54
typedef char FcChar8;
55
typedef sal_Int32 FcChar32;
54
#endif
56
#endif
55
57
56
#include <cstdio>
58
#include <cstdio>
Lines 74-79 Link Here
74
#ifndef _RTL_USTRBUF_HXX
76
#ifndef _RTL_USTRBUF_HXX
75
#include <rtl/ustrbuf.hxx>
77
#include <rtl/ustrbuf.hxx>
76
#endif
78
#endif
79
#ifndef _OSL_PROCESS_H_
80
#include <osl/process.h>
81
#endif
82
#ifndef _RTL_LOCALE_HXX_
83
#include <rtl/locale.hxx>
84
#endif
85
#include <utility>
86
#include <algorithm>
87
77
88
78
using namespace psp;
89
using namespace psp;
79
using namespace osl;
90
using namespace osl;
Lines 83-88 Link Here
83
{
94
{
84
    oslModule		m_pLib;
95
    oslModule		m_pLib;
85
    FcConfig*		m_pDefConfig;
96
    FcConfig*		m_pDefConfig;
97
    FcFontSet*      m_pOutlineSet;
86
98
87
	FcBool          (*m_pFcInit)();
99
	FcBool          (*m_pFcInit)();
88
    FcConfig*		(*m_pFcConfigGetCurrent)();
100
    FcConfig*		(*m_pFcConfigGetCurrent)();
Lines 91-108 Link Here
91
    FcPattern*		(*m_pFcPatternCreate)();
103
    FcPattern*		(*m_pFcPatternCreate)();
92
    void			(*m_pFcPatternDestroy)(FcPattern*);
104
    void			(*m_pFcPatternDestroy)(FcPattern*);
93
    FcFontSet*		(*m_pFcFontList)(FcConfig*,FcPattern*,FcObjectSet*);
105
    FcFontSet*		(*m_pFcFontList)(FcConfig*,FcPattern*,FcObjectSet*);
106
    FcFontSet*      (*m_pFcConfigGetFonts)(FcConfig*,FcSetName);
94
    FcFontSet*		(*m_pFcFontSetCreate)();
107
    FcFontSet*		(*m_pFcFontSetCreate)();
108
    FcCharSet*                (*m_pFcCharSetCreate)();
109
    FcBool                    (*m_pFcCharSetAddChar)(FcCharSet *, FcChar32);
110
    FcBool          (*m_pFcCharSetHasChar)(FcCharSet *, FcChar32);
111
    void            (*m_pFcCharSetDestroy)(FcCharSet*);
95
    void			(*m_pFcFontSetDestroy)(FcFontSet*);
112
    void			(*m_pFcFontSetDestroy)(FcFontSet*);
96
    FcBool			(*m_pFcFontSetAdd)(FcFontSet*,FcPattern*);
113
    FcBool			(*m_pFcFontSetAdd)(FcFontSet*,FcPattern*);
114
    void            (*m_pFcPatternReference)(FcPattern*);
115
    FcResult        (*m_pFcPatternGetCharSet)(const FcPattern*,const char*,int,FcCharSet**);
97
    FcResult		(*m_pFcPatternGetString)(const FcPattern*,const char*,int,FcChar8**);
116
    FcResult		(*m_pFcPatternGetString)(const FcPattern*,const char*,int,FcChar8**);
98
    FcResult		(*m_pFcPatternGetInteger)(const FcPattern*,const char*,int,int*);
117
    FcResult		(*m_pFcPatternGetInteger)(const FcPattern*,const char*,int,int*);
99
    FcResult		(*m_pFcPatternGetDouble)(const FcPattern*,const char*,int,double*);
118
    FcResult		(*m_pFcPatternGetDouble)(const FcPattern*,const char*,int,double*);
100
    FcResult		(*m_pFcPatternGetBool)(const FcPattern*,const char*,int,FcBool*);
119
    FcResult		(*m_pFcPatternGetBool)(const FcPattern*,const char*,int,FcBool*);
101
    void			(*m_pFcDefaultSubstitute)(FcPattern *);
120
    void			(*m_pFcDefaultSubstitute)(FcPattern *);
102
    FcPattern*		(*m_pFcFontMatch)(FcConfig*,FcPattern*,FcResult*);    
103
    FcPattern*		(*m_pFcFontSetMatch)(FcConfig*,FcFontSet**, int, FcPattern*,FcResult*);    
121
    FcPattern*		(*m_pFcFontSetMatch)(FcConfig*,FcFontSet**, int, FcPattern*,FcResult*);    
104
    FcBool			(*m_pFcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind);
122
    FcBool			(*m_pFcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind);
105
    FcBool			(*m_pFcPatternAddInteger)(FcPattern*,const char*,int);
123
    FcBool			(*m_pFcPatternAddInteger)(FcPattern*,const char*,int);
124
    FcBool                    (*m_pFcPatternAddBool)(FcPattern*,const char*,FcBool);
125
    FcBool                    (*m_pFcPatternAddCharSet)(FcPattern*,const char*,const FcCharSet*);
106
    FcBool			(*m_pFcPatternAddString)(FcPattern*,const char*,const FcChar8*);
126
    FcBool			(*m_pFcPatternAddString)(FcPattern*,const char*,const FcChar8*);
107
127
108
    oslGenericFunction loadSymbol( const char* );
128
    oslGenericFunction loadSymbol( const char* );
Lines 118-123 Link Here
118
    { return m_pLib != NULL;}
138
    { return m_pLib != NULL;}
119
139
120
    FcConfig* getDefConfig() { return m_pDefConfig; }
140
    FcConfig* getDefConfig() { return m_pDefConfig; }
141
    FcFontSet* getFontSet() { return m_pOutlineSet; }
121
142
122
    FcBool FcInit()
143
    FcBool FcInit()
123
    { return m_pFcInit(); }
144
    { return m_pFcInit(); }
Lines 147-160 Link Here
147
    
168
    
148
    FcFontSet* FcFontList( FcConfig* pConfig, FcPattern* pPattern, FcObjectSet* pSet )
169
    FcFontSet* FcFontList( FcConfig* pConfig, FcPattern* pPattern, FcObjectSet* pSet )
149
    { return m_pFcFontList( pConfig, pPattern, pSet ); }
170
    { return m_pFcFontList( pConfig, pPattern, pSet ); }
150
    
171
172
    FcFontSet* FcConfigGetFonts( FcConfig* pConfig, FcSetName eSet)
173
    { return m_pFcConfigGetFonts( pConfig, eSet ); }
174
151
    FcFontSet* FcFontSetCreate()
175
    FcFontSet* FcFontSetCreate()
152
    { return m_pFcFontSetCreate(); }
176
    { return m_pFcFontSetCreate(); }
177
178
    FcCharSet* FcCharSetCreate()
179
    { return m_pFcCharSetCreate(); }
180
181
    FcBool FcCharSetAddChar(FcCharSet *fcs, FcChar32 ucs4)
182
    { return m_pFcCharSetAddChar(fcs, ucs4); }
183
184
    FcBool FcCharSetHasChar(FcCharSet *fcs, FcChar32 ucs4)
185
    { return m_pFcCharSetHasChar(fcs, ucs4); }
186
187
    void FcCharSetDestroy( FcCharSet* pSet )
188
    { m_pFcCharSetDestroy( pSet );}
189
153
    void FcFontSetDestroy( FcFontSet* pSet )
190
    void FcFontSetDestroy( FcFontSet* pSet )
154
    { m_pFcFontSetDestroy( pSet );}
191
    { m_pFcFontSetDestroy( pSet );}
192
155
    FcBool FcFontSetAdd( FcFontSet* pSet, FcPattern* pPattern )
193
    FcBool FcFontSetAdd( FcFontSet* pSet, FcPattern* pPattern )
156
    { return m_pFcFontSetAdd( pSet, pPattern ); }
194
    { return m_pFcFontSetAdd( pSet, pPattern ); }
157
195
196
    void FcPatternReference( FcPattern* pPattern )
197
    { m_pFcPatternReference( pPattern ); }
198
199
    FcResult FcPatternGetCharSet( const FcPattern* pPattern, const char* object, int n, FcCharSet** s )
200
    { return m_pFcPatternGetCharSet( pPattern, object, n, s ); }
201
158
    FcResult FcPatternGetString( const FcPattern* pPattern, const char* object, int n, FcChar8** s )
202
    FcResult FcPatternGetString( const FcPattern* pPattern, const char* object, int n, FcChar8** s )
159
    { return m_pFcPatternGetString( pPattern, object, n, s ); }
203
    { return m_pFcPatternGetString( pPattern, object, n, s ); }
160
204
Lines 168-175 Link Here
168
    { return m_pFcPatternGetBool( pPattern, object, n, s ); }
212
    { return m_pFcPatternGetBool( pPattern, object, n, s ); }
169
    void FcDefaultSubstitute( FcPattern* pPattern )
213
    void FcDefaultSubstitute( FcPattern* pPattern )
170
    { m_pFcDefaultSubstitute( pPattern ); }
214
    { m_pFcDefaultSubstitute( pPattern ); }
171
    FcPattern* FcFontMatch( FcConfig* pConfig, FcPattern* pPattern, FcResult* pResult )
172
    { return m_pFcFontMatch( pConfig, pPattern, pResult ); }
173
    FcPattern* FcFontSetMatch( FcConfig* pConfig, FcFontSet **ppFontSet, int nset, FcPattern* pPattern, FcResult* pResult )
215
    FcPattern* FcFontSetMatch( FcConfig* pConfig, FcFontSet **ppFontSet, int nset, FcPattern* pPattern, FcResult* pResult )
174
    { return m_pFcFontSetMatch ? m_pFcFontSetMatch( pConfig, ppFontSet, nset, pPattern, pResult ) : 0; }
216
    { return m_pFcFontSetMatch ? m_pFcFontSetMatch( pConfig, ppFontSet, nset, pPattern, pResult ) : 0; }
175
    FcBool FcConfigSubstitute( FcConfig* pConfig, FcPattern* pPattern, FcMatchKind eKind )
217
    FcBool FcConfigSubstitute( FcConfig* pConfig, FcPattern* pPattern, FcMatchKind eKind )
Lines 178-183 Link Here
178
    { return m_pFcPatternAddInteger( pPattern, pObject, nValue ); }
220
    { return m_pFcPatternAddInteger( pPattern, pObject, nValue ); }
179
    FcBool FcPatternAddString( FcPattern* pPattern, const char* pObject, const FcChar8* pString )
221
    FcBool FcPatternAddString( FcPattern* pPattern, const char* pObject, const FcChar8* pString )
180
    { return m_pFcPatternAddString( pPattern, pObject, pString ); }
222
    { return m_pFcPatternAddString( pPattern, pObject, pString ); }
223
    FcBool FcPatternAddBool( FcPattern* pPattern, const char* pObject, bool nValue )
224
    { return m_pFcPatternAddBool( pPattern, pObject, nValue ); }
225
    FcBool FcPatternAddCharSet(FcPattern* pPattern,const char* pObject,const FcCharSet*pCharSet)
226
    { return m_pFcPatternAddCharSet(pPattern,pObject,pCharSet); }
181
};
227
};
182
228
183
oslGenericFunction FontCfgWrapper::loadSymbol( const char* pSymbol )
229
oslGenericFunction FontCfgWrapper::loadSymbol( const char* pSymbol )
Lines 192-198 Link Here
192
238
193
FontCfgWrapper::FontCfgWrapper()
239
FontCfgWrapper::FontCfgWrapper()
194
        : m_pLib( NULL ),
240
        : m_pLib( NULL ),
195
          m_pDefConfig( NULL )
241
          m_pDefConfig( NULL ),
242
          m_pOutlineSet( NULL )
196
{
243
{
197
#ifdef ENABLE_FONTCONFIG
244
#ifdef ENABLE_FONTCONFIG
198
    OUString aLib( RTL_CONSTASCII_USTRINGPARAM( "libfontconfig.so.1" ) );
245
    OUString aLib( RTL_CONSTASCII_USTRINGPARAM( "libfontconfig.so.1" ) );
Lines 226-237 Link Here
226
        loadSymbol( "FcPatternDestroy" );
273
        loadSymbol( "FcPatternDestroy" );
227
    m_pFcFontList = (FcFontSet*(*)(FcConfig*,FcPattern*,FcObjectSet*))
274
    m_pFcFontList = (FcFontSet*(*)(FcConfig*,FcPattern*,FcObjectSet*))
228
        loadSymbol( "FcFontList" );
275
        loadSymbol( "FcFontList" );
276
    m_pFcConfigGetFonts = (FcFontSet*(*)(FcConfig*,FcSetName))
277
        loadSymbol( "FcConfigGetFonts" );
229
    m_pFcFontSetCreate = (FcFontSet*(*)())
278
    m_pFcFontSetCreate = (FcFontSet*(*)())
230
        loadSymbol( "FcFontSetCreate" );
279
        loadSymbol( "FcFontSetCreate" );
280
    m_pFcCharSetCreate = (FcCharSet*(*)())
281
        loadSymbol( "FcCharSetCreate" );
282
    m_pFcCharSetAddChar = (FcBool(*)(FcCharSet*, FcChar32))
283
        loadSymbol( "FcCharSetAddChar" );
284
    m_pFcCharSetHasChar = (FcBool(*)(FcCharSet*, FcChar32))
285
        loadSymbol( "FcCharSetHasChar" );
286
    m_pFcCharSetDestroy = (void(*)(FcCharSet*))
287
        loadSymbol( "FcCharSetDestroy" );
231
    m_pFcFontSetDestroy = (void(*)(FcFontSet*))
288
    m_pFcFontSetDestroy = (void(*)(FcFontSet*))
232
        loadSymbol( "FcFontSetDestroy" );
289
        loadSymbol( "FcFontSetDestroy" );
233
    m_pFcFontSetAdd = (FcBool(*)(FcFontSet*,FcPattern*))
290
    m_pFcFontSetAdd = (FcBool(*)(FcFontSet*,FcPattern*))
234
        loadSymbol( "FcFontSetAdd" );
291
        loadSymbol( "FcFontSetAdd" );
292
    m_pFcPatternReference = (void(*)(FcPattern*))
293
        loadSymbol( "FcPatternReference" );
294
    m_pFcPatternGetCharSet = (FcResult(*)(const FcPattern*,const char*,int,FcCharSet**))
295
        loadSymbol( "FcPatternGetCharSet" );
235
    m_pFcPatternGetString = (FcResult(*)(const FcPattern*,const char*,int,FcChar8**))
296
    m_pFcPatternGetString = (FcResult(*)(const FcPattern*,const char*,int,FcChar8**))
236
        loadSymbol( "FcPatternGetString" );
297
        loadSymbol( "FcPatternGetString" );
237
    m_pFcPatternGetInteger = (FcResult(*)(const FcPattern*,const char*,int,int*))
298
    m_pFcPatternGetInteger = (FcResult(*)(const FcPattern*,const char*,int,int*))
Lines 242-255 Link Here
242
        loadSymbol( "FcPatternGetBool" );
303
        loadSymbol( "FcPatternGetBool" );
243
    m_pFcDefaultSubstitute = (void(*)(FcPattern *))
304
    m_pFcDefaultSubstitute = (void(*)(FcPattern *))
244
        loadSymbol( "FcDefaultSubstitute" );
305
        loadSymbol( "FcDefaultSubstitute" );
245
    m_pFcFontMatch = (FcPattern*(*)(FcConfig*,FcPattern*,FcResult*))
246
        loadSymbol( "FcFontMatch" );
247
    m_pFcFontSetMatch = (FcPattern*(*)(FcConfig*,FcFontSet**,int,FcPattern*,FcResult*))
306
    m_pFcFontSetMatch = (FcPattern*(*)(FcConfig*,FcFontSet**,int,FcPattern*,FcResult*))
248
        loadSymbol( "FcFontSetMatch" );
307
        loadSymbol( "FcFontSetMatch" );
249
    m_pFcConfigSubstitute = (FcBool(*)(FcConfig*,FcPattern*,FcMatchKind))
308
    m_pFcConfigSubstitute = (FcBool(*)(FcConfig*,FcPattern*,FcMatchKind))
250
        loadSymbol( "FcConfigSubstitute" );
309
        loadSymbol( "FcConfigSubstitute" );
251
    m_pFcPatternAddInteger = (FcBool(*)(FcPattern*,const char*,int))
310
    m_pFcPatternAddInteger = (FcBool(*)(FcPattern*,const char*,int))
252
        loadSymbol( "FcPatternAddInteger" );
311
        loadSymbol( "FcPatternAddInteger" );
312
    m_pFcPatternAddBool = (FcBool(*)(FcPattern*,const char*,FcBool))
313
        loadSymbol( "FcPatternAddBool" );
314
    m_pFcPatternAddCharSet = (FcBool(*)(FcPattern*,const char*,const FcCharSet *))
315
        loadSymbol( "FcPatternAddCharSet" );
253
    m_pFcPatternAddString = (FcBool(*)(FcPattern*,const char*,const FcChar8*))
316
    m_pFcPatternAddString = (FcBool(*)(FcPattern*,const char*,const FcChar8*))
254
        loadSymbol( "FcPatternAddString" );
317
        loadSymbol( "FcPatternAddString" );
255
318
Lines 261-277 Link Here
261
            m_pFcPatternCreate				&&
324
            m_pFcPatternCreate				&&
262
            m_pFcPatternDestroy				&&
325
            m_pFcPatternDestroy				&&
263
            m_pFcFontList					&&
326
            m_pFcFontList					&&
327
            m_pFcConfigGetFonts             &&
264
            m_pFcFontSetCreate				&&
328
            m_pFcFontSetCreate				&&
329
            m_pFcCharSetCreate				&&
330
            m_pFcCharSetAddChar 			&&
331
            m_pFcCharSetHasChar             &&
332
            m_pFcCharSetDestroy             &&
265
            m_pFcFontSetDestroy				&&
333
            m_pFcFontSetDestroy				&&
266
            m_pFcFontSetAdd					&&
334
            m_pFcFontSetAdd					&&
335
            m_pFcPatternReference           &&
336
			m_pFcPatternGetCharSet			&&
267
            m_pFcPatternGetString			&&
337
            m_pFcPatternGetString			&&
268
            m_pFcPatternGetInteger			&&
338
            m_pFcPatternGetInteger			&&
269
            m_pFcPatternGetDouble			&&
339
            m_pFcPatternGetDouble			&&
270
            m_pFcPatternGetBool				&&
340
            m_pFcPatternGetBool				&&
271
            m_pFcDefaultSubstitute			&&
341
            m_pFcDefaultSubstitute			&&
272
            m_pFcFontMatch					&&
273
            m_pFcConfigSubstitute			&&
342
            m_pFcConfigSubstitute			&&
274
            m_pFcPatternAddInteger			&&
343
            m_pFcPatternAddInteger			&&
344
            m_pFcPatternAddCharSet			&&
345
            m_pFcPatternAddBool 			&&
275
            m_pFcPatternAddString
346
            m_pFcPatternAddString
276
            ) )
347
            ) )
277
    {
348
    {
Lines 289-298 Link Here
289
        osl_unloadModule( (oslModule)m_pLib );
360
        osl_unloadModule( (oslModule)m_pLib );
290
        m_pLib = NULL;
361
        m_pLib = NULL;
291
    }
362
    }
363
364
    m_pOutlineSet = FcFontSetCreate();
365
366
    /*
367
      add only acceptable outlined fonts to our config, 
368
      for future fontconfig use
369
    */
370
    FcFontSet *pOrig = FcConfigGetFonts(NULL, FcSetSystem);
371
372
    if (!pOrig)
373
        return;
374
375
    for( int i = 0; i < pOrig->nfont; ++i )
376
    {
377
        FcBool outline = false;
378
        FcPattern *pOutlinePattern = pOrig->fonts[i];
379
        FcResult eOutRes = 
380
			FcPatternGetBool( pOutlinePattern, FC_OUTLINE, 0, &outline );
381
        if (eOutRes == FcResultMatch && !outline)
382
            continue;
383
        FcPatternReference(pOutlinePattern);
384
        FcFontSetAdd(m_pOutlineSet, pOutlinePattern);
385
    }
292
}
386
}
293
387
294
FontCfgWrapper::~FontCfgWrapper()
388
FontCfgWrapper::~FontCfgWrapper()
295
{
389
{
390
	if( m_pOutlineSet )
391
		FcFontSetDestroy( m_pOutlineSet );
296
    if( m_pLib )
392
    if( m_pLib )
297
        osl_unloadModule( (oslModule)m_pLib );
393
        osl_unloadModule( (oslModule)m_pLib );
298
}
394
}
Lines 319-324 Link Here
319
#define FC_EMBEDDED_BITMAP "embeddedbitmap"
415
#define FC_EMBEDDED_BITMAP "embeddedbitmap"
320
#endif
416
#endif
321
417
418
namespace
419
{
420
    typedef std::pair<FcChar8*, FcChar8*> lang_and_family;
421
422
    class localizedsorter
423
    {
424
            rtl::OLocale maLoc;
425
        public:
426
            localizedsorter(rtl_Locale* pLoc) : maLoc(pLoc) {}
427
            FcChar8* bestname(const std::vector<lang_and_family> &families);
428
    };
429
430
    FcChar8* localizedsorter::bestname(const std::vector<lang_and_family> &families)
431
    {
432
        FcChar8* candidate = families.begin()->second;
433
        rtl::OString sLangMatch(rtl::OUStringToOString(maLoc.getLanguage().toAsciiLowerCase(), RTL_TEXTENCODING_UTF8));
434
        rtl::OString sFullMatch = sLangMatch;
435
        sFullMatch += OString('-');
436
        sFullMatch += rtl::OUStringToOString(maLoc.getCountry().toAsciiLowerCase(), RTL_TEXTENCODING_UTF8);
437
438
        std::vector<lang_and_family>::const_iterator aEnd = families.end();
439
        bool alreadyclosematch = false;
440
        for (std::vector<lang_and_family>::const_iterator aIter = families.begin(); aIter != aEnd; ++aIter)
441
        {
442
            const char *pLang = (const char*)aIter->first;
443
            //perfect
444
            if (strcmp(pLang, sFullMatch.getStr()) == 0)
445
            {
446
                candidate = aIter->second;
447
                break;
448
            }
449
            else if ((strcmp(pLang, sLangMatch.getStr()) == 0) && (!alreadyclosematch))
450
            {
451
                candidate = aIter->second;
452
                alreadyclosematch = true;
453
            }
454
        }
455
456
        return candidate;
457
    }
458
459
460
    FcResult lcl_FamilyFromPattern(FontCfgWrapper& rWrapper, FcPattern* pPattern, FcChar8 **family, 
461
        std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash > &aFontconfigNameToLocalized)
462
    {
463
	FcChar8 *origfamily;
464
        FcResult eFamilyRes	= rWrapper.FcPatternGetString( pPattern, FC_FAMILY, 0, &origfamily );
465
        *family = origfamily;
466
467
        if( eFamilyRes == FcResultMatch)
468
        {
469
            FcChar8* familylang = NULL;
470
            if (rWrapper.FcPatternGetString( pPattern, FC_FAMILYLANG, 0, &familylang ) == FcResultMatch)
471
            {
472
                std::vector< lang_and_family > lang_and_families;
473
                lang_and_families.push_back(lang_and_family(familylang, *family));
474
                int k = 1;
475
                while (1)
476
                {
477
                    if (rWrapper.FcPatternGetString( pPattern, FC_FAMILYLANG, k, &familylang ) != FcResultMatch)
478
                        break;
479
                    if (rWrapper.FcPatternGetString( pPattern, FC_FAMILY, k, family ) != FcResultMatch)
480
                        break;
481
                    lang_and_families.push_back(lang_and_family(familylang, *family));
482
                    ++k;
483
                }
484
485
                //possible to-do, sort by UILocale instead of process locale
486
                rtl_Locale* pLoc;
487
                osl_getProcessLocale(&pLoc);
488
                localizedsorter aSorter(pLoc);
489
                *family = aSorter.bestname(lang_and_families);
490
                
491
		 std::vector<lang_and_family>::const_iterator aEnd = lang_and_families.end();
492
		 for (std::vector<lang_and_family>::const_iterator aIter = lang_and_families.begin(); aIter != aEnd; ++aIter)
493
		 {
494
		     const char *candidate = (const char*)(aIter->second);
495
		     if (strcmp(candidate, (const char*)(*family)) != 0)
496
		         aFontconfigNameToLocalized[OString(candidate)] = OString((const char*)(*family));
497
		 }
498
            }
499
        }
500
501
        return eFamilyRes;
502
    }
503
}
504
505
322
/*
506
/*
323
 * PrintFontManager::initFontconfig
507
 * PrintFontManager::initFontconfig
324
 */
508
 */
Lines 331-350 Link Here
331
    if( ! rWrapper.isValid() )
505
    if( ! rWrapper.isValid() )
332
        return false;
506
        return false;
333
507
334
    FcConfig* pConfig = rWrapper.getDefConfig();
508
    FcFontSet* pFSet = rWrapper.getFontSet();
335
    FcObjectSet* pOSet = rWrapper.FcObjectSetBuild( FC_FAMILY,
336
                                                    FC_STYLE,
337
                                                    FC_SLANT,
338
                                                    FC_WEIGHT,
339
                                                    FC_SPACING,
340
                                                    FC_FILE,
341
                                                    FC_OUTLINE,
342
                                                    FC_INDEX,
343
                                                    FC_EMBEDDED_BITMAP,
344
                                                    FC_ANTIALIAS,
345
                                                    (void *) NULL );
346
    FcPattern* pPattern = rWrapper.FcPatternCreate();
347
    FcFontSet* pFSet = rWrapper.FcFontList( pConfig, pPattern, pOSet );
348
509
349
    if( pFSet )
510
    if( pFSet )
350
    {
511
    {
Lines 363-369 Link Here
363
            FcBool outline = false, embitmap = true, antialias = true;
524
            FcBool outline = false, embitmap = true, antialias = true;
364
            
525
            
365
            FcResult eFileRes	      = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_FILE, 0, &file );
526
            FcResult eFileRes	      = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_FILE, 0, &file );
366
            FcResult eFamilyRes	      = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_FAMILY, 0, &family );
527
            FcResult eFamilyRes       = lcl_FamilyFromPattern(rWrapper, pFSet->fonts[i], &family, m_aFontconfigNameToLocalized );
367
            FcResult eStyleRes	      = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_STYLE, 0, &style );
528
            FcResult eStyleRes	      = rWrapper.FcPatternGetString( pFSet->fonts[i], FC_STYLE, 0, &style );
368
            FcResult eSlantRes	      = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_SLANT, 0, &slant );
529
            FcResult eSlantRes	      = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_SLANT, 0, &slant );
369
            FcResult eWeightRes	      = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_WEIGHT, 0, &weight );
530
            FcResult eWeightRes	      = rWrapper.FcPatternGetInteger( pFSet->fonts[i], FC_WEIGHT, 0, &weight );
Lines 389-394 Link Here
389
                     );
550
                     );
390
#endif
551
#endif
391
552
553
            OSL_ASSERT(eOutRes != FcResultMatch || outline);
554
392
            // only outline fonts are usable to psprint anyway
555
            // only outline fonts are usable to psprint anyway
393
            if( eOutRes == FcResultMatch && ! outline )
556
            if( eOutRes == FcResultMatch && ! outline )
394
                continue;
557
                continue;
Lines 542-555 Link Here
542
        }
705
        }
543
    }
706
    }
544
    
707
    
545
    // cleanup
546
    if( pPattern )
547
        rWrapper.FcPatternDestroy( pPattern );
548
    if( pFSet )
549
        rWrapper.FcFontSetDestroy( pFSet );
550
    if( pOSet )
551
        rWrapper.FcObjectSetDestroy( pOSet );
552
    
553
    // how does one get rid of the config ?
708
    // how does one get rid of the config ?
554
#if OSL_DEBUG_LEVEL > 1
709
#if OSL_DEBUG_LEVEL > 1
555
    fprintf( stderr, "inserted %d fonts from fontconfig\n", nFonts );
710
    fprintf( stderr, "inserted %d fonts from fontconfig\n", nFonts );
Lines 563-601 Link Here
563
    FontCfgWrapper::release();
718
    FontCfgWrapper::release();
564
}
719
}
565
720
566
bool PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale )
721
static void addtopattern(FontCfgWrapper& rWrapper, FcPattern *pPattern, 
722
	italic::type eItalic, weight::type eWeight, width::type eWidth, pitch::type ePitch)
567
{
723
{
568
#ifdef ENABLE_FONTCONFIG
724
#ifdef ENABLE_FONTCONFIG
569
    FontCfgWrapper& rWrapper = FontCfgWrapper::get();
725
    if( eItalic != italic::Unknown )
570
    if( ! rWrapper.isValid() )
571
        return false;
572
573
    FcConfig* pConfig = rWrapper.getDefConfig();
574
    FcPattern* pPattern = rWrapper.FcPatternCreate();
575
576
    OString aLangAttrib;
577
    // populate pattern with font characteristics
578
    if( rLocale.Language.getLength() )
579
    {
580
        OUStringBuffer aLang(6);
581
        aLang.append( rLocale.Language );
582
        if( rLocale.Country.getLength() )
583
        {
584
            aLang.append( sal_Unicode('-') );
585
            aLang.append( rLocale.Country );
586
        }
587
        aLangAttrib = OUStringToOString( aLang.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
588
    }
589
    if( aLangAttrib.getLength() )
590
        rWrapper.FcPatternAddString( pPattern, FC_LANG, (FcChar8*)aLangAttrib.getStr() );
591
592
    OString aFamily = OUStringToOString( rInfo.m_aFamilyName, RTL_TEXTENCODING_UTF8 );
593
    if( aFamily.getLength() )
594
        rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)aFamily.getStr() );
595
    if( rInfo.m_eItalic != italic::Unknown )
596
    {
726
    {
597
        int nSlant = FC_SLANT_ROMAN;
727
        int nSlant = FC_SLANT_ROMAN;
598
        switch( rInfo.m_eItalic )
728
        switch( eItalic )
599
        {
729
        {
600
            case italic::Italic:	 	nSlant = FC_SLANT_ITALIC;break;
730
            case italic::Italic:	 	nSlant = FC_SLANT_ITALIC;break;
601
            case italic::Oblique:	 	nSlant = FC_SLANT_OBLIQUE;break;
731
            case italic::Oblique:	 	nSlant = FC_SLANT_OBLIQUE;break;
Lines 604-613 Link Here
604
        }
734
        }
605
        rWrapper.FcPatternAddInteger( pPattern, FC_SLANT, nSlant );
735
        rWrapper.FcPatternAddInteger( pPattern, FC_SLANT, nSlant );
606
    }
736
    }
607
    if( rInfo.m_eWeight != weight::Unknown )
737
    if( eWeight != weight::Unknown )
608
    {
738
    {
609
        int nWeight = FC_WEIGHT_NORMAL;
739
        int nWeight = FC_WEIGHT_NORMAL;
610
        switch( rInfo.m_eWeight )
740
        switch( eWeight )
611
        {
741
        {
612
            case weight::Thin:			nWeight = FC_WEIGHT_THIN;break;
742
            case weight::Thin:			nWeight = FC_WEIGHT_THIN;break;
613
            case weight::UltraLight:	nWeight = FC_WEIGHT_ULTRALIGHT;break;
743
            case weight::UltraLight:	nWeight = FC_WEIGHT_ULTRALIGHT;break;
Lines 624-633 Link Here
624
        }
754
        }
625
        rWrapper.FcPatternAddInteger( pPattern, FC_WEIGHT, nWeight );
755
        rWrapper.FcPatternAddInteger( pPattern, FC_WEIGHT, nWeight );
626
    }
756
    }
627
    if( rInfo.m_eWidth != width::Unknown )
757
    if( eWidth != width::Unknown )
628
    {
758
    {
629
        int nWidth = FC_WIDTH_NORMAL;
759
        int nWidth = FC_WIDTH_NORMAL;
630
        switch( rInfo.m_eWidth )
760
        switch( eWidth )
631
        {
761
        {
632
            case width::UltraCondensed:	nWidth = FC_WIDTH_ULTRACONDENSED;break;
762
            case width::UltraCondensed:	nWidth = FC_WIDTH_ULTRACONDENSED;break;
633
            case width::ExtraCondensed: nWidth = FC_WIDTH_EXTRACONDENSED;break;
763
            case width::ExtraCondensed: nWidth = FC_WIDTH_EXTRACONDENSED;break;
Lines 643-652 Link Here
643
        }
773
        }
644
        rWrapper.FcPatternAddInteger( pPattern, FC_WIDTH, nWidth );
774
        rWrapper.FcPatternAddInteger( pPattern, FC_WIDTH, nWidth );
645
    }
775
    }
646
    if( rInfo.m_ePitch != pitch::Unknown )
776
    if( ePitch != pitch::Unknown )
647
    {
777
    {
648
        int nSpacing = FC_PROPORTIONAL;
778
        int nSpacing = FC_PROPORTIONAL;
649
        switch( rInfo.m_ePitch )
779
        switch( ePitch )
650
        {
780
        {
651
            case pitch::Fixed:			nSpacing = FC_MONO;break;
781
            case pitch::Fixed:			nSpacing = FC_MONO;break;
652
            case pitch::Variable:		nSpacing = FC_PROPORTIONAL;break;
782
            case pitch::Variable:		nSpacing = FC_PROPORTIONAL;break;
Lines 654-665 Link Here
654
                break;
784
                break;
655
        }
785
        }
656
        rWrapper.FcPatternAddInteger( pPattern, FC_SPACING, nSpacing );
786
        rWrapper.FcPatternAddInteger( pPattern, FC_SPACING, nSpacing );
787
        if (nSpacing == FC_MONO)
788
            rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)"monospace");
657
    }
789
    }
790
#endif
791
}
792
793
String PrintFontManager::Substitute(const std::vector<String> &rNames, std::vector<sal_Unicode> &rGlyphs,
794
        const ByteString &rLangAttrib, italic::type eItalic, weight::type eWeight,
795
        width::type eWidth, pitch::type ePitch) const
796
{
797
    String aName;
798
#ifdef ENABLE_FONTCONFIG
799
    FontCfgWrapper& rWrapper = FontCfgWrapper::get();
800
    if( ! rWrapper.isValid() )
801
        return aName;
802
803
    FcFontSet*  pSet = NULL;
804
    FcPattern*  pPattern = rWrapper.FcPatternCreate();
805
806
    // Prefer scalable fonts
807
    rWrapper.FcPatternAddBool( pPattern, FC_SCALABLE, 1 );
808
809
    std::vector<String>::const_iterator aEnd = rNames.end();
810
    for (std::vector<String>::const_iterator aIter = rNames.begin(); aIter != aEnd; ++aIter)
811
    {
812
	    OString maTargetName = OUStringToOString(*aIter, RTL_TEXTENCODING_UTF8);
813
        rWrapper.FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*)maTargetName.getStr());
814
        break;
815
    }
816
817
    if( rLangAttrib.Len() )
818
        rWrapper.FcPatternAddString(pPattern, FC_LANG, (FcChar8*)rLangAttrib.GetBuffer());
819
820
    // Add required Unicode characters, if any
821
    if (! rGlyphs.empty() )
822
    {
823
       FcCharSet *unicodes = rWrapper.FcCharSetCreate();
824
	    std::vector<sal_Unicode>::const_iterator aGlyphEnd = rGlyphs.end();
825
	    for (std::vector<sal_Unicode>::const_iterator aGlyphIter = rGlyphs.begin(); 
826
            aGlyphIter != aGlyphEnd; ++aGlyphIter)
827
	    {
828
            rWrapper.FcCharSetAddChar( unicodes, (FcChar32)*aGlyphIter );
829
	    }
830
       rWrapper.FcPatternAddCharSet( pPattern, FC_CHARSET, unicodes);
831
       rWrapper.FcCharSetDestroy( unicodes );
832
    }
833
834
    addtopattern(rWrapper, pPattern, eItalic, eWeight, eWidth, ePitch);
835
836
    rWrapper.FcConfigSubstitute( NULL, pPattern, FcMatchPattern );
837
    rWrapper.FcDefaultSubstitute( pPattern );
838
    FcResult eResult = FcResultNoMatch;
839
    FcFontSet *pFontSet = rWrapper.getFontSet();
840
    FcPattern* pResult = rWrapper.FcFontSetMatch( NULL, &pFontSet, 1, pPattern, &eResult );
841
    rWrapper.FcPatternDestroy( pPattern );
842
843
    if( pResult )
844
    {
845
        pSet = rWrapper.FcFontSetCreate();
846
        // info: destroying the pSet destroys pResult implicitly
847
        // since pResult was "added" to pSet
848
        rWrapper.FcFontSetAdd( pSet, pResult );
849
    }
850
851
    if( pSet )
852
    {
853
        if( pSet->nfont > 0 )
854
        {
855
            //extract the closest match
856
            FcChar8* family = NULL;
857
            FcResult eFileRes = rWrapper.FcPatternGetString( pSet->fonts[0], FC_FAMILY, 0, &family );
858
859
            if( eFileRes == FcResultMatch )
860
            {
861
                OString sFamily((sal_Char*)family);
862
                std::hash_map< rtl::OString, rtl::OString, rtl::OStringHash >::const_iterator aI = m_aFontconfigNameToLocalized.find(sFamily);
863
                if (aI != m_aFontconfigNameToLocalized.end())
864
                    sFamily = aI->second;
865
                aName = String( sFamily.getStr(), RTL_TEXTENCODING_UTF8 );
866
            }
867
868
            if (!rGlyphs.empty() )
869
            {
870
		std::vector<sal_Unicode> aGlyphs;
871
                FcCharSet *unicodes;
872
                if (rWrapper.FcPatternGetCharSet(pSet->fonts[0], FC_CHARSET, 0, &unicodes) == FcResultMatch)
873
                {
874
                    std::vector<sal_Unicode>::iterator aGlyphEnd = rGlyphs.end();
875
                    for (std::vector<sal_Unicode>::iterator aGlyphIter = rGlyphs.begin();
876
                        aGlyphIter != aGlyphEnd; ++aGlyphIter)
877
                    {
878
                            if (rWrapper.FcCharSetHasChar( unicodes, (FcChar32)*aGlyphIter ))
879
				aGlyphs.push_back(*aGlyphIter);
880
                    }
881
                }
882
		rGlyphs.swap(aGlyphs);
883
            }
884
885
        }
886
    }
887
    rWrapper.FcFontSetDestroy( pSet );
888
#endif
889
    return aName;
890
}
891
892
bool PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale )
893
{
894
#ifdef ENABLE_FONTCONFIG
895
    FontCfgWrapper& rWrapper = FontCfgWrapper::get();
896
    if( ! rWrapper.isValid() )
897
        return false;
898
899
    FcConfig* pConfig = rWrapper.getDefConfig();
900
    FcPattern* pPattern = rWrapper.FcPatternCreate();
901
902
    OString aLangAttrib;
903
    // populate pattern with font characteristics
904
    if( rLocale.Language.getLength() )
905
    {
906
        OUStringBuffer aLang(6);
907
        aLang.append( rLocale.Language );
908
        if( rLocale.Country.getLength() )
909
        {
910
            aLang.append( sal_Unicode('-') );
911
            aLang.append( rLocale.Country );
912
        }
913
        aLangAttrib = OUStringToOString( aLang.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
914
    }
915
    if( aLangAttrib.getLength() )
916
        rWrapper.FcPatternAddString( pPattern, FC_LANG, (FcChar8*)aLangAttrib.getStr() );
917
918
    OString aFamily = OUStringToOString( rInfo.m_aFamilyName, RTL_TEXTENCODING_UTF8 );
919
    if( aFamily.getLength() )
920
        rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)aFamily.getStr() );
921
922
    addtopattern(rWrapper, pPattern, rInfo.m_eItalic, rInfo.m_eWeight, rInfo.m_eWidth, rInfo.m_ePitch);
658
923
659
    rWrapper.FcConfigSubstitute( pConfig, pPattern, FcMatchPattern );
924
    rWrapper.FcConfigSubstitute( pConfig, pPattern, FcMatchPattern );
660
    rWrapper.FcDefaultSubstitute( pPattern );
925
    rWrapper.FcDefaultSubstitute( pPattern );
661
    FcResult eResult = FcResultNoMatch;
926
    FcResult eResult = FcResultNoMatch;
662
    FcPattern* pResult = rWrapper.FcFontMatch( pConfig, pPattern, &eResult );
927
    FcFontSet *pFontSet = rWrapper.getFontSet();
928
    FcPattern* pResult = rWrapper.FcFontSetMatch( pConfig, &pFontSet, 1, pPattern, &eResult );
663
    bool bSuccess = false;
929
    bool bSuccess = false;
664
    if( pResult )
930
    if( pResult )
665
    {
931
    {
(-)OOE680_m6.fontconfig/psprint/source/fontmanager/fontmanager.cxx (-4 / +5 lines)
Lines 1165-1171 Link Here
1165
        m_nNextFontID( 1 ),
1165
        m_nNextFontID( 1 ),
1166
        m_pAtoms( new MultiAtomProvider() ),
1166
        m_pAtoms( new MultiAtomProvider() ),
1167
        m_nNextDirAtom( 1 ),
1167
        m_nNextDirAtom( 1 ),
1168
        m_pFontCache( NULL )
1168
        m_pFontCache( NULL ),
1169
	m_bFontconfigSuccess(false)
1169
{
1170
{
1170
    for( unsigned int i = 0; i < sizeof( aAdobeCodes )/sizeof( aAdobeCodes[0] ); i++ )
1171
    for( unsigned int i = 0; i < sizeof( aAdobeCodes )/sizeof( aAdobeCodes[0] ); i++ )
1171
    {
1172
    {
Lines 2124-2130 Link Here
2124
#endif
2125
#endif
2125
2126
2126
    // first try fontconfig
2127
    // first try fontconfig
2127
    bool bFontconfigSuccess = initFontconfig();
2128
    m_bFontconfigSuccess = initFontconfig();
2128
2129
2129
    // part one - look for downloadable fonts
2130
    // part one - look for downloadable fonts
2130
    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
2131
    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
Lines 2146-2152 Link Here
2146
    }
2147
    }
2147
2148
2148
    // don't search through many directories fontconfig already told us about
2149
    // don't search through many directories fontconfig already told us about
2149
    if( ! bFontconfigSuccess )
2150
    if( ! m_bFontconfigSuccess )
2150
    {							
2151
    {							
2151
        Display *pDisplay = (Display*)pInitDisplay;
2152
        Display *pDisplay = (Display*)pInitDisplay;
2152
        
2153
        
Lines 2239-2245 Link Here
2239
            }
2240
            }
2240
        }
2241
        }
2241
#endif /* SOLARIS */
2242
#endif /* SOLARIS */
2242
    } // ! bFontconfigSuccess
2243
    } // ! m_bFontconfigSuccess
2243
2244
2244
    // fill XLFD aliases from fonts.alias files
2245
    // fill XLFD aliases from fonts.alias files
2245
    initFontsAlias();
2246
    initFontsAlias();
(-)openoffice.org.orig/vcl/inc/vcl/sallayout.hxx (+3 lines)
Lines 281-286 Link Here
281
    ImplFontData*	 GetFallbackFontData( int nFallbackLevel ) const
281
    ImplFontData*	 GetFallbackFontData( int nFallbackLevel ) const
282
    { return mpFallbackFonts[ nFallbackLevel ]; }
282
    { return mpFallbackFonts[ nFallbackLevel ]; }
283
283
284
    void SetInComplete(bool bInComplete = true);
285
284
protected:
286
protected:
285
    virtual         ~MultiSalLayout();
287
    virtual         ~MultiSalLayout();
286
288
Lines 299-304 Link Here
299
    ImplFontData*	mpFallbackFonts[ MAX_FALLBACK ];
301
    ImplFontData*	mpFallbackFonts[ MAX_FALLBACK ];
300
    ImplLayoutRuns  maFallbackRuns[ MAX_FALLBACK ];
302
    ImplLayoutRuns  maFallbackRuns[ MAX_FALLBACK ];
301
    int             mnLevel;
303
    int             mnLevel;
304
    bool            mbInComplete;
302
};
305
};
303
306
304
// --------------------
307
// --------------------
(-)openoffice.org.orig/vcl/source/gdi/outdev3.cxx (-1 / +10 lines)
Lines 6320-6326 Link Here
6320
6320
6321
        aFontSelData.mpFontEntry = pFallbackFont;
6321
        aFontSelData.mpFontEntry = pFallbackFont;
6322
        aFontSelData.mpFontData = pFallbackFont->maFontSelData.mpFontData;
6322
        aFontSelData.mpFontData = pFallbackFont->maFontSelData.mpFontData;
6323
        if( mpFontEntry )
6323
        if( mpFontEntry && nFallbackLevel < MAX_FALLBACK-1)
6324
        {
6324
        {
6325
            // ignore fallback font if it is the same as the original font
6325
            // ignore fallback font if it is the same as the original font
6326
            if( mpFontEntry->maFontSelData.mpFontData == aFontSelData.mpFontData )
6326
            if( mpFontEntry->maFontSelData.mpFontData == aFontSelData.mpFontData )
Lines 6348-6362 Link Here
6348
        SalLayout* pFallback = mpGraphics->GetTextLayout( rLayoutArgs, nFallbackLevel );
6348
        SalLayout* pFallback = mpGraphics->GetTextLayout( rLayoutArgs, nFallbackLevel );
6349
        if( pFallback )
6349
        if( pFallback )
6350
        {
6350
        {
6351
            int nTemp = rLayoutArgs.mnFlags;
6352
6353
            if (nFallbackLevel == MAX_FALLBACK-1)
6354
                rLayoutArgs.mnFlags = rLayoutArgs.mnFlags ^= SAL_LAYOUT_FOR_FALLBACK;
6355
6351
            if( pFallback->LayoutText( rLayoutArgs ) )
6356
            if( pFallback->LayoutText( rLayoutArgs ) )
6352
            {
6357
            {
6353
                if( !pMultiSalLayout )
6358
                if( !pMultiSalLayout )
6354
                    pMultiSalLayout = new MultiSalLayout( *pSalLayout );
6359
                    pMultiSalLayout = new MultiSalLayout( *pSalLayout );
6355
                pMultiSalLayout->AddFallback( *pFallback,
6360
                pMultiSalLayout->AddFallback( *pFallback,
6356
                    rLayoutArgs.maRuns, aFontSelData.mpFontData );
6361
                    rLayoutArgs.maRuns, aFontSelData.mpFontData );
6362
                if (nFallbackLevel == MAX_FALLBACK-1)
6363
                    pMultiSalLayout->SetInComplete();
6357
            }
6364
            }
6358
            else
6365
            else
6359
                pFallback->Release();
6366
                pFallback->Release();
6367
6368
            rLayoutArgs.mnFlags = nTemp;
6360
        }
6369
        }
6361
6370
6362
        mpFontCache->Release( pFallbackFont );
6371
        mpFontCache->Release( pFallbackFont );
(-)openoffice.org.orig/vcl/source/gdi/sallayout.cxx (-3 / +16 lines)
Lines 1561-1573 Link Here
1561
1561
1562
MultiSalLayout::MultiSalLayout( SalLayout& rBaseLayout )
1562
MultiSalLayout::MultiSalLayout( SalLayout& rBaseLayout )
1563
:   SalLayout(),
1563
:   SalLayout(),
1564
    mnLevel( 1 )
1564
    mnLevel( 1 ),
1565
    mbInComplete( false )
1565
{
1566
{
1566
    //maFallbackRuns[0].Clear();
1567
    //maFallbackRuns[0].Clear();
1567
    mpLayouts[ 0 ]  = &rBaseLayout;
1568
    mpLayouts[ 0 ]  = &rBaseLayout;
1568
    mnUnitsPerPixel = rBaseLayout.GetUnitsPerPixel();
1569
    mnUnitsPerPixel = rBaseLayout.GetUnitsPerPixel();
1569
}
1570
}
1570
1571
1572
void MultiSalLayout::SetInComplete(bool bInComplete)
1573
{
1574
    mbInComplete = bInComplete;
1575
    maFallbackRuns[mnLevel-1] = ImplLayoutRuns();
1576
}
1577
1571
// -----------------------------------------------------------------------
1578
// -----------------------------------------------------------------------
1572
1579
1573
MultiSalLayout::~MultiSalLayout()
1580
MultiSalLayout::~MultiSalLayout()
Lines 1597-1603 Link Here
1597
{
1604
{
1598
    if( mnLevel <= 1 )
1605
    if( mnLevel <= 1 )
1599
        return false;
1606
        return false;
1600
    maFallbackRuns[ mnLevel-1 ] = rArgs.maRuns;
1607
    if (!mbInComplete)
1608
        maFallbackRuns[ mnLevel-1 ] = rArgs.maRuns;
1601
    return true;
1609
    return true;
1602
}
1610
}
1603
1611
Lines 1683-1689 Link Here
1683
1691
1684
        // remove unused parts of component
1692
        // remove unused parts of component
1685
        if( n > 0 )
1693
        if( n > 0 )
1686
            mpLayouts[n]->Simplify( false );
1694
        {
1695
            if (mbInComplete && (n == mnLevel-1))
1696
                mpLayouts[n]->Simplify( true );
1697
            else
1698
                mpLayouts[n]->Simplify( false );
1699
        }
1687
1700
1688
        // prepare merging components
1701
        // prepare merging components
1689
        nStartNew[ nLevel ] = nStartOld[ nLevel ] = 0;
1702
        nStartNew[ nLevel ] = nStartOld[ nLevel ] = 0;

Return to issue 54603