summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/generic/fontmanager/fontconfig.cxx47
-rw-r--r--vcl/generic/glyphs/gcach_layout.cxx61
-rw-r--r--vcl/inc/generic/glyphcache.hxx5
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; }
};