diff options
-rw-r--r-- | vcl/generic/fontmanager/fontconfig.cxx | 47 | ||||
-rw-r--r-- | vcl/generic/glyphs/gcach_layout.cxx | 61 | ||||
-rw-r--r-- | vcl/inc/generic/glyphcache.hxx | 5 |
3 files changed, 89 insertions, 24 deletions
diff --git a/vcl/generic/fontmanager/fontconfig.cxx b/vcl/generic/fontmanager/fontconfig.cxx index fb3bae215270..20e7768f6368 100644 --- a/vcl/generic/fontmanager/fontconfig.cxx +++ b/vcl/generic/fontmanager/fontconfig.cxx @@ -854,6 +854,49 @@ namespace #endif } + //returns true if the given code-point couldn't possibly be in rLangTag. + bool isImpossibleCodePointForLang(const LanguageTag &rLangTag, sal_uInt32 currentChar) + { + //a non-default script is set, lets believe it + if (rLangTag.hasScript()) + return false; + + int32_t script = u_getIntPropertyValue(currentChar, UCHAR_SCRIPT); + UScriptCode eScript = static_cast<UScriptCode>(script); + bool bIsImpossible = false; + OUString sLang = rLangTag.getLanguage(); + switch (eScript) + { + //http://en.wiktionary.org/wiki/Category:Oriya_script_languages + case USCRIPT_ORIYA: + bIsImpossible = + sLang != "or" && + sLang != "kxv"; + break; + //http://en.wiktionary.org/wiki/Category:Telugu_script_languages + case USCRIPT_TELUGU: + bIsImpossible = + sLang != "te" && + sLang != "gon" && + sLang != "kfc"; + break; + //http://en.wiktionary.org/wiki/Category:Bengali_script_languages + case USCRIPT_BENGALI: + bIsImpossible = + sLang != "bn" && + sLang != "as" && + sLang != "bpy" && + sLang != "ctg" && + sLang != "sa"; + break; + default: + break; + } + SAL_WARN_IF(bIsImpossible, "vcl", "Throwing away user set language of " + << sLang << " for finding a font for glyph fallback and autodetecting instead"); + return bIsImpossible; + } + LanguageTag getExemplerLangTagForCodePoint(sal_uInt32 currentChar) { int32_t script = u_getIntPropertyValue(currentChar, UCHAR_SCRIPT); @@ -961,6 +1004,10 @@ bool PrintFontManager::Substitute( FontSelectPattern &rPattern, OUString& rMissi // also handle unicode surrogates const sal_uInt32 nCode = rMissingCodes.iterateCodePoints( &nStrIndex ); FcCharSetAddChar( unicodes, nCode ); + //if the codepoint is impossible for this lang tag, then clear it + //and autodetect something useful + if (!aLangAttrib.isEmpty() && isImpossibleCodePointForLang(aLangTag, nCode)) + aLangAttrib = OString(); //#i105784#/rhbz#527719 improve selection of fallback font if (aLangAttrib.isEmpty()) { diff --git a/vcl/generic/glyphs/gcach_layout.cxx b/vcl/generic/glyphs/gcach_layout.cxx index 833cf4f9a383..848f4cbc51e5 100644 --- a/vcl/generic/glyphs/gcach_layout.cxx +++ b/vcl/generic/glyphs/gcach_layout.cxx @@ -41,6 +41,10 @@ #include <unicode/uscript.h> #include <unicode/ubidi.h> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/i18n/CharacterIteratorMode.hpp> +#include <comphelper/processfactory.hxx> + // ======================================================================= // layout implementation for ServerFont // ======================================================================= @@ -90,23 +94,42 @@ void ServerFontLayout::AdjustLayout( ImplLayoutArgs& rArgs ) } } -// ======================================================================= - -static bool lcl_CharIsJoiner(sal_Unicode cChar) +void ServerFontLayout::setNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nCharPos, + bool bRightToLeft) { - return ((cChar == 0x200C) || (cChar == 0x200D)); -} + if (nCharPos < 0) + return; -static bool needPreviousCode(sal_Unicode cChar) -{ - return lcl_CharIsJoiner(cChar) || U16_IS_LEAD(cChar); -} + using namespace ::com::sun::star; -static bool needNextCode(sal_Unicode cChar) -{ - return lcl_CharIsJoiner(cChar) || U16_IS_TRAIL(cChar); + if (!mxBreak.is()) + { + uno::Reference< lang::XMultiServiceFactory > xFactory = + comphelper::getProcessServiceFactory(); + mxBreak = uno::Reference< i18n::XBreakIterator >(xFactory->createInstance( + "com.sun.star.i18n.BreakIterator"), uno::UNO_QUERY); + } + + LanguageTag aLangTag(rArgs.meLanguage); + lang::Locale aLocale(aLangTag.getLocale()); + + //if position nCharPos is missing in the font, grab the entire grapheme and + //mark all glyphs as missing so the whole thing is rendered with the same + //font + OUString aRun(rArgs.mpStr); + sal_Int32 nDone; + sal_Int32 nGraphemeStartPos = + mxBreak->previousCharacters(aRun, nCharPos+1, aLocale, + i18n::CharacterIteratorMode::SKIPCELL, 1, nDone); + sal_Int32 nGraphemeEndPos = + mxBreak->nextCharacters(aRun, nCharPos, aLocale, + i18n::CharacterIteratorMode::SKIPCELL, 1, nDone); + + rArgs.NeedFallback(nGraphemeStartPos, nGraphemeEndPos, bRightToLeft); } +// ======================================================================= + std::ostream &operator <<(std::ostream& s, ServerFont* pFont) { #ifndef SAL_LOG_INFO @@ -427,9 +450,7 @@ bool HbLayoutEngine::layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs) // if needed request glyph fallback by updating LayoutArgs if (!nGlyphIndex) { - if (nCharPos >= 0) - rArgs.NeedFallback(nCharPos, bRightToLeft); - + rLayout.setNeedFallback(rArgs, nCharPos, bRightToLeft); if (SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags) continue; } @@ -1032,15 +1053,7 @@ bool IcuLayoutEngine::layout(ServerFontLayout& rLayout, ImplLayoutArgs& rArgs) // if needed request glyph fallback by updating LayoutArgs if( !nGlyphIndex ) { - if( nCharPos >= 0 ) - { - rArgs.NeedFallback( nCharPos, bRightToLeft ); - if ( (nCharPos > 0) && needPreviousCode(rArgs.mpStr[nCharPos-1]) ) - rArgs.NeedFallback( nCharPos-1, bRightToLeft ); - else if ( (nCharPos + 1 < nEndRunPos) && needNextCode(rArgs.mpStr[nCharPos+1]) ) - rArgs.NeedFallback( nCharPos+1, bRightToLeft ); - } - + rLayout.setNeedFallback(rArgs, nCharPos, bRightToLeft); if( SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags ) continue; } diff --git a/vcl/inc/generic/glyphcache.hxx b/vcl/inc/generic/glyphcache.hxx index a7363f9bfa42..d6cdee19d6e9 100644 --- a/vcl/inc/generic/glyphcache.hxx +++ b/vcl/inc/generic/glyphcache.hxx @@ -37,6 +37,7 @@ class ImplFontOptions; #include <boost/unordered_map.hpp> #include <boost/unordered_set.hpp> #include <boost/shared_ptr.hpp> +#include <com/sun/star/i18n/XBreakIterator.hpp> namespace basegfx { class B2DPolyPolygon; } @@ -311,6 +312,7 @@ class VCL_DLLPUBLIC ServerFontLayout : public GenericSalLayout { private: ServerFont& mrServerFont; + com::sun::star::uno::Reference<com::sun::star::i18n::XBreakIterator> mxBreak; // enforce proper copy semantic SAL_DLLPRIVATE ServerFontLayout( const ServerFontLayout& ); @@ -323,6 +325,9 @@ public: virtual bool LayoutText( ImplLayoutArgs& ); virtual void AdjustLayout( ImplLayoutArgs& ); virtual void DrawText( SalGraphics& ) const; + void setNeedFallback(ImplLayoutArgs& rArgs, sal_Int32 nIndex, + bool bRightToLeft); + ServerFont& GetServerFont() const { return mrServerFont; } }; |