Commits

hdu  committed 30c14ef

#i87970# fix problem with glyph fallback to same font-family (patch by CMC, thanks)

  • Participants
  • Parent commits a4d4c27

Comments (0)

Files changed (4)

File vcl/inc/vcl/fontmanager.hxx

     FontConfigHints getFontConfigHints(const FastPrintFontInfo& rInfo, int nSize, void (*subcallback)(void *));
 
     rtl::OUString Substitute( const rtl::OUString& rFontName, rtl::OUString& rMissingCodes, 
-        const rtl::OString& rLangAttrib, italic::type eItalic, weight::type eWeight, 
-        width::type eWidth, pitch::type ePitch) const;
+        const rtl::OString& rLangAttrib, italic::type& rItalic, weight::type& rWeight, 
+        width::type& rWidth, pitch::type& rPitch) const;
     bool hasFontconfig() const { return m_bFontconfigSuccess; }
 
     int FreeTypeCharIndex( void *pFace, sal_uInt32 aChar );

File vcl/unx/source/fontmanager/fontconfig.cxx

     return true;
 }
 
+namespace
+{
+    weight::type convertWeight(int weight)
+    {
+        // set weight
+        if( weight <= FC_WEIGHT_THIN )
+            return weight::Thin;
+        else if( weight <= FC_WEIGHT_ULTRALIGHT )
+            return weight::UltraLight;
+        else if( weight <= FC_WEIGHT_LIGHT )
+            return weight::Light;
+        else if( weight <= FC_WEIGHT_BOOK )
+            return weight::SemiLight;
+        else if( weight <= FC_WEIGHT_NORMAL )
+            return weight::Normal;
+        else if( weight <= FC_WEIGHT_MEDIUM )
+            return weight::Medium;
+        else if( weight <= FC_WEIGHT_SEMIBOLD )
+            return weight::SemiBold;
+        else if( weight <= FC_WEIGHT_BOLD )
+            return weight::Bold;
+        else if( weight <= FC_WEIGHT_ULTRABOLD )
+            return weight::UltraBold;
+        return weight::Black;
+    }
+
+    italic::type convertSlant(int slant)
+    {
+        // set italic
+        if( slant == FC_SLANT_ITALIC )
+            return italic::Italic;
+        else if( slant == FC_SLANT_OBLIQUE )
+            return italic::Oblique;
+        return italic::Upright;
+    }
+
+    pitch::type convertSpacing(int spacing)
+    {
+        // set pitch
+        if( spacing == FC_MONO || spacing == FC_CHARCELL )
+            return pitch::Fixed;
+        return pitch::Variable;
+    }
+
+    width::type convertWidth(int width)
+    {
+        if (width == FC_WIDTH_ULTRACONDENSED)
+            return width::UltraCondensed;
+        else if (width == FC_WIDTH_EXTRACONDENSED)
+            return width::ExtraCondensed;
+        else if (width == FC_WIDTH_CONDENSED)
+            return width::Condensed;
+        else if (width == FC_WIDTH_SEMICONDENSED)
+            return width::SemiCondensed;
+        else if (width == FC_WIDTH_SEMIEXPANDED)
+            return width::SemiExpanded;
+        else if (width == FC_WIDTH_EXPANDED)
+            return width::Expanded;
+        else if (width == FC_WIDTH_EXTRAEXPANDED)
+            return width::ExtraExpanded;
+        else if (width == FC_WIDTH_ULTRAEXPANDED)
+            return width::UltraExpanded;
+        return width::Normal;
+    }
+}
+
 int PrintFontManager::countFontconfigFonts()
 {
     int nFonts = 0;
                     pUpdate->m_nFamilyName = nFamilyName;
                 }
                 if( eWeightRes == FcResultMatch )
-                {
-                    // set weight
-                    if( weight <= FC_WEIGHT_THIN )
-                        pUpdate->m_eWeight = weight::Thin;
-                    else if( weight <= FC_WEIGHT_ULTRALIGHT )
-                        pUpdate->m_eWeight = weight::UltraLight;
-                    else if( weight <= FC_WEIGHT_LIGHT )
-                        pUpdate->m_eWeight = weight::Light;
-                    else if( weight <= FC_WEIGHT_BOOK )
-                        pUpdate->m_eWeight = weight::SemiLight;
-                    else if( weight <= FC_WEIGHT_NORMAL )
-                        pUpdate->m_eWeight = weight::Normal;
-                    else if( weight <= FC_WEIGHT_MEDIUM )
-                        pUpdate->m_eWeight = weight::Medium;
-                    else if( weight <= FC_WEIGHT_SEMIBOLD )
-                        pUpdate->m_eWeight = weight::SemiBold;
-                    else if( weight <= FC_WEIGHT_BOLD )
-                        pUpdate->m_eWeight = weight::Bold;
-                    else if( weight <= FC_WEIGHT_ULTRABOLD )
-                        pUpdate->m_eWeight = weight::UltraBold;
-                    else
-                        pUpdate->m_eWeight = weight::Black;
-                }
+					pUpdate->m_eWeight = convertWeight(weight);
                 if( eSpacRes == FcResultMatch )
-                {
-                    // set pitch
-                    if( spacing == FC_PROPORTIONAL )
-                        pUpdate->m_ePitch = pitch::Variable;
-                    else if( spacing == FC_MONO || spacing == FC_CHARCELL )
-                        pUpdate->m_ePitch = pitch::Fixed;
-                }
+                    pUpdate->m_ePitch = convertSpacing(spacing);
                 if( eSlantRes == FcResultMatch )
-                {
-                    // set italic
-                    if( slant == FC_SLANT_ROMAN )
-                        pUpdate->m_eItalic = italic::Upright;
-                    else if( slant == FC_SLANT_ITALIC )
-                        pUpdate->m_eItalic = italic::Italic;
-                    else if( slant == FC_SLANT_OBLIQUE )
-                        pUpdate->m_eItalic = italic::Oblique;
-                }
+					pUpdate->m_eItalic = convertSlant(slant);
                 if( eStyleRes == FcResultMatch )
                 {
                     pUpdate->m_aStyleName = OStringToOUString( OString( (sal_Char*)style ), RTL_TEXTENCODING_UTF8 );
 
 rtl::OUString PrintFontManager::Substitute(const rtl::OUString& rFontName,
     rtl::OUString& rMissingCodes, const rtl::OString &rLangAttrib,
-    italic::type eItalic, weight::type eWeight,
-    width::type eWidth, pitch::type ePitch) const
+    italic::type &rItalic, weight::type &rWeight,
+    width::type &rWidth, pitch::type &rPitch) const
 {
     rtl::OUString aName;
     FontCfgWrapper& rWrapper = FontCfgWrapper::get();
        rWrapper.FcCharSetDestroy( unicodes );
     }
 
-    addtopattern(rWrapper, pPattern, eItalic, eWeight, eWidth, ePitch);
+    addtopattern(rWrapper, pPattern, rItalic, rWeight, rWidth, rPitch);
 
     // query fontconfig for a substitute
     rWrapper.FcConfigSubstitute( rWrapper.FcConfigGetCurrent(), pPattern, FcMatchPattern );
                 if (aI != rWrapper.m_aFontNameToLocalized.end())
                     sFamily = aI->second;
                 aName = rtl::OStringToOUString( sFamily, RTL_TEXTENCODING_UTF8 );
+
+
+                int val = 0;
+                if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WEIGHT, 0, &val))
+                    rWeight = convertWeight(val);
+                if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_SLANT, 0, &val))
+                    rItalic = convertSlant(val);
+                if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_SPACING, 0, &val))
+                    rPitch = convertSpacing(val);
+                if ( FcResultMatch == rWrapper.FcPatternGetInteger( pSet->fonts[0], FC_WIDTH, 0, &val))
+                    rWidth = convertWidth(val);
             }
 
 			// update rMissingCodes by removing resolved unicodes

File vcl/unx/source/gdi/pspgraphics.cxx

     }
 }
 
-void PspGraphics::GetFontHints( const ImplFontAttributes& rFontAttributes, int nSize, ImplFontHints& rFontHints) const
+void PspGraphics::GetFontHints( const ImplFontAttributes& /*rFontAttributes*/,
+    int /*nSize*/, ImplFontHints& /*rFontHints*/) const
 {
+    // psprint just exports the fonts including hints
+    // the printer is then free to use the hints any way it wants
+    // AFAIK there is no printer driver that uses the fc-settings for this
 }
 
 void PspGraphics::GetFontMetric( ImplFontMetricData *pMetric )

File vcl/unx/source/gdi/salgdi3.cxx

 
 // -----------------------------------------------------------------------
 
-static rtl::OUString GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUString& rMissingCodes )
+static ImplFontSelectData GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUString& rMissingCodes )
 {
+    ImplFontSelectData aRet(rFontSelData);
+
     const rtl::OString aLangAttrib; //TODO: = MsLangId::convertLanguageToIsoByteString( rFontSelData.meLanguage );
 
     psp::italic::type eItalic = psp::italic::Unknown;
     }
 
     const psp::PrintFontManager& rMgr = psp::PrintFontManager::get();
-    return rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch);
+    aRet.maSearchName = rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch);
+
+    switch (eItalic)
+    {
+        case psp::italic::Upright: aRet.meItalic = ITALIC_NONE; break;
+        case psp::italic::Italic: aRet.meItalic = ITALIC_NORMAL; break;
+        case psp::italic::Oblique: aRet.meItalic = ITALIC_OBLIQUE; break;
+        default:
+            break;
+    }
+
+    switch (eWeight)
+    {
+        case psp::weight::Thin: aRet.meWeight = WEIGHT_THIN; break;
+        case psp::weight::UltraLight: aRet.meWeight = WEIGHT_ULTRALIGHT; break;
+        case psp::weight::Light: aRet.meWeight = WEIGHT_LIGHT; break;
+        case psp::weight::SemiLight: aRet.meWeight = WEIGHT_SEMILIGHT; break;
+        case psp::weight::Normal: aRet.meWeight = WEIGHT_NORMAL; break;
+        case psp::weight::Medium: aRet.meWeight = WEIGHT_MEDIUM; break;
+        case psp::weight::SemiBold: aRet.meWeight = WEIGHT_SEMIBOLD; break;
+        case psp::weight::Bold: aRet.meWeight = WEIGHT_BOLD; break;
+        case psp::weight::UltraBold: aRet.meWeight = WEIGHT_ULTRABOLD; break;
+        case psp::weight::Black: aRet.meWeight = WEIGHT_BLACK; break;
+        default:
+                break;
+    }
+
+    switch (eWidth)
+    {
+        case psp::width::UltraCondensed: aRet.meWidthType = WIDTH_ULTRA_CONDENSED; break;
+        case psp::width::ExtraCondensed: aRet.meWidthType = WIDTH_EXTRA_CONDENSED; break;
+        case psp::width::Condensed: aRet.meWidthType = WIDTH_CONDENSED; break;
+        case psp::width::SemiCondensed: aRet.meWidthType = WIDTH_SEMI_CONDENSED; break;
+        case psp::width::Normal: aRet.meWidthType = WIDTH_NORMAL; break;
+        case psp::width::SemiExpanded: aRet.meWidthType = WIDTH_SEMI_EXPANDED; break;
+        case psp::width::Expanded: aRet.meWidthType = WIDTH_EXPANDED; break;
+        case psp::width::ExtraExpanded: aRet.meWidthType = WIDTH_EXTRA_EXPANDED; break;
+        case psp::width::UltraExpanded: aRet.meWidthType = WIDTH_ULTRA_EXPANDED; break;
+        default:
+            break;
+    }
+
+    switch (ePitch)
+    {
+        case psp::pitch::Fixed: aRet.mePitch = PITCH_FIXED; break;
+        case psp::pitch::Variable: aRet.mePitch = PITCH_VARIABLE; break;
+        default:
+            break;
+    }
+
+    return aRet;
+}
+
+namespace
+{
+    bool uselessmatch(const ImplFontSelectData &rOrig, const ImplFontSelectData &rNew)
+    {
+        return
+          (
+            rOrig.maTargetName == rNew.maSearchName &&
+            rOrig.meWeight == rNew.meWeight &&
+            rOrig.meItalic == rNew.meItalic &&
+            rOrig.mePitch == rNew.mePitch &&
+            rOrig.meWidthType == rNew.meWidthType
+          );
+    }
 }
 
 //--------------------------------------------------------------------------
         return false;
 
     rtl::OUString aDummy;
-    const rtl::OUString aOUName = GetFcSubstitute( rFontSelData, aDummy );
-    if( !aOUName.getLength() )
+    const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, aDummy );
+    if (!aOut.maSearchName.Len())
         return false;
-    const String aName( aOUName );
-    if( aName == rFontSelData.maTargetName )
+    if( uselessmatch(rFontSelData, aOut ) )
         return false;
 
 #ifdef DEBUG
     ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
-    ByteString aSubstName( aName, RTL_TEXTENCODING_UTF8 );
+    ByteString aSubstName( aOut.maSearchName, RTL_TEXTENCODING_UTF8 );
     printf( "FcPreMatchSubstititution \"%s\" -> \"%s\"\n",
         aOrigName.GetBuffer(), aSubstName.GetBuffer() );
 #endif
-    rFontSelData.maSearchName = aName;
+    rFontSelData = aOut;
     return true;
 }
 
     ||  0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) )
         return false;
 
-    const rtl::OUString aOUName = GetFcSubstitute( rFontSelData, rMissingCodes );
+    const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, rMissingCodes );
     // TODO: cache the unicode+font specific result
-    if( !aOUName.getLength() )
+    if (!aOut.maSearchName.Len())
         return false;
-    const String aName( aOUName );
-    if( aName == rFontSelData.maTargetName )
+    if (uselessmatch(rFontSelData, aOut))
         return false;
 
 #ifdef DEBUG
     ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 );
-    ByteString aSubstName( aName, RTL_TEXTENCODING_UTF8 );
+    ByteString aSubstName( aOut.maSearchName, RTL_TEXTENCODING_UTF8 );
     printf( "FcGlyphFallbackSubstititution \"%s\" -> \"%s\"\n",
         aOrigName.GetBuffer(), aSubstName.GetBuffer() );
 #endif
-    rFontSelData.maSearchName = aName;
+    rFontSelData = aOut;
     return true;
 }