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

(-)openoffice.org.orig/vcl/inc/outdev.h (-1 / +2 lines)
Lines 239-245 Link Here
239
                             const Font& rFont, const Size& rSize, ImplFontSubstEntry* pDevSpecific );
239
                             const Font& rFont, const Size& rSize, ImplFontSubstEntry* pDevSpecific );
240
    ImplFontEntry*      GetFallback( ImplDevFontList* pFontList,
240
    ImplFontEntry*      GetFallback( ImplDevFontList* pFontList,
241
                                     const Font& rFont, const Size& rSize,
241
                                     const Font& rFont, const Size& rSize,
242
                                     int nFallbackLevel );
242
                                     int nFallbackLevel, sal_Unicode *pMissingUnicodes,
243
                                     int nMissingUnicodes );
243
    void                Release( ImplFontEntry* );
244
    void                Release( ImplFontEntry* );
244
    void                Invalidate();
245
    void                Invalidate();
245
};
246
};
(-)openoffice.org.orig/vcl/inc/outfont.hxx (+15 lines)
Lines 252-257 Link Here
252
    ImplDevFontListData*    FindFontFamily( const String& rFontName ) const;
252
    ImplDevFontListData*    FindFontFamily( const String& rFontName ) const;
253
    ImplDevFontListData*    ImplFindByFont( ImplFontSelectData&, bool bPrinter, ImplFontSubstEntry* pDevSpecificSubst ) const;
253
    ImplDevFontListData*    ImplFindByFont( ImplFontSelectData&, bool bPrinter, ImplFontSubstEntry* pDevSpecificSubst ) const;
254
    ImplDevFontListData*    ImplFindBySearchName( const String& ) const;
254
    ImplDevFontListData*    ImplFindBySearchName( const String& ) const;
255
    ImplDevFontListData*    ImplGetFontconfigSubstitute( ImplFontSelectData &rFontSelData, ImplFontSubstEntry* pDevSpecific );
255
256
256
    bool                    HasFallbacks() const;
257
    bool                    HasFallbacks() const;
257
    void                    SetFallbacks( ImplDevFontListData**, int nCount );
258
    void                    SetFallbacks( ImplDevFontListData**, int nCount );
Lines 354-359 Link Here
354
                        ImplFontEntry( const ImplFontSelectData& );
355
                        ImplFontEntry( const ImplFontSelectData& );
355
    virtual             ~ImplFontEntry() {}
356
    virtual             ~ImplFontEntry() {}
356
357
358
    // cache of Unicode characters and replacement font names
359
    typedef ::std::hash_map<sal_Unicode,String> UnicodeFallbackList;
360
    UnicodeFallbackList maUnicodeFallbackList;
361
357
public: // TODO: make data members private
362
public: // TODO: make data members private
358
    ImplFontSelectData  maFontSelData;      // FontSelectionData
363
    ImplFontSelectData  maFontSelData;      // FontSelectionData
359
    ImplFontMetricData  maMetric;           // Font Metric
364
    ImplFontMetricData  maMetric;           // Font Metric
Lines 364-369 Link Here
364
    short               mnOwnOrientation;   // text angle if lower layers don't rotate text themselves
369
    short               mnOwnOrientation;   // text angle if lower layers don't rotate text themselves
365
    short               mnOrientation;      // text angle in 3600 system
370
    short               mnOrientation;      // text angle in 3600 system
366
    bool                mbInit;             // true if maMetric member is valid
371
    bool                mbInit;             // true if maMetric member is valid
372
373
    void                AddFallbackForUnicode( sal_Unicode ch, String fallback )
374
                            { maUnicodeFallbackList[ch] = fallback; }
375
    String              GetFallbackForUnicode( sal_Unicode ch )
376
                            {
377
                                UnicodeFallbackList::const_iterator it = maUnicodeFallbackList.find( ch );
378
                                if ( it != maUnicodeFallbackList.end() )
379
                                    return (*it).second;
380
                                return String();
381
                            }
367
};
382
};
368
383
369
384
(-)openoffice.org.orig/vcl/source/gdi/outdev3.cxx (-96 / +242 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 <tools/isolang.hxx>
173
171
// =======================================================================
174
// =======================================================================
172
175
173
DBG_NAMEEX( OutputDevice );
176
DBG_NAMEEX( OutputDevice );
Lines 2656-2661 ImplFontCache::~ImplFontCache() Link Here
2656
    }
2659
    }
2657
}
2660
}
2658
2661
2662
2663
// -----------------------------------------------------------------------
2664
2665
String GetFcSubstitute(const ImplFontSelectData &rFontSelData, sal_Unicode *pMissingGlyphs=0, int nMissingGlyphs=0)
2666
{
2667
    std::vector<String> aNames;
2668
    if( rFontSelData.GetFamilyName().Len() )
2669
    {
2670
        sal_uInt16 nIndex = 0;
2671
	String aTempName;
2672
        do
2673
        {
2674
                aTempName = GetNextFontToken(rFontSelData.GetFamilyName(), nIndex);
2675
		aNames.push_back(aTempName);
2676
        }
2677
        while (nIndex != STRING_NOTFOUND);
2678
    }
2679
2680
    std::vector<sal_Unicode> aGlyphs;
2681
    for (int i=0; i < nMissingGlyphs; ++i)
2682
	aGlyphs.push_back(pMissingGlyphs[i]);
2683
2684
    ByteString aLangAttrib = ConvertLanguageToIsoByteString( rFontSelData.meLanguage );
2685
2686
    psp::italic::type eItalic = psp::italic::Unknown;
2687
    if( rFontSelData.GetSlant() != ITALIC_DONTKNOW )
2688
    {
2689
        switch( rFontSelData.GetSlant() )
2690
        {
2691
            case ITALIC_NORMAL:  eItalic = psp::italic::Italic; break;
2692
            case ITALIC_OBLIQUE: eItalic = psp::italic::Oblique; break;
2693
            default:
2694
                break;
2695
        }
2696
    }
2697
2698
    psp::weight::type eWeight = psp::weight::Unknown;
2699
    if( rFontSelData.GetWeight() != WEIGHT_DONTKNOW )
2700
    {
2701
        switch( rFontSelData.GetWeight() )
2702
        {
2703
            case WEIGHT_THIN:		eWeight = psp::weight::Thin; break;
2704
            case WEIGHT_ULTRALIGHT:	eWeight = psp::weight::UltraLight; break;
2705
            case WEIGHT_LIGHT:		eWeight = psp::weight::Light; break;
2706
            case WEIGHT_SEMILIGHT:	eWeight = psp::weight::SemiLight; break;
2707
            case WEIGHT_NORMAL:		eWeight = psp::weight::Normal; break;
2708
            case WEIGHT_MEDIUM:		eWeight = psp::weight::Medium; break;
2709
            case WEIGHT_SEMIBOLD:	eWeight = psp::weight::SemiBold; break;
2710
            case WEIGHT_BOLD:		eWeight = psp::weight::Bold; break;
2711
            case WEIGHT_ULTRABOLD:	eWeight = psp::weight::UltraBold; break;
2712
            case WEIGHT_BLACK:		eWeight = psp::weight::Black; break;
2713
            default:
2714
                break;
2715
        }
2716
    }
2717
2718
    psp::width::type eWidth = psp::width::Unknown;
2719
    if( rFontSelData.GetWidthType() != WIDTH_DONTKNOW )
2720
    {
2721
        switch( rFontSelData.GetWidthType() )
2722
        {
2723
            case WIDTH_ULTRA_CONDENSED:	eWidth = psp::width::UltraCondensed; break;
2724
            case WIDTH_EXTRA_CONDENSED: eWidth = psp::width::ExtraCondensed; break;
2725
            case WIDTH_CONDENSED:	eWidth = psp::width::Condensed; break;
2726
            case WIDTH_SEMI_CONDENSED:	eWidth = psp::width::SemiCondensed; break;
2727
            case WIDTH_NORMAL:		eWidth = psp::width::Normal; break;
2728
            case WIDTH_SEMI_EXPANDED:	eWidth = psp::width::SemiExpanded; break;
2729
            case WIDTH_EXPANDED:	eWidth = psp::width::Expanded; break;
2730
            case WIDTH_EXTRA_EXPANDED:	eWidth = psp::width::ExtraExpanded; break;
2731
            case WIDTH_ULTRA_EXPANDED:	eWidth = psp::width::UltraExpanded; break;
2732
            default:
2733
                break;
2734
        }
2735
    }
2736
2737
    psp::pitch::type ePitch = psp::pitch::Unknown;
2738
    if( rFontSelData.GetPitch() != PITCH_DONTKNOW )
2739
    {
2740
        switch(  rFontSelData.GetPitch() )
2741
        {
2742
            case PITCH_FIXED:    ePitch=psp::pitch::Fixed; break;
2743
            case PITCH_VARIABLE: ePitch=psp::pitch::Variable; break;
2744
            default:
2745
                break;
2746
        }
2747
    }
2748
2749
    const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
2750
    return rMgr.Substitute(aNames, aGlyphs, aLangAttrib, eItalic, eWeight, eWidth, ePitch);
2751
}
2752
2753
// -----------------------------------------------------------------------
2754
2755
ImplDevFontListData *ImplDevFontList::ImplGetFontconfigSubstitute( ImplFontSelectData &rFontSelData, ImplFontSubstEntry* pDevSpecific )
2756
{
2757
    // We dont' actually want to talk to Fontconfig at all for symbol fonts
2758
    if (rFontSelData.IsSymbolFont())
2759
        return 0;
2760
    // StarSymbol is a unicode font, but it still deserves the symbol flag
2761
    if( 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "starsymbol", 10)
2762
        ||  0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
2763
        return 0;
2764
2765
    String aName(GetFcSubstitute(rFontSelData));
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
2659
// -----------------------------------------------------------------------
2780
// -----------------------------------------------------------------------
2660
2781
2661
ImplFontEntry* ImplFontCache::Get( ImplDevFontList* pFontList,
2782
ImplFontEntry* ImplFontCache::Get( ImplDevFontList* pFontList,
Lines 2693-2700 ImplFontEntry* ImplFontCache::Get( ImplD Link Here
2693
2814
2694
    if( !pEntry ) // no direct cache hit
2815
    if( !pEntry ) // no direct cache hit
2695
    {
2816
    {
2696
        // find the best matching logical font family and update font selector accordingly
2817
        pFontFamily = pFontList->ImplGetFontconfigSubstitute( aFontSelData, pDevSpecific );
2697
        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
        }
2698
        DBG_ASSERT( (pFontFamily != NULL), "ImplFontCache::Get() No logical font found!" );
2823
        DBG_ASSERT( (pFontFamily != NULL), "ImplFontCache::Get() No logical font found!" );
2699
        aFontSelData.maSearchName = pFontFamily->GetSearchName();
2824
        aFontSelData.maSearchName = pFontFamily->GetSearchName();
2700
2825
Lines 3014-3128 ImplDevFontListData* ImplDevFontList::Im Link Here
3014
// -----------------------------------------------------------------------
3139
// -----------------------------------------------------------------------
3015
3140
3016
ImplFontEntry* ImplFontCache::GetFallback( ImplDevFontList* pFontList,
3141
ImplFontEntry* ImplFontCache::GetFallback( ImplDevFontList* pFontList,
3017
    const Font& rOrigFont, const Size& rSize, int nFallbackLevel )
3142
     const Font& rOrigFont, const Size& rSize, int nFallbackLevel,
3143
     sal_Unicode *pMissingUnicodes, int nMissingUnicodes )
3018
{
3144
{
3019
    // make sure the fontlist knows it's fallbacks
3145
    ImplFontEntry*      pFallbackFont = NULL;
3020
    if( !pFontList->HasFallbacks() )
3146
    bool                cached = false;
3147
    bool                new_entry = false;
3148
    bool                symbolFont = false;
3149
    ImplFontEntry*      pOrigFontEntry = Get( pFontList, rOrigFont, rSize, NULL );
3150
    ImplFontSelectData  aSelData( rOrigFont, rOrigFont.GetName(), rSize );
3151
    sal_uInt16          nToken = 0;
3152
    String              aOrigFontName( GetNextFontToken(rOrigFont.GetName(), nToken) );
3153
3154
    const FontSubstConfigItem& rFontSubst = *FontSubstConfigItem::get();
3155
    const FontNameAttr* fontAttr = rFontSubst.getSubstInfo( aOrigFontName );
3156
3157
    // We dont' actually want to talk to Fontconfig at all for symbol fonts
3158
    if ( pFontList && fontAttr && (fontAttr->Type & IMPL_FONT_ATTR_SYMBOL) )
3021
    {
3159
    {
3022
        // normalized family names of fonts suited for glyph fallback
3160
        if ( fontAttr->Substitutions.size() )
3023
        // if a font is available related fonts can be ignored
3024
        // TODO: implement dynamic lists
3025
        static const char* aGlyphFallbackList[] = {
3026
            // empty strings separate the names of unrelated fonts
3027
            "eudc", "",
3028
            "arialunicodems", "cyberbit", "code2000", "",
3029
            "andalesansui", "",
3030
            "starsymbol", "opensymbol", "",
3031
            "msmincho", "fzmingti", "fzheiti", "ipamincho", "sazanamimincho", "kochimincho", "",
3032
            "sunbatang", "sundotum", "baekmukdotum", "gulim", "batang", "dotum", "",
3033
            "hgmincholightj", "msunglightsc", "msunglighttc", "hymyeongjolightk", "",
3034
            "tahoma", "timesnewroman", "lucidatypewriter", "lucidasans", "nimbussansl", "",
3035
            "shree", "mangal", "raavi", "shruti", "tunga", "latha", "",
3036
            "shayyalmt", "naskmt", "",
3037
            "david", "nachlieli", "lucidagrande", "",
3038
            "norasi", "angsanaupc", "",
3039
            "khmerossystem", "",
3040
            0
3041
        };
3042
3043
        bool bHasEudc = false;
3044
        int nMaxLevel = 0;
3045
        int nBestQuality = 0;
3046
        ImplDevFontListData** pFallbackList = NULL;
3047
        for( const char** ppNames = &aGlyphFallbackList[0];; ++ppNames )
3048
        {
3161
        {
3049
            // advance to next sub-list when end-of-sublist marker
3162
            ::std::vector< String >::const_iterator it = fontAttr->Substitutions.begin();
3050
            if( !**ppNames )    // #i46456# check for empty string, i.e., deref string itself not only ptr to it
3163
            while ( it != fontAttr->Substitutions.end() )
3051
            {
3164
            {
3052
                if( nBestQuality > 0 )
3165
                // Since *it is the "search name" like "standardsymbolsl"
3053
                    if( ++nMaxLevel >= MAX_FALLBACK )
3166
                // we have to find the Family Name (Standard Symbols L) for Fontconfig
3054
                        break;
3167
                ImplDevFontListData* pFontFamily = pFontList->FindFontFamily( *it );
3055
                if( !ppNames[1] )
3168
                if (pFontFamily)
3169
                {
3170
                    aSelData.maSearchName = pFontFamily->GetFamilyName();
3056
                    break;
3171
                    break;
3057
                nBestQuality = 0;
3172
                }
3058
                continue;
3173
                ++it;
3059
            }
3174
            }
3175
        }
3176
        symbolFont = true;
3177
        cached = true;
3178
    }
3060
3179
3061
            // test if the glyph fallback candidate font is available and scalable
3180
    // Try cached fallbacks first
3062
            String aTokenName( *ppNames, RTL_TEXTENCODING_UTF8 );
3181
    if ( !symbolFont && (nMissingUnicodes > 0) )
3063
            ImplDevFontListData* pFallbackFont = pFontList->FindFontFamily( aTokenName );
3182
    {
3064
            if( !pFallbackFont )
3183
        aSelData.maSearchName = pOrigFontEntry->GetFallbackForUnicode( pMissingUnicodes[0] );
3065
                continue;
3184
        if ( aSelData.maSearchName.Len() )
3066
            if( !pFallbackFont->IsScalable() )
3185
            cached = true;
3067
                continue;
3186
    }
3068
3187
3069
            // keep the best font of the glyph fallback sub-list
3188
    if ( !cached )
3070
            if( nBestQuality < pFallbackFont->GetMinQuality() )
3189
    {
3071
            {
3190
        String aName(GetFcSubstitute( aSelData, pMissingUnicodes, nMissingUnicodes ));
3072
                nBestQuality = pFallbackFont->GetMinQuality();
3191
      if (aName.Len())
3073
                // store available glyph fallback fonts
3192
            aSelData.maSearchName = aName;
3074
                if( !pFallbackList )
3193
    }
3075
                    pFallbackList = new ImplDevFontListData*[ MAX_FALLBACK ];
3076
                pFallbackList[ nMaxLevel ] = pFallbackFont;
3077
                if( !bHasEudc && !nMaxLevel )
3078
                    bHasEudc = (0 == strncmp( *ppNames, "eudc", 5 ));
3079
            }
3080
        }
3081
3194
3082
        // sort the list of fonts for glyph fallback by quality (highest first)
3195
    // Check our font instance cache first, if not found then
3083
        // #i33947# keep the EUDC font at the front of the list
3196
    // add this ImplFontSelectData to the cache along with its ImplFontEntry
3084
        // an insertion sort is good enough for this short list
3197
    FontInstanceList::const_iterator it = maFontInstanceList.find( aSelData );
3085
        const int nSortStart = bHasEudc ? 1 : 0;
3198
    if (it != maFontInstanceList.end())
3086
        for( int i = nSortStart+1, j; i < nMaxLevel; ++i )
3199
        pFallbackFont = (*it).second;
3087
        {
3200
    else
3088
            ImplDevFontListData* pTestFont = pFallbackList[ i ];
3201
    {
3089
            int nTestQuality = pTestFont->GetMinQuality();
3202
        // find the best matching physical font face
3090
            for( j = i; --j >= nSortStart; )
3203
        ImplDevFontListData* pFontFamily = pFontList->FindFontFamily( aSelData.maSearchName );
3091
                if( nTestQuality > pFallbackList[j]->GetMinQuality() )
3204
        if (pFontFamily)
3092
                    pFallbackList[ j+1 ] = pFallbackList[ j ];
3205
        {
3093
                else
3206
            ImplFontData* pFontData = pFontFamily->FindBestFontFace( aSelData );
3094
                    break;
3095
            pFallbackList[ j+1 ] = pTestFont;
3096
        }
3097
3207
3098
#if defined(HDU_DEBUG)
3208
            // create a new logical font instance from this physical font face
3099
        for( int i = 0; i < nMaxLevel; ++i )
3209
            aSelData.mpFontData = pFontData;
3210
            pFallbackFont = pFontData->CreateFontInstance( aSelData );
3211
3212
            // if we found a different symbol font we need a symbol conversion table
3213
            if( pFontData->IsSymbolFont() )
3214
                if( aSelData.maTargetName != aSelData.maSearchName )
3215
                    pFallbackFont->mpConversion = ImplGetRecodeData( aSelData.maTargetName, aSelData.maSearchName );
3216
            // add the new entry to the cache
3217
            maFontInstanceList[ aSelData ] = pFallbackFont;
3218
            new_entry = true;
3219
        }
3220
        else
3100
        {
3221
        {
3101
            ImplDevFontListData* pFont = pFallbackList[ i ];
3222
            ByteString l( aSelData.maSearchName, RTL_TEXTENCODING_UTF8 );
3102
            ByteString aFontName( pFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 );
3223
            fprintf (stderr, "--- Couldn't get FontFamily for '%s'\n", l.GetBuffer());
3103
            fprintf( stderr, "GlyphFallbackFont[%d] (quality=%05d): \"%s\"\n",
3104
                i, pFont->GetMinQuality(), aFontName.GetBuffer() );
3105
        }
3224
        }
3106
#endif
3107
3108
        pFontList->SetFallbacks( pFallbackList, nMaxLevel );
3109
    }
3225
    }
3110
3226
3111
    Font aFallbackFont = rOrigFont;
3227
    // Cache the fallback font for each of the missing Unicode chars
3112
3228
    if ( !symbolFont && aSelData.maSearchName.Len() )
3113
    // nFallbackLevel==0 => original font without device specific substitution
3114
    // nFallbackLevel>=1 => use a font from the glyph fallback font list
3115
    if( nFallbackLevel>=1 )
3116
    {
3229
    {
3117
        ImplDevFontListData* pFallbackData = pFontList->GetFallback( nFallbackLevel-1 );
3230
        for ( int i = 0; i < nMissingUnicodes; i++ )
3118
        if( !pFallbackData )
3231
        {
3119
            return NULL;
3232
            if ( ! pOrigFontEntry->GetFallbackForUnicode(pMissingUnicodes[i]).Len() )
3120
3233
                pOrigFontEntry->AddFallbackForUnicode( pMissingUnicodes[i], aSelData.maSearchName );
3121
        aFallbackFont.SetName( pFallbackData->GetSearchName() );
3234
        }
3122
    }
3235
    }
3123
3236
3124
    ImplFontEntry* pFallbackFont = Get( pFontList, aFallbackFont, rSize, NULL );
3125
3126
    if( pFallbackFont && !pFallbackFont->mbInit )
3237
    if( pFallbackFont && !pFallbackFont->mbInit )
3127
    {
3238
    {
3128
        // HACK: maMetrics are irrelevant for fallback fonts, but
3239
        // HACK: maMetrics are irrelevant for fallback fonts, but
Lines 3131-3136 ImplFontEntry* ImplFontCache::GetFallbac Link Here
3131
        pFallbackFont->maMetric.maStyleName = String();
3242
        pFallbackFont->maMetric.maStyleName = String();
3132
    }
3243
    }
3133
3244
3245
    if ( pFallbackFont && !new_entry )
3246
    {
3247
        // increase the font instance's reference count
3248
        if( !pFallbackFont->mnRefCount++ )
3249
            --mnRef0Count;
3250
    }
3251
3252
#if 0
3253
    sal_uInt16 nTok = 0;
3254
    ByteString n( GetNextFontToken(rOrigFont.GetName(), nTok), RTL_TEXTENCODING_UTF8);
3255
    ByteString m;
3256
    if (pFallbackFont)
3257
    {
3258
        nTok = 0;
3259
        ByteString tS( GetNextFontToken(pFallbackFont->maFontSelData.mpFontData->GetFamilyName(), nTok), RTL_TEXTENCODING_UTF8 );
3260
        m.Assign( tS );
3261
    }
3262
    fprintf (stderr, "Glyph fallback '%s'->'%s' %s\n", n.GetBuffer(), pFallbackFont ? m.GetBuffer() : "none",
3263
                new_entry ? "(new)" : "(cached)");
3264
#endif
3265
3134
    return pFallbackFont;
3266
    return pFallbackFont;
3135
}
3267
}
3136
3268
Lines 6097-6103 SalLayout* OutputDevice::ImplLayout( con Link Here
6097
    // do glyph fallback if needed
6229
    // do glyph fallback if needed
6098
    // #105768# avoid fallback for very small font sizes
6230
    // #105768# avoid fallback for very small font sizes
6099
    if( aLayoutArgs.NeedFallback() )
6231
    if( aLayoutArgs.NeedFallback() )
6100
        if( mpFontEntry && (mpFontEntry->maFontSelData.mnHeight >= 6) )
6232
        if( mpFontEntry && (mpFontEntry->maFontSelData.mnHeight >= 3) )
6101
            pSalLayout = ImplGlyphFallbackLayout( pSalLayout, aLayoutArgs );
6233
            pSalLayout = ImplGlyphFallbackLayout( pSalLayout, aLayoutArgs );
6102
6234
6103
    // position, justify, etc. the layout
6235
    // position, justify, etc. the layout
Lines 6141-6146 SalLayout* OutputDevice::ImplGlyphFallba Link Here
6141
        rLayoutArgs.ResetPos();
6273
        rLayoutArgs.ResetPos();
6142
    }
6274
    }
6143
#endif
6275
#endif
6276
    int nCharPos = -1;
6277
    bool bRTL = false;
6278
    sal_Unicode *pMissingUnicodes = new sal_Unicode[8];
6279
    int nMissingUnicodes = 0;
6280
6281
    for( int i=0; i<8 && rLayoutArgs.GetNextPos( &nCharPos, &bRTL); ++i )
6282
    {
6283
        pMissingUnicodes[i] = rLayoutArgs.mpStr[ nCharPos ];
6284
        nMissingUnicodes++;
6285
    }
6286
    rLayoutArgs.ResetPos();
6144
6287
6145
    ImplFontSelectData aFontSelData = mpFontEntry->maFontSelData;
6288
    ImplFontSelectData aFontSelData = mpFontEntry->maFontSelData;
6146
    Size aFontSize( aFontSelData.mnWidth, aFontSelData.mnHeight );
6289
    Size aFontSize( aFontSelData.mnWidth, aFontSelData.mnHeight );
Lines 6157-6163 SalLayout* OutputDevice::ImplGlyphFallba Link Here
6157
    {
6300
    {
6158
        // find a font family suited for glyph fallback
6301
        // find a font family suited for glyph fallback
6159
        ImplFontEntry* pFallbackFont = mpFontCache->GetFallback( mpFontList,
6302
        ImplFontEntry* pFallbackFont = mpFontCache->GetFallback( mpFontList,
6160
            maFont, aFontSize, nFallbackLevel-nDevSpecificFallback );
6303
            maFont, aFontSize, nFallbackLevel-nDevSpecificFallback,
6304
            (nMissingUnicodes ? pMissingUnicodes : NULL), nMissingUnicodes );
6161
        if( !pFallbackFont )
6305
        if( !pFallbackFont )
6162
            break;
6306
            break;
6163
6307
Lines 6208-6213 SalLayout* OutputDevice::ImplGlyphFallba Link Here
6208
        if( !rLayoutArgs.PrepareFallback() )
6352
        if( !rLayoutArgs.PrepareFallback() )
6209
            break;
6353
            break;
6210
    }
6354
    }
6355
6356
    delete[] pMissingUnicodes;
6211
6357
6212
    if( pMultiSalLayout && pMultiSalLayout->LayoutText( rLayoutArgs ) )
6358
    if( pMultiSalLayout && pMultiSalLayout->LayoutText( rLayoutArgs ) )
6213
        pSalLayout = pMultiSalLayout;
6359
        pSalLayout = pMultiSalLayout;
(-)openoffice.org.orig/vcl/source/window/window.cxx (+5 lines)
Lines 212-217 Link Here
212
#endif
212
#endif
213
213
214
#include <pdfextoutdevdata.hxx>
214
#include <pdfextoutdevdata.hxx>
215
#include <psprint/fontmanager.hxx>
215
216
216
using namespace rtl;
217
using namespace rtl;
217
using namespace ::com::sun::star::uno;
218
using namespace ::com::sun::star::uno;
Lines 350-355 Link Here
350
{
351
{
351
    ImplInitFontList();
352
    ImplInitFontList();
352
353
354
    const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
355
    if (rMgr.hasFontconfig())
356
        return true;
357
353
    String aTestText;
358
    String aTestText;
354
    aTestText.Append( Button::GetStandardText( BUTTON_OK ) );
359
    aTestText.Append( Button::GetStandardText( BUTTON_OK ) );
355
    aTestText.Append( Button::GetStandardText( BUTTON_CANCEL ) );
360
    aTestText.Append( Button::GetStandardText( BUTTON_CANCEL ) );
(-)openoffice.org.orig/vcl/util/makefile.mk (-1 / +1 lines)
Lines 265-271 Link Here
265
.ENDIF
265
.ENDIF
266
266
267
267
268
SHL1STDLIBS += -lX11
268
SHL1STDLIBS += -lX11 -lpsp$(VERSION)$(DLLPOSTFIX)
269
269
270
.ENDIF          # "$(GUI)"=="UNX"
270
.ENDIF          # "$(GUI)"=="UNX"
271
271
(-)openoffice.org.orig/psprint/uinc/psprint/fontmanager.hxx (-2 / +11 lines)
Lines 75-80 Link Here
75
#ifndef _PSPRINT_HELPER_HXX_
75
#ifndef _PSPRINT_HELPER_HXX_
76
#include <psprint/helper.hxx>
76
#include <psprint/helper.hxx>
77
#endif
77
#endif
78
#ifndef _STRING_HXX
79
#include <tools/string.hxx>
80
#endif
78
81
79
#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
82
#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
80
#include <com/sun/star/lang/Locale.hpp>
83
#include <com/sun/star/lang/Locale.hpp>
Lines 419-424 Link Here
419
    std::hash_multimap< sal_uInt8, sal_Unicode >	m_aAdobecodeToUnicode;
422
    std::hash_multimap< sal_uInt8, sal_Unicode >	m_aAdobecodeToUnicode;
420
423
421
    mutable FontCache*							m_pFontCache;
424
    mutable FontCache*							m_pFontCache;
425
    bool m_bFontconfigSuccess;
422
        
426
        
423
    rtl::OString getAfmFile( PrintFont* pFont ) const;
427
    rtl::OString getAfmFile( PrintFont* pFont ) const;
424
    rtl::OString getFontFile( PrintFont* pFont ) const;
428
    rtl::OString getFontFile( PrintFont* pFont ) const;
Lines 504-513 Link Here
504
    const rtl::OUString& getPSName( fontID nFontID ) const;
508
    const rtl::OUString& getPSName( fontID nFontID ) const;
505
509
506
    // get a specific fonts style family
510
    // get a specific fonts style family
507
    family::type PrintFontManager::getFontFamilyType( fontID nFontID ) const;
511
    family::type getFontFamilyType( fontID nFontID ) const;
508
512
509
    // get a specific fonts family name aliases
513
    // get a specific fonts family name aliases
510
    void PrintFontManager::getFontFamilyAliases( fontID nFontID ) const;
514
    void getFontFamilyAliases( fontID nFontID ) const;
511
        
515
        
512
    // get a specific fonts type
516
    // get a specific fonts type
513
    fonttype::type getFontType( fontID nFontID ) const
517
    fonttype::type getFontType( fontID nFontID ) const
Lines 729-734 Link Here
729
    false else
733
    false else
730
     */
734
     */
731
    bool matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale );
735
    bool matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale );
736
737
    String Substitute(const std::vector<String> &rNames, const std::vector<sal_Unicode> &rGlyphs, 
738
        const ByteString &rLangAttrib, italic::type eItalic, weight::type eWeight, 
739
        width::type eWidth, pitch::type ePitch) const;
740
    bool hasFontconfig() const { return m_bFontconfigSuccess; }
732
};
741
};
733
742
734
} // namespace
743
} // namespace
(-)openoffice.org.orig/psprint/usource/fontmanager/fontcache.cxx (-1 / +1 lines)
Lines 688-696 Link Here
688
        FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
688
        FontDirMap::const_iterator entry = dir->second.m_aEntries.find( rFile );
689
        if( entry != dir->second.m_aEntries.end() )
689
        if( entry != dir->second.m_aEntries.end() )
690
        {
690
        {
691
            bSuccess = true;
692
            for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
691
            for( FontCacheEntry::const_iterator font = entry->second.m_aEntry.begin(); font != entry->second.m_aEntry.end(); ++font )
693
            {
692
            {
693
                bSuccess = true;
694
                PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
694
                PrintFontManager::PrintFont* pFont = clonePrintFont( *font );
695
                rNewFonts.push_back( pFont );
695
                rNewFonts.push_back( pFont );
696
            }
696
            }
(-)openoffice.org.orig/psprint/usource/fontmanager/fontmanager.cxx (-4 / +5 lines)
Lines 1155-1161 PrintFontManager::PrintFontManager() : Link Here
1155
        m_nNextFontID( 1 ),
1155
        m_nNextFontID( 1 ),
1156
        m_pAtoms( new MultiAtomProvider() ),
1156
        m_pAtoms( new MultiAtomProvider() ),
1157
        m_nNextDirAtom( 1 ),
1157
        m_nNextDirAtom( 1 ),
1158
        m_pFontCache( NULL )
1158
        m_pFontCache( NULL ),
1159
	m_bFontconfigSuccess(false)
1159
{
1160
{
1160
    for( unsigned int i = 0; i < sizeof( aAdobeCodes )/sizeof( aAdobeCodes[0] ); i++ )
1161
    for( unsigned int i = 0; i < sizeof( aAdobeCodes )/sizeof( aAdobeCodes[0] ); i++ )
1161
    {
1162
    {
Lines 2109-2115 void PrintFontManager::initialize( void* Link Here
2109
#endif
2110
#endif
2110
2111
2111
    // first try fontconfig
2112
    // first try fontconfig
2112
    bool bFontconfigSuccess = initFontconfig();
2113
    m_bFontconfigSuccess = initFontconfig();
2113
2114
2114
    // part one - look for downloadable fonts
2115
    // part one - look for downloadable fonts
2115
    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
2116
    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
Lines 2131-2137 void PrintFontManager::initialize( void* Link Here
2131
    }
2132
    }
2132
2133
2133
    // don't search through many directories fontconfig already told us about
2134
    // don't search through many directories fontconfig already told us about
2134
    if( ! bFontconfigSuccess )
2135
    if( ! m_bFontconfigSuccess )
2135
    {							
2136
    {							
2136
        Display *pDisplay = (Display*)pInitDisplay;
2137
        Display *pDisplay = (Display*)pInitDisplay;
2137
        
2138
        
Lines 2209-2215 void PrintFontManager::initialize( void* Link Here
2209
            }
2210
            }
2210
        }
2211
        }
2211
#endif /* SOLARIS */
2212
#endif /* SOLARIS */
2212
    } // ! bFontconfigSuccess
2213
    } // ! m_bFontconfigSuccess
2213
2214
2214
    // fill XLFD aliases from fonts.alias files
2215
    // fill XLFD aliases from fonts.alias files
2215
    initFontsAlias();
2216
    initFontsAlias();
(-)openoffice.org.orig/psprint/source/fontmanager/fontconfig.cxx (-64 / +205 lines)
Lines 44-53 typedef void FcConfig; Link Here
44
typedef void FcObjectSet;
44
typedef void FcObjectSet;
45
typedef void FcPattern;
45
typedef void FcPattern;
46
typedef void FcFontSet;
46
typedef void FcFontSet;
47
typedef void FcCharSet;
47
typedef int FcResult;
48
typedef int FcResult;
48
typedef int FcBool;
49
typedef int FcBool;
49
typedef int FcMatchKind;
50
typedef int FcMatchKind;
50
typedef char FcChar8;
51
typedef char FcChar8;
52
typedef sal_Int32 FcChar32;
51
#endif
53
#endif
52
54
53
#include <cstdio>
55
#include <cstdio>
Lines 80-85 class FontCfgWrapper Link Here
80
{
82
{
81
    void*			m_pLib;
83
    void*			m_pLib;
82
    FcConfig*		m_pDefConfig;
84
    FcConfig*		m_pDefConfig;
85
    FcFontSet*      m_pOutlineSet;
83
86
84
	FcBool          (*m_pFcInit)();
87
	FcBool          (*m_pFcInit)();
85
    FcConfig*		(*m_pFcConfigGetCurrent)();
88
    FcConfig*		(*m_pFcConfigGetCurrent)();
Lines 88-104 class FontCfgWrapper Link Here
88
    FcPattern*		(*m_pFcPatternCreate)();
91
    FcPattern*		(*m_pFcPatternCreate)();
89
    void			(*m_pFcPatternDestroy)(FcPattern*);
92
    void			(*m_pFcPatternDestroy)(FcPattern*);
90
    FcFontSet*		(*m_pFcFontList)(FcConfig*,FcPattern*,FcObjectSet*);
93
    FcFontSet*		(*m_pFcFontList)(FcConfig*,FcPattern*,FcObjectSet*);
94
    FcFontSet*      (*m_pFcConfigGetFonts)(FcConfig*,FcSetName);
91
    FcFontSet*		(*m_pFcFontSetCreate)();
95
    FcFontSet*		(*m_pFcFontSetCreate)();
96
    FcCharSet*		(*m_pFcCharSetCreate)();
97
    FcBool			(*m_pFcCharSetAddChar)(FcCharSet *, FcChar32);
92
    void			(*m_pFcFontSetDestroy)(FcFontSet*);
98
    void			(*m_pFcFontSetDestroy)(FcFontSet*);
93
    FcBool			(*m_pFcFontSetAdd)(FcFontSet*,FcPattern*);
99
    FcBool			(*m_pFcFontSetAdd)(FcFontSet*,FcPattern*);
100
    void            (*m_pFcPatternReference)(FcPattern*);
94
    FcResult		(*m_pFcPatternGetString)(const FcPattern*,const char*,int,FcChar8**);
101
    FcResult		(*m_pFcPatternGetString)(const FcPattern*,const char*,int,FcChar8**);
95
    FcResult		(*m_pFcPatternGetInteger)(const FcPattern*,const char*,int,int*);
102
    FcResult		(*m_pFcPatternGetInteger)(const FcPattern*,const char*,int,int*);
96
    FcResult		(*m_pFcPatternGetDouble)(const FcPattern*,const char*,int,double*);
103
    FcResult		(*m_pFcPatternGetDouble)(const FcPattern*,const char*,int,double*);
97
    FcResult		(*m_pFcPatternGetBool)(const FcPattern*,const char*,int,FcBool*);
104
    FcResult		(*m_pFcPatternGetBool)(const FcPattern*,const char*,int,FcBool*);
98
    void			(*m_pFcDefaultSubstitute)(FcPattern *);
105
    void			(*m_pFcDefaultSubstitute)(FcPattern *);
99
    FcPattern*		(*m_pFcFontMatch)(FcConfig*,FcPattern*,FcResult*);    
106
    FcPattern*      (*m_pFcFontSetMatch)(FcConfig*,FcFontSet**, int, FcPattern*,FcResult*);
100
    FcBool			(*m_pFcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind);
107
    FcBool			(*m_pFcConfigSubstitute)(FcConfig*,FcPattern*,FcMatchKind);
101
    FcBool			(*m_pFcPatternAddInteger)(FcPattern*,const char*,int);
108
    FcBool			(*m_pFcPatternAddInteger)(FcPattern*,const char*,int);
109
    FcBool			(*m_pFcPatternAddBool)(FcPattern*,const char*,FcBool);
110
    FcBool			(*m_pFcPatternAddCharSet)(FcPattern*,const char*,const FcCharSet*);
102
    FcBool			(*m_pFcPatternAddString)(FcPattern*,const char*,const FcChar8*);
111
    FcBool			(*m_pFcPatternAddString)(FcPattern*,const char*,const FcChar8*);
103
112
104
    void* loadSymbol( const char* );
113
    void* loadSymbol( const char* );
Lines 114-119 public: Link Here
114
    { return m_pLib != NULL;}
123
    { return m_pLib != NULL;}
115
124
116
    FcConfig* getDefConfig() { return m_pDefConfig; }
125
    FcConfig* getDefConfig() { return m_pDefConfig; }
126
    FcFontSet* getFontSet() { return m_pOutlineSet; }
117
127
118
    FcBool FcInit()
128
    FcBool FcInit()
119
    { return m_pFcInit(); }
129
    { return m_pFcInit(); }
Lines 143-156 public: Link Here
143
    
153
    
144
    FcFontSet* FcFontList( FcConfig* pConfig, FcPattern* pPattern, FcObjectSet* pSet )
154
    FcFontSet* FcFontList( FcConfig* pConfig, FcPattern* pPattern, FcObjectSet* pSet )
145
    { return m_pFcFontList( pConfig, pPattern, pSet ); }
155
    { return m_pFcFontList( pConfig, pPattern, pSet ); }
146
    
156
157
    FcFontSet* FcConfigGetFonts( FcConfig* pConfig, FcSetName eSet)
158
    { return m_pFcConfigGetFonts( pConfig, eSet ); }
159
147
    FcFontSet* FcFontSetCreate()
160
    FcFontSet* FcFontSetCreate()
148
    { return m_pFcFontSetCreate(); }
161
    { return m_pFcFontSetCreate(); }
162
163
    FcCharSet* FcCharSetCreate()
164
    { return m_pFcCharSetCreate(); }
165
166
    FcBool FcCharSetAddChar(FcCharSet *fcs, FcChar32 ucs4)
167
    { return m_pFcCharSetAddChar(fcs, ucs4); }
168
149
    void FcFontSetDestroy( FcFontSet* pSet )
169
    void FcFontSetDestroy( FcFontSet* pSet )
150
    { m_pFcFontSetDestroy( pSet );}
170
    { m_pFcFontSetDestroy( pSet );}
171
151
    FcBool FcFontSetAdd( FcFontSet* pSet, FcPattern* pPattern )
172
    FcBool FcFontSetAdd( FcFontSet* pSet, FcPattern* pPattern )
152
    { return m_pFcFontSetAdd( pSet, pPattern ); }
173
    { return m_pFcFontSetAdd( pSet, pPattern ); }
153
174
175
    void FcPatternReference( FcPattern* pPattern )
176
    { m_pFcPatternReference( pPattern ); }
177
154
    FcResult FcPatternGetString( const FcPattern* pPattern, const char* object, int n, FcChar8** s )
178
    FcResult FcPatternGetString( const FcPattern* pPattern, const char* object, int n, FcChar8** s )
155
    { return m_pFcPatternGetString( pPattern, object, n, s ); }
179
    { return m_pFcPatternGetString( pPattern, object, n, s ); }
156
180
Lines 164-175 public: Link Here
164
    { return m_pFcPatternGetBool( pPattern, object, n, s ); }
188
    { return m_pFcPatternGetBool( pPattern, object, n, s ); }
165
    void FcDefaultSubstitute( FcPattern* pPattern )
189
    void FcDefaultSubstitute( FcPattern* pPattern )
166
    { m_pFcDefaultSubstitute( pPattern ); }
190
    { m_pFcDefaultSubstitute( pPattern ); }
167
    FcPattern* FcFontMatch( FcConfig* pConfig, FcPattern* pPattern, FcResult* pResult )
191
    FcPattern* FcFontSetMatch(FcConfig* pConfig, FcFontSet** ppFontSet, int nset, FcPattern *pPattern, FcResult *pResult)
168
    { return m_pFcFontMatch( pConfig, pPattern, pResult ); }
192
    { return m_pFcFontSetMatch( pConfig, ppFontSet, nset, pPattern, pResult ); }
169
    FcBool FcConfigSubstitute( FcConfig* pConfig, FcPattern* pPattern, FcMatchKind eKind )
193
    FcBool FcConfigSubstitute( FcConfig* pConfig, FcPattern* pPattern, FcMatchKind eKind )
170
    { return m_pFcConfigSubstitute( pConfig, pPattern, eKind ); }
194
    { return m_pFcConfigSubstitute( pConfig, pPattern, eKind ); }
171
    FcBool FcPatternAddInteger( FcPattern* pPattern, const char* pObject, int nValue )
195
    FcBool FcPatternAddInteger( FcPattern* pPattern, const char* pObject, int nValue )
172
    { return m_pFcPatternAddInteger( pPattern, pObject, nValue ); }
196
    { return m_pFcPatternAddInteger( pPattern, pObject, nValue ); }
197
    FcBool FcPatternAddBool( FcPattern* pPattern, const char* pObject, FcBool b )
198
    { return m_pFcPatternAddBool( pPattern, pObject, b ); }
199
    FcBool FcPatternAddCharSet( FcPattern* pPattern, const char* pObject, const FcCharSet *c)
200
    { return m_pFcPatternAddCharSet( pPattern, pObject, c ); }
173
    FcBool FcPatternAddString( FcPattern* pPattern, const char* pObject, const FcChar8* pString )
201
    FcBool FcPatternAddString( FcPattern* pPattern, const char* pObject, const FcChar8* pString )
174
    { return m_pFcPatternAddString( pPattern, pObject, pString ); }
202
    { return m_pFcPatternAddString( pPattern, pObject, pString ); }
175
};
203
};
Lines 186-192 void* FontCfgWrapper::loadSymbol( const Link Here
186
214
187
FontCfgWrapper::FontCfgWrapper()
215
FontCfgWrapper::FontCfgWrapper()
188
        : m_pLib( NULL ),
216
        : m_pLib( NULL ),
189
          m_pDefConfig( NULL )
217
          m_pDefConfig( NULL ),
218
          m_pOutlineSet( NULL )
190
{
219
{
191
#ifdef ENABLE_FONTCONFIG
220
#ifdef ENABLE_FONTCONFIG
192
    OUString aLib( RTL_CONSTASCII_USTRINGPARAM( "libfontconfig.so.1" ) );
221
    OUString aLib( RTL_CONSTASCII_USTRINGPARAM( "libfontconfig.so.1" ) );
Lines 220-231 FontCfgWrapper::FontCfgWrapper() Link Here
220
        loadSymbol( "FcPatternDestroy" );
249
        loadSymbol( "FcPatternDestroy" );
221
    m_pFcFontList = (FcFontSet*(*)(FcConfig*,FcPattern*,FcObjectSet*))
250
    m_pFcFontList = (FcFontSet*(*)(FcConfig*,FcPattern*,FcObjectSet*))
222
        loadSymbol( "FcFontList" );
251
        loadSymbol( "FcFontList" );
252
    m_pFcConfigGetFonts = (FcFontSet*(*)(FcConfig*,FcSetName))
253
        loadSymbol( "FcConfigGetFonts" );
223
    m_pFcFontSetCreate = (FcFontSet*(*)())
254
    m_pFcFontSetCreate = (FcFontSet*(*)())
224
        loadSymbol( "FcFontSetCreate" );
255
        loadSymbol( "FcFontSetCreate" );
256
    m_pFcCharSetCreate = (FcCharSet*(*)())
257
        loadSymbol( "FcCharSetCreate" );
258
    m_pFcCharSetAddChar = (FcBool(*)(FcCharSet*, FcChar32))
259
        loadSymbol( "FcCharSetAddChar" );
225
    m_pFcFontSetDestroy = (void(*)(FcFontSet*))
260
    m_pFcFontSetDestroy = (void(*)(FcFontSet*))
226
        loadSymbol( "FcFontSetDestroy" );
261
        loadSymbol( "FcFontSetDestroy" );
227
    m_pFcFontSetAdd = (FcBool(*)(FcFontSet*,FcPattern*))
262
    m_pFcFontSetAdd = (FcBool(*)(FcFontSet*,FcPattern*))
228
        loadSymbol( "FcFontSetAdd" );
263
        loadSymbol( "FcFontSetAdd" );
264
    m_pFcPatternReference = (void(*)(FcPattern*))
265
        loadSymbol( "FcPatternReference" );
229
    m_pFcPatternGetString = (FcResult(*)(const FcPattern*,const char*,int,FcChar8**))
266
    m_pFcPatternGetString = (FcResult(*)(const FcPattern*,const char*,int,FcChar8**))
230
        loadSymbol( "FcPatternGetString" );
267
        loadSymbol( "FcPatternGetString" );
231
    m_pFcPatternGetInteger = (FcResult(*)(const FcPattern*,const char*,int,int*))
268
    m_pFcPatternGetInteger = (FcResult(*)(const FcPattern*,const char*,int,int*))
Lines 236-247 FontCfgWrapper::FontCfgWrapper() Link Here
236
        loadSymbol( "FcPatternGetBool" );
273
        loadSymbol( "FcPatternGetBool" );
237
    m_pFcDefaultSubstitute = (void(*)(FcPattern *))
274
    m_pFcDefaultSubstitute = (void(*)(FcPattern *))
238
        loadSymbol( "FcDefaultSubstitute" );
275
        loadSymbol( "FcDefaultSubstitute" );
239
    m_pFcFontMatch = (FcPattern*(*)(FcConfig*,FcPattern*,FcResult*))
276
    m_pFcFontSetMatch = (FcPattern*(*)(FcConfig*,FcFontSet**, int, FcPattern*,FcResult*))
240
        loadSymbol( "FcFontMatch" );
277
        loadSymbol( "FcFontSetMatch" );
241
    m_pFcConfigSubstitute = (FcBool(*)(FcConfig*,FcPattern*,FcMatchKind))
278
    m_pFcConfigSubstitute = (FcBool(*)(FcConfig*,FcPattern*,FcMatchKind))
242
        loadSymbol( "FcConfigSubstitute" );
279
        loadSymbol( "FcConfigSubstitute" );
243
    m_pFcPatternAddInteger = (FcBool(*)(FcPattern*,const char*,int))
280
    m_pFcPatternAddInteger = (FcBool(*)(FcPattern*,const char*,int))
244
        loadSymbol( "FcPatternAddInteger" );
281
        loadSymbol( "FcPatternAddInteger" );
282
    m_pFcPatternAddBool = (FcBool(*)(FcPattern*,const char*,FcBool))
283
        loadSymbol( "FcPatternAddBool" );
284
    m_pFcPatternAddCharSet = (FcBool(*)(FcPattern*,const char*,const FcCharSet *))
285
        loadSymbol( "FcPatternAddCharSet" );
245
    m_pFcPatternAddString = (FcBool(*)(FcPattern*,const char*,const FcChar8*))
286
    m_pFcPatternAddString = (FcBool(*)(FcPattern*,const char*,const FcChar8*))
246
        loadSymbol( "FcPatternAddString" );
287
        loadSymbol( "FcPatternAddString" );
247
288
Lines 253-269 FontCfgWrapper::FontCfgWrapper() Link Here
253
            m_pFcPatternCreate				&&
294
            m_pFcPatternCreate				&&
254
            m_pFcPatternDestroy				&&
295
            m_pFcPatternDestroy				&&
255
            m_pFcFontList					&&
296
            m_pFcFontList					&&
297
            m_pFcConfigGetFonts             &&
256
            m_pFcFontSetCreate				&&
298
            m_pFcFontSetCreate				&&
299
            m_pFcCharSetCreate				&&
300
            m_pFcCharSetAddChar 			&&
257
            m_pFcFontSetDestroy				&&
301
            m_pFcFontSetDestroy				&&
258
            m_pFcFontSetAdd					&&
302
            m_pFcFontSetAdd					&&
303
            m_pFcPatternReference           &&
259
            m_pFcPatternGetString			&&
304
            m_pFcPatternGetString			&&
260
            m_pFcPatternGetInteger			&&
305
            m_pFcPatternGetInteger			&&
261
            m_pFcPatternGetDouble			&&
306
            m_pFcPatternGetDouble			&&
262
            m_pFcPatternGetBool				&&
307
            m_pFcPatternGetBool				&&
263
            m_pFcDefaultSubstitute			&&
308
            m_pFcDefaultSubstitute			&&
264
            m_pFcFontMatch					&&
309
            m_pFcFontSetMatch				&&
265
            m_pFcConfigSubstitute			&&
310
            m_pFcConfigSubstitute			&&
266
            m_pFcPatternAddInteger			&&
311
            m_pFcPatternAddInteger			&&
312
            m_pFcPatternAddCharSet			&&
313
            m_pFcPatternAddBool 			&&
267
            m_pFcPatternAddString
314
            m_pFcPatternAddString
268
            ) )
315
            ) )
269
    {
316
    {
Lines 281-290 FontCfgWrapper::FontCfgWrapper() Link Here
281
        osl_unloadModule( (oslModule)m_pLib );
328
        osl_unloadModule( (oslModule)m_pLib );
282
        m_pLib = NULL;
329
        m_pLib = NULL;
283
    }
330
    }
331
332
    m_pOutlineSet = FcFontSetCreate();
333
334
    /*
335
      add only acceptable outlined fonts to our config, 
336
      for future fontconfig use
337
    */
338
    FcFontSet *pOrig = FcConfigGetFonts(NULL, FcSetSystem);
339
340
    if (!pOrig)
341
        return;
342
343
    for( int i = 0; i < pOrig->nfont; ++i )
344
    {
345
        FcBool outline = false;
346
        FcPattern *pOutlinePattern = pOrig->fonts[i];
347
        FcResult eOutRes = 
348
			FcPatternGetBool( pOutlinePattern, FC_OUTLINE, 0, &outline );
349
        if (eOutRes == FcResultMatch && !outline)
350
            continue;
351
        FcPatternReference(pOutlinePattern);
352
        FcFontSetAdd(m_pOutlineSet, pOutlinePattern);
353
    }
284
}
354
}
285
355
286
FontCfgWrapper::~FontCfgWrapper()
356
FontCfgWrapper::~FontCfgWrapper()
287
{
357
{
358
	if( m_pOutlineSet )
359
		FcFontSetDestroy( m_pOutlineSet );
288
    if( m_pLib )
360
    if( m_pLib )
289
        osl_unloadModule( (oslModule)m_pLib );
361
        osl_unloadModule( (oslModule)m_pLib );
290
}
362
}
Lines 319-337 bool PrintFontManager::initFontconfig() Link Here
319
    if( ! rWrapper.isValid() )
391
    if( ! rWrapper.isValid() )
320
        return false;
392
        return false;
321
393
322
    FcConfig* pConfig = rWrapper.getDefConfig();
323
    FcObjectSet* pOSet = rWrapper.FcObjectSetBuild( FC_FAMILY,
324
                                                    FC_STYLE,
325
                                                    FC_SLANT,
326
                                                    FC_WEIGHT,
327
                                                    FC_SPACING,
328
                                                    FC_FILE,
329
                                                    FC_OUTLINE,
330
                                                    FC_INDEX,
331
                                                    (void *) NULL );
332
    FcPattern* pPattern = rWrapper.FcPatternCreate();
333
    FcFontSet* pFSet = rWrapper.FcFontList( pConfig, pPattern, pOSet );
334
    rtl_TextEncoding aThreadTextEncoding = osl_getThreadTextEncoding();
394
    rtl_TextEncoding aThreadTextEncoding = osl_getThreadTextEncoding();
395
    FcFontSet* pFSet = rWrapper.getFontSet();
335
396
336
    if( pFSet )
397
    if( pFSet )
337
    {
398
    {
Lines 374-379 bool PrintFontManager::initFontconfig() Link Here
374
                     );
434
                     );
375
#endif
435
#endif
376
436
437
            OSL_ASSERT(eOutRes != FcResultMatch || outline);
438
377
            // only outline fonts are usable to psprint anyway
439
            // only outline fonts are usable to psprint anyway
378
            if( eOutRes == FcResultMatch && ! outline )
440
            if( eOutRes == FcResultMatch && ! outline )
379
                continue;
441
                continue;
Lines 516-529 bool PrintFontManager::initFontconfig() Link Here
516
        }
578
        }
517
    }
579
    }
518
    
580
    
519
    // cleanup
520
    if( pPattern )
521
        rWrapper.FcPatternDestroy( pPattern );
522
    if( pFSet )
523
        rWrapper.FcFontSetDestroy( pFSet );
524
    if( pOSet )
525
        rWrapper.FcObjectSetDestroy( pOSet );
526
    
527
    // how does one get rid of the config ?
581
    // how does one get rid of the config ?
528
#if OSL_DEBUG_LEVEL > 1
582
#if OSL_DEBUG_LEVEL > 1
529
    fprintf( stderr, "inserted %d fonts from fontconfig\n", nFonts );
583
    fprintf( stderr, "inserted %d fonts from fontconfig\n", nFonts );
Lines 537-575 void PrintFontManager::deinitFontconfig( Link Here
537
    FontCfgWrapper::release();
591
    FontCfgWrapper::release();
538
}
592
}
539
593
540
bool PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale )
594
static void addtopattern(FontCfgWrapper& rWrapper, FcPattern *pPattern, 
595
	italic::type eItalic, weight::type eWeight, width::type eWidth, pitch::type ePitch)
541
{
596
{
542
#ifdef ENABLE_FONTCONFIG
597
#ifdef ENABLE_FONTCONFIG
543
    FontCfgWrapper& rWrapper = FontCfgWrapper::get();
598
    if( eItalic != italic::Unknown )
544
    if( ! rWrapper.isValid() )
545
        return false;
546
547
    FcConfig* pConfig = rWrapper.getDefConfig();
548
    FcPattern* pPattern = rWrapper.FcPatternCreate();
549
550
    OString aLangAttrib;
551
    // populate pattern with font characteristics
552
    if( rLocale.Language.getLength() )
553
    {
554
        OUStringBuffer aLang(6);
555
        aLang.append( rLocale.Language );
556
        if( rLocale.Country.getLength() )
557
        {
558
            aLang.append( sal_Unicode('-') );
559
            aLang.append( rLocale.Country );
560
        }
561
        aLangAttrib = OUStringToOString( aLang.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
562
    }
563
    if( aLangAttrib.getLength() )
564
        rWrapper.FcPatternAddString( pPattern, FC_LANG, (FcChar8*)aLangAttrib.getStr() );
565
566
    OString aFamily = OUStringToOString( rInfo.m_aFamilyName, RTL_TEXTENCODING_UTF8 );
567
    if( aFamily.getLength() )
568
        rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)aFamily.getStr() );
569
    if( rInfo.m_eItalic != italic::Unknown )
570
    {
599
    {
571
        int nSlant = FC_SLANT_ROMAN;
600
        int nSlant = FC_SLANT_ROMAN;
572
        switch( rInfo.m_eItalic )
601
        switch( eItalic )
573
        {
602
        {
574
            case italic::Italic:	 	nSlant = FC_SLANT_ITALIC;break;
603
            case italic::Italic:	 	nSlant = FC_SLANT_ITALIC;break;
575
            case italic::Oblique:	 	nSlant = FC_SLANT_OBLIQUE;break;
604
            case italic::Oblique:	 	nSlant = FC_SLANT_OBLIQUE;break;
Lines 578-587 bool PrintFontManager::matchFont( FastPr Link Here
578
        }
607
        }
579
        rWrapper.FcPatternAddInteger( pPattern, FC_SLANT, nSlant );
608
        rWrapper.FcPatternAddInteger( pPattern, FC_SLANT, nSlant );
580
    }
609
    }
581
    if( rInfo.m_eWeight != weight::Unknown )
610
    if( eWeight != weight::Unknown )
582
    {
611
    {
583
        int nWeight = FC_WEIGHT_NORMAL;
612
        int nWeight = FC_WEIGHT_NORMAL;
584
        switch( rInfo.m_eWeight )
613
        switch( eWeight )
585
        {
614
        {
586
            case weight::Thin:			nWeight = FC_WEIGHT_THIN;break;
615
            case weight::Thin:			nWeight = FC_WEIGHT_THIN;break;
587
            case weight::UltraLight:	nWeight = FC_WEIGHT_ULTRALIGHT;break;
616
            case weight::UltraLight:	nWeight = FC_WEIGHT_ULTRALIGHT;break;
Lines 598-607 bool PrintFontManager::matchFont( FastPr Link Here
598
        }
627
        }
599
        rWrapper.FcPatternAddInteger( pPattern, FC_WEIGHT, nWeight );
628
        rWrapper.FcPatternAddInteger( pPattern, FC_WEIGHT, nWeight );
600
    }
629
    }
601
    if( rInfo.m_eWidth != width::Unknown )
630
    if( eWidth != width::Unknown )
602
    {
631
    {
603
        int nWidth = FC_WIDTH_NORMAL;
632
        int nWidth = FC_WIDTH_NORMAL;
604
        switch( rInfo.m_eWidth )
633
        switch( eWidth )
605
        {
634
        {
606
            case width::UltraCondensed:	nWidth = FC_WIDTH_ULTRACONDENSED;break;
635
            case width::UltraCondensed:	nWidth = FC_WIDTH_ULTRACONDENSED;break;
607
            case width::ExtraCondensed: nWidth = FC_WIDTH_EXTRACONDENSED;break;
636
            case width::ExtraCondensed: nWidth = FC_WIDTH_EXTRACONDENSED;break;
Lines 617-626 bool PrintFontManager::matchFont( FastPr Link Here
617
        }
646
        }
618
        rWrapper.FcPatternAddInteger( pPattern, FC_WIDTH, nWidth );
647
        rWrapper.FcPatternAddInteger( pPattern, FC_WIDTH, nWidth );
619
    }
648
    }
620
    if( rInfo.m_ePitch != pitch::Unknown )
649
    if( ePitch != pitch::Unknown )
621
    {
650
    {
622
        int nSpacing = FC_PROPORTIONAL;
651
        int nSpacing = FC_PROPORTIONAL;
623
        switch( rInfo.m_ePitch )
652
        switch( ePitch )
624
        {
653
        {
625
            case pitch::Fixed:			nSpacing = FC_MONO;break;
654
            case pitch::Fixed:			nSpacing = FC_MONO;break;
626
            case pitch::Variable:		nSpacing = FC_PROPORTIONAL;break;
655
            case pitch::Variable:		nSpacing = FC_PROPORTIONAL;break;
Lines 628-639 bool PrintFontManager::matchFont( FastPr Link Here
628
                break;
657
                break;
629
        }
658
        }
630
        rWrapper.FcPatternAddInteger( pPattern, FC_SPACING, nSpacing );
659
        rWrapper.FcPatternAddInteger( pPattern, FC_SPACING, nSpacing );
660
        if (nSpacing == FC_MONO)
661
            rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)"monospace");
631
    }
662
    }
663
#endif
664
}
665
666
String PrintFontManager::Substitute(const std::vector<String> &rNames, const std::vector<sal_Unicode> &rGlyphs,
667
        const ByteString &rLangAttrib, italic::type eItalic, weight::type eWeight,
668
        width::type eWidth, pitch::type ePitch) const
669
{
670
    String aName;
671
#ifdef ENABLE_FONTCONFIG
672
    FontCfgWrapper& rWrapper = FontCfgWrapper::get();
673
    if( ! rWrapper.isValid() )
674
        return aName;
675
676
    FcFontSet*  pSet = NULL;
677
    FcPattern*  pPattern = rWrapper.FcPatternCreate();
678
679
    // Prefer scalable fonts
680
    rWrapper.FcPatternAddBool( pPattern, FC_SCALABLE, 1 );
681
682
    std::vector<String>::const_iterator aEnd = rNames.end();
683
    for (std::vector<String>::const_iterator aIter = rNames.begin(); aIter != aEnd; ++aIter)
684
    {
685
	    OString maTargetName = OUStringToOString(*aIter, RTL_TEXTENCODING_UTF8);
686
        rWrapper.FcPatternAddString(pPattern, FC_FAMILY, (FcChar8*)maTargetName.getStr());
687
        break;
688
    }
689
690
    if( rLangAttrib.Len() )
691
        rWrapper.FcPatternAddString(pPattern, FC_LANG, (FcChar8*)rLangAttrib.GetBuffer());
692
693
    // Add required Unicode characters, if any
694
    FcCharSet *unicodes = NULL;
695
    if (! rGlyphs.empty() )
696
    {
697
        unicodes = rWrapper.FcCharSetCreate();
698
	    std::vector<sal_Unicode>::const_iterator aGlyphEnd = rGlyphs.end();
699
	    for (std::vector<sal_Unicode>::const_iterator aGlyphIter = rGlyphs.begin(); 
700
            aGlyphIter != aGlyphEnd; ++aGlyphIter)
701
	    {
702
            rWrapper.FcCharSetAddChar( unicodes, (FcChar32)*aGlyphIter );
703
	    }
704
        rWrapper.FcPatternAddCharSet( pPattern, FC_CHARSET, unicodes);
705
    }
706
707
    addtopattern(rWrapper, pPattern, eItalic, eWeight, eWidth, ePitch);
708
709
    rWrapper.FcConfigSubstitute( NULL, pPattern, FcMatchPattern );
710
    rWrapper.FcDefaultSubstitute( pPattern );
711
    FcResult eResult = FcResultNoMatch;
712
    FcFontSet *pFontSet = rWrapper.getFontSet();
713
    FcPattern* pResult = rWrapper.FcFontSetMatch( NULL, &pFontSet, 1, pPattern, &eResult );
714
    rWrapper.FcPatternDestroy( pPattern );
715
716
    if( pResult )
717
    {
718
        pSet = rWrapper.FcFontSetCreate();
719
        // info: destroying the pSet destroys pResult implicitly
720
        // since pResult was "added" to pSet
721
        rWrapper.FcFontSetAdd( pSet, pResult );
722
    }
723
724
    if( pSet )
725
    {
726
        if( pSet->nfont > 0 )
727
        {
728
            //extract the closest match
729
            FcChar8* family = NULL;
730
            FcResult eFileRes = rWrapper.FcPatternGetString( pSet->fonts[0], FC_FAMILY, 0, &family );
731
            if( eFileRes == FcResultMatch )
732
                aName = String( (sal_Char*)family, RTL_TEXTENCODING_UTF8 );
733
        }
734
    }
735
    rWrapper.FcFontSetDestroy( pSet );
736
#endif
737
    return aName;
738
}
739
740
bool PrintFontManager::matchFont( FastPrintFontInfo& rInfo, const com::sun::star::lang::Locale& rLocale )
741
{
742
#ifdef ENABLE_FONTCONFIG
743
    FontCfgWrapper& rWrapper = FontCfgWrapper::get();
744
    if( ! rWrapper.isValid() )
745
        return false;
746
747
    FcConfig* pConfig = rWrapper.getDefConfig();
748
    FcPattern* pPattern = rWrapper.FcPatternCreate();
749
750
    OString aLangAttrib;
751
    // populate pattern with font characteristics
752
    if( rLocale.Language.getLength() )
753
    {
754
        OUStringBuffer aLang(6);
755
        aLang.append( rLocale.Language );
756
        if( rLocale.Country.getLength() )
757
        {
758
            aLang.append( sal_Unicode('-') );
759
            aLang.append( rLocale.Country );
760
        }
761
        aLangAttrib = OUStringToOString( aLang.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
762
    }
763
    if( aLangAttrib.getLength() )
764
        rWrapper.FcPatternAddString( pPattern, FC_LANG, (FcChar8*)aLangAttrib.getStr() );
765
766
    OString aFamily = OUStringToOString( rInfo.m_aFamilyName, RTL_TEXTENCODING_UTF8 );
767
    if( aFamily.getLength() )
768
        rWrapper.FcPatternAddString( pPattern, FC_FAMILY, (FcChar8*)aFamily.getStr() );
769
770
    addtopattern(rWrapper, pPattern, rInfo.m_eItalic, rInfo.m_eWeight, rInfo.m_eWidth, rInfo.m_ePitch);
632
771
633
    rWrapper.FcConfigSubstitute( pConfig, pPattern, FcMatchPattern );
772
    rWrapper.FcConfigSubstitute( pConfig, pPattern, FcMatchPattern );
634
    rWrapper.FcDefaultSubstitute( pPattern );
773
    rWrapper.FcDefaultSubstitute( pPattern );
635
    FcResult eResult = FcResultNoMatch;
774
    FcResult eResult = FcResultNoMatch;
636
    FcPattern* pResult = rWrapper.FcFontMatch( pConfig, pPattern, &eResult );
775
    FcFontSet *pFontSet = rWrapper.getFontSet();
776
    FcPattern* pResult = rWrapper.FcFontSetMatch( pConfig, &pFontSet, 1, pPattern, &eResult );
637
    bool bSuccess = false;
777
    bool bSuccess = false;
638
    if( pResult )
778
    if( pResult )
639
    {
779
    {

Return to issue 54603