[Libreoffice-commits] core.git: Branch 'libreoffice-4-1' - vcl/generic vcl/inc

Caolán McNamara caolanm at redhat.com
Wed Oct 23 17:09:23 PDT 2013


 vcl/generic/fontmanager/fontconfig.cxx |   47 +++++++++++++++++++++++++
 vcl/generic/glyphs/gcach_layout.cxx    |   61 ++++++++++++++++++++-------------
 vcl/inc/generic/glyphcache.hxx         |    5 ++
 3 files changed, 89 insertions(+), 24 deletions(-)

New commits:
commit 5a0984fd383e54c130016d15a0b72c230968c61e
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Tue Jun 4 15:48:23 2013 +0100

    fdo#70741 fdo#66042 rhbz#968892: force render full grapheme with fallback font
    
    Related: rhbz#968892 discard impossible languages for oriya script fallback
    Related: rhbz#968892 discard impossible languages for glyph fallback
    Resolves: fdo#66042 get the bounds of the current grapheme
    (also includes Change-Id: I14f1bab09eb0be9c2c896a1dde45913b99aab6df)
    (also includes Change-Id: I5b1808d74f0a1dd0d8b6ea22136e574c0a6e8e2a)
    (also includes Change-Id: I5bb98c61d047e69d74666261b2c489d80f344502)
    
    Change-Id: I46d8cacba2b8ca0f24e1c4ba836839387d74e1a4
    Reviewed-on: https://gerrit.libreoffice.org/6398
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    Reviewed-by: Björn Michaelsen <bjoern.michaelsen at canonical.com>

diff --git a/vcl/generic/fontmanager/fontconfig.cxx b/vcl/generic/fontmanager/fontconfig.cxx
index fb3bae2..20e7768 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 833cf4f..848f4cb 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 a7363f9..d6cdee1 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; }
 };
 


More information about the Libreoffice-commits mailing list