diff options
Diffstat (limited to 'vcl/generic/print/fontsubst.cxx')
-rw-r--r-- | vcl/generic/print/fontsubst.cxx | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/vcl/generic/print/fontsubst.cxx b/vcl/generic/print/fontsubst.cxx new file mode 100644 index 000000000000..5c0dff6f25be --- /dev/null +++ b/vcl/generic/print/fontsubst.cxx @@ -0,0 +1,227 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" +#include "generic/geninst.h" +#include "generic/pspgraphics.h" +#include "generic/glyphcache.hxx" + +#include "vcl/sysdata.hxx" +#include "outfont.hxx" +#include <i18npool/mslangid.hxx> + +#include "generic/printergfx.hxx" +#include "salbmp.hxx" +#include "impfont.hxx" +#include "outfont.hxx" +#include "outdev.h" +#include "fontsubset.hxx" +#include "salprn.hxx" +#include "region.h" + +// =========================================================================== +// platform specific font substitution hooks +// =========================================================================== + +class FcPreMatchSubstititution +: public ImplPreMatchFontSubstitution +{ +public: + bool FindFontSubstitute( ImplFontSelectData& ) const; +}; + +class FcGlyphFallbackSubstititution +: public ImplGlyphFallbackFontSubstitution +{ + // TODO: add a cache +public: + bool FindFontSubstitute( ImplFontSelectData&, OUString& rMissingCodes ) const; +}; + +void RegisterFontSubstitutors( ImplDevFontList* pList ) +{ + // init font substitution defaults + int nDisableBits = 0; +#ifdef SOLARIS + nDisableBits = 1; // disable "font fallback" here on default +#endif + // apply the environment variable if any + const char* pEnvStr = ::getenv( "SAL_DISABLE_FC_SUBST" ); + if( pEnvStr ) + { + if( (*pEnvStr >= '0') && (*pEnvStr <= '9') ) + nDisableBits = (*pEnvStr - '0'); + else + nDisableBits = ~0U; // no specific bits set: disable all + } + + // register font fallback substitutions (unless disabled by bit0) + if( (nDisableBits & 1) == 0 ) + { + static FcPreMatchSubstititution aSubstPreMatch; + pList->SetPreMatchHook( &aSubstPreMatch ); + } + + // register glyph fallback substitutions (unless disabled by bit1) + if( (nDisableBits & 2) == 0 ) + { + static FcGlyphFallbackSubstititution aSubstFallback; + pList->SetFallbackHook( &aSubstFallback ); + } +} + +// ----------------------------------------------------------------------- + +static ImplFontSelectData GetFcSubstitute(const ImplFontSelectData &rFontSelData, OUString& rMissingCodes ) +{ + ImplFontSelectData aRet(rFontSelData); + + const rtl::OString aLangAttrib = MsLangId::convertLanguageToIsoByteString( rFontSelData.meLanguage ); + + FontItalic eItalic = rFontSelData.GetSlant(); + FontWeight eWeight = rFontSelData.GetWeight(); + FontWidth eWidth = rFontSelData.GetWidthType(); + FontPitch ePitch = rFontSelData.GetPitch(); + + const psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + aRet.maSearchName = rMgr.Substitute( rFontSelData.maTargetName, rMissingCodes, aLangAttrib, eItalic, eWeight, eWidth, ePitch); + + aRet.meItalic = eItalic; + aRet.meWeight = eWeight; + aRet.meWidthType = eWidth; + aRet.mePitch = ePitch; + + 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 + ); + } +} + +//-------------------------------------------------------------------------- + +bool FcPreMatchSubstititution::FindFontSubstitute( ImplFontSelectData &rFontSelData ) const +{ + // We dont' actually want to talk to Fontconfig at all for symbol fonts + if( rFontSelData.IsSymbolFont() ) + return false; + // StarSymbol is a unicode font, but it still deserves the symbol flag + if( 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "starsymbol", 10) + || 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) ) + return false; + + //Note: see fdo#41556 if you feel compelled to cache the results here, + //remember that fontconfig can return e.g. an italic font for a non-italic + //input and/or different fonts depending on fontsize, bold, etc settings so + //don't cache just on the name, cache on all the input and be don't just + //return the original selection data with the fontname updated + rtl::OUString aDummy; + const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, aDummy ); + + if( !aOut.maSearchName.Len() ) + return false; + + const bool bHaveSubstitute = !uselessmatch( rFontSelData, aOut ); + +#ifdef DEBUG + const ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); + const ByteString aSubstName( aOut.maSearchName, RTL_TEXTENCODING_UTF8 ); + printf( "FcPreMatchSubstititution \"%s\" bipw=%d%d%d%d -> ", + aOrigName.GetBuffer(), rFontSelData.meWeight, rFontSelData.meItalic, + rFontSelData.mePitch, rFontSelData.meWidthType ); + if( !bHaveSubstitute ) + printf( "no substitute available\n" ); + else + printf( "\"%s\" bipw=%d%d%d%d\n", aSubstName.GetBuffer(), + aOut.meWeight, aOut.meItalic, aOut.mePitch, aOut.meWidthType ); +#endif + + if( bHaveSubstitute ) + rFontSelData = aOut; + + return bHaveSubstitute; +} + +// ----------------------------------------------------------------------- + +bool FcGlyphFallbackSubstititution::FindFontSubstitute( ImplFontSelectData& rFontSelData, + rtl::OUString& rMissingCodes ) const +{ + // We dont' actually want to talk to Fontconfig at all for symbol fonts + if( rFontSelData.IsSymbolFont() ) + return false; + // StarSymbol is a unicode font, but it still deserves the symbol flag + if( 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "starsymbol", 10) + || 0 == rFontSelData.maSearchName.CompareIgnoreCaseToAscii( "opensymbol", 10) ) + return false; + + const ImplFontSelectData aOut = GetFcSubstitute( rFontSelData, rMissingCodes ); + // TODO: cache the unicode + srcfont specific result + // FC doing it would be preferable because it knows the invariables + // e.g. FC knows the FC rule that all Arial gets replaced by LiberationSans + // whereas we would have to check for every size or attribute + if( !aOut.maSearchName.Len() ) + return false; + + const bool bHaveSubstitute = !uselessmatch( rFontSelData, aOut ); + +#ifdef DEBUG + const ByteString aOrigName( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); + const ByteString aSubstName( aOut.maSearchName, RTL_TEXTENCODING_UTF8 ); + printf( "FcGFSubstititution \"%s\" bipw=%d%d%d%d ->", + aOrigName.GetBuffer(), rFontSelData.meWeight, rFontSelData.meItalic, + rFontSelData.mePitch, rFontSelData.meWidthType ); + if( !bHaveSubstitute ) + printf( "no substitute available\n" ); + else + printf( "\"%s\" bipw=%d%d%d%d\n", aSubstName.GetBuffer(), + aOut.meWeight, aOut.meItalic, aOut.mePitch, aOut.meWidthType ); +#endif + + if( bHaveSubstitute ) + rFontSelData = aOut; + + return bHaveSubstitute; +} + +// =========================================================================== + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |