[Libreoffice-commits] core.git: include/xmloff sc/source xmloff/inc xmloff/source

Eike Rathke erack at redhat.com
Tue Jul 9 06:52:44 PDT 2013


 include/xmloff/languagetagodf.hxx                               |   35 +
 include/xmloff/xmlexp.hxx                                       |   33 +
 include/xmloff/xmltoken.hxx                                     |    2 
 include/xmloff/xmltypes.hxx                                     |    3 
 sc/source/filter/xml/XMLExportDatabaseRanges.cxx                |    5 
 sc/source/filter/xml/xmlimprt.cxx                               |    2 
 sc/source/filter/xml/xmlimprt.hxx                               |    2 
 sc/source/filter/xml/xmlsorti.cxx                               |   23 
 sc/source/filter/xml/xmlsorti.hxx                               |    4 
 xmloff/inc/XMLIndexBibliographyConfigurationContext.hxx         |    3 
 xmloff/source/core/xmlexp.cxx                                   |  105 ++++
 xmloff/source/core/xmltoken.cxx                                 |    2 
 xmloff/source/style/chrlohdl.cxx                                |  260 +++++++++-
 xmloff/source/style/chrlohdl.hxx                                |   22 
 xmloff/source/style/prhdlfac.cxx                                |    6 
 xmloff/source/style/xmlnumfe.cxx                                |   17 
 xmloff/source/style/xmlnumfi.cxx                                |   64 +-
 xmloff/source/text/XMLIndexAlphabeticalSourceContext.cxx        |   14 
 xmloff/source/text/XMLIndexAlphabeticalSourceContext.hxx        |    3 
 xmloff/source/text/XMLIndexBibliographyConfigurationContext.cxx |   21 
 xmloff/source/text/XMLIndexSourceBaseContext.cxx                |    2 
 xmloff/source/text/XMLIndexSourceBaseContext.hxx                |    2 
 xmloff/source/text/XMLSectionExport.cxx                         |   10 
 xmloff/source/text/txtprmap.cxx                                 |   12 
 24 files changed, 573 insertions(+), 79 deletions(-)

New commits:
commit 4935422b410757bb4920b98a2d81da3c11b8e3d7
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Jul 9 15:48:10 2013 +0200

    read/write ODF *:script* and *:rfc-language-tag*
    
    This prepares to be able to read/write the attributes, it does not
    enable proper handling of unknown language tags yet. An unknown tag
    usually falls back to SYSTEM locale.
    
    Change-Id: I4a78e8fd37deae188c69570157bc4589a712bc7a

diff --git a/include/xmloff/languagetagodf.hxx b/include/xmloff/languagetagodf.hxx
new file mode 100644
index 0000000..9eef8e8
--- /dev/null
+++ b/include/xmloff/languagetagodf.hxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+#include <rtl/ustring.hxx>
+#include <i18nlangtag/languagetag.hxx>
+
+/** Helper to gather the single language tag relevant attributes during reading
+    ODF and form a resulting LanguageTag when done.
+
+    For example fo:language, fo:script, fo:country, style:rfc-language-tag
+ */
+struct LanguageTagODF
+{
+    OUString    maRfcLanguageTag;
+    OUString    maLanguage;
+    OUString    maScript;
+    OUString    maCountry;
+
+    bool isEmpty() const { return maRfcLanguageTag.isEmpty() &&
+        maLanguage.isEmpty() && maScript.isEmpty() && maCountry.isEmpty(); }
+
+    /** Best call this only once per instance, it recreates a LanguageTag
+        instance on every call.
+    */
+    LanguageTag getLanguageTag() const { return LanguageTag( maRfcLanguageTag, maLanguage, maScript, maCountry); }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/xmloff/xmlexp.hxx b/include/xmloff/xmlexp.hxx
index 148f736..8a58cfd 100644
--- a/include/xmloff/xmlexp.hxx
+++ b/include/xmloff/xmlexp.hxx
@@ -70,6 +70,7 @@ class XMLEventExport;
 class XMLSettingsExportHelper;
 class XMLImageMapExport;
 class XMLErrors;
+class LanguageTag;
 
 // Shapes in Writer cannot be named via context menu (#i51726#)
 #include <unotools/moduleoptions.hxx>
@@ -77,6 +78,7 @@ class XMLErrors;
 namespace com { namespace sun { namespace star {
     namespace frame { class XModel; }
     namespace container { class XIndexContainer; }
+    namespace lang { struct Locale; }
 } } }
 namespace comphelper { class UnoInterfaceToUniqueIdentifierMapper; }
 
@@ -349,6 +351,37 @@ public:
                        const OUString& rValue );
     void AddAttribute( const OUString& rQName,
                        enum ::xmloff::token::XMLTokenEnum eValue );
+
+    /** Add language tag attributes, deciding which are necessary.
+
+        @param  nPrefix
+                Namespace prefix for *:language, *:script and *:country
+
+        @param  nPrefixRfc
+                Namespace prefix for *:rfc-language-tag
+
+        @param  bWriteEmpty
+                Whether to write empty *:language and *:country attribute
+                values in case of an empty locale (denoting system).
+
+        @param  eClass
+                default, XML_LANGUAGE: XML_SCRIPT, XML_COUNTRY, XML_RFC_LANGUAGE_TAG
+                XML_LANGUAGE_ASIAN: XML_SCRIPT_ASIAN, XML_COUNTRY_ASIAN, XML_RFC_LANGUAGE_TAG_ASIAN
+                    also switches nPrefix XML_NAMESPACE_FO to XML_NAMESPACE_STYLE
+                XML_LANGUAGE_COMPLEX: XML_SCRIPT_COMPLEX, XML_COUNTRY_COMPLEX, XML_RFC_LANGUAGE_TAG_COMPLEX
+                    also switches nPrefix XML_NAMESPACE_FO to XML_NAMESPACE_STYLE
+     */
+    void AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc,
+            const ::com::sun::star::lang::Locale& rLocale, bool bWriteEmpty,
+            enum ::xmloff::token::XMLTokenEnum eClass = ::xmloff::token::XML_LANGUAGE );
+
+    /** Same as AddLanguageTagAttributes() but with LanguageTag parameter
+        instead of Locale.
+     */
+    void AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc,
+            const LanguageTag& rLanguageTag, bool bWriteEmpty,
+            enum ::xmloff::token::XMLTokenEnum eClass = ::xmloff::token::XML_LANGUAGE );
+
     // add several attributes to the common attribute list
     void AddAttributeList( const ::com::sun::star::uno::Reference<
                                   ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index a47dedd..69282ce 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1547,6 +1547,8 @@ namespace xmloff { namespace token {
         XML_SCIENTIFIC_NUMBER,
         XML_SCORE_SPACES,
         XML_SCRIPT,
+        XML_SCRIPT_ASIAN,
+        XML_SCRIPT_COMPLEX,
         XML_SCROLL,
         XML_SDEV,
         XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL,
diff --git a/include/xmloff/xmltypes.hxx b/include/xmloff/xmltypes.hxx
index c20394f..1953af4 100644
--- a/include/xmloff/xmltypes.hxx
+++ b/include/xmloff/xmltypes.hxx
@@ -274,6 +274,9 @@
 #define XML_TYPE_BOOL_FALSE             (XML_TEXT_TYPES_START + 114)
 #define XML_TYPE_FILLSTYLE              (XML_TEXT_TYPES_START + 115)
 
+#define XML_TYPE_CHAR_SCRIPT            (XML_TEXT_TYPES_START + 116)
+#define XML_TYPE_CHAR_RFC_LANGUAGE_TAG  (XML_TEXT_TYPES_START + 117)
+
 #define XML_SCH_TYPES_START (0x4 << XML_TYPE_APP_SHIFT)
 #define XML_PM_TYPES_START  (0x5 << XML_TYPE_APP_SHIFT) // page master
 #define XML_DB_TYPES_START  (0x6 << XML_TYPE_APP_SHIFT)
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 29b8ea6..4fa8b2a 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -325,10 +325,7 @@ private:
         if (aParam.bCaseSens)
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE);
 
-        if (!aParam.aCollatorLocale.Language.isEmpty())
-            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_LANGUAGE, aParam.aCollatorLocale.Language);
-        if (!aParam.aCollatorLocale.Country.isEmpty())
-            mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_COUNTRY, aParam.aCollatorLocale.Country);
+        mrExport.AddLanguageTagAttributes( XML_NAMESPACE_TABLE, XML_NAMESPACE_TABLE, aParam.aCollatorLocale, false);
         if (!aParam.aCollatorAlgorithm.isEmpty())
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ALGORITHM, aParam.aCollatorAlgorithm);
 
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index de77a82..ba46743 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -1408,7 +1408,9 @@ const SvXMLTokenMap& ScXMLImport::GetSortAttrTokenMap()
             { XML_NAMESPACE_TABLE, XML_BIND_STYLES_TO_CONTENT,  XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT    },
             { XML_NAMESPACE_TABLE, XML_TARGET_RANGE_ADDRESS,    XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS      },
             { XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE,          XML_TOK_SORT_ATTR_CASE_SENSITIVE            },
+            { XML_NAMESPACE_TABLE, XML_RFC_LANGUAGE_TAG,        XML_TOK_SORT_ATTR_RFC_LANGUAGE_TAG          },
             { XML_NAMESPACE_TABLE, XML_LANGUAGE,                XML_TOK_SORT_ATTR_LANGUAGE                  },
+            { XML_NAMESPACE_TABLE, XML_SCRIPT,                  XML_TOK_SORT_ATTR_SCRIPT                    },
             { XML_NAMESPACE_TABLE, XML_COUNTRY,                 XML_TOK_SORT_ATTR_COUNTRY                   },
             { XML_NAMESPACE_TABLE, XML_ALGORITHM,               XML_TOK_SORT_ATTR_ALGORITHM                 },
             XML_TOKEN_MAP_END
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index aa85f7e..6203b61 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -509,7 +509,9 @@ enum ScXMLSortAttrTokens
     XML_TOK_SORT_ATTR_BIND_STYLES_TO_CONTENT,
     XML_TOK_SORT_ATTR_TARGET_RANGE_ADDRESS,
     XML_TOK_SORT_ATTR_CASE_SENSITIVE,
+    XML_TOK_SORT_ATTR_RFC_LANGUAGE_TAG,
     XML_TOK_SORT_ATTR_LANGUAGE,
+    XML_TOK_SORT_ATTR_SCRIPT,
     XML_TOK_SORT_ATTR_COUNTRY,
     XML_TOK_SORT_ATTR_ALGORITHM
 };
diff --git a/sc/source/filter/xml/xmlsorti.cxx b/sc/source/filter/xml/xmlsorti.cxx
index e87ba23..175966f 100644
--- a/sc/source/filter/xml/xmlsorti.cxx
+++ b/sc/source/filter/xml/xmlsorti.cxx
@@ -45,8 +45,6 @@ ScXMLSortContext::ScXMLSortContext( ScXMLImport& rImport,
                                         ScXMLDatabaseRangeContext* pTempDatabaseRangeContext) :
     SvXMLImportContext( rImport, nPrfx, rLName ),
     pDatabaseRangeContext(pTempDatabaseRangeContext),
-    sCountry(),
-    sLanguage(),
     sAlgorithm(),
     nUserListIndex(0),
     bCopyOutputData(false),
@@ -87,11 +85,17 @@ ScXMLSortContext::ScXMLSortContext( ScXMLImport& rImport,
                 bIsCaseSensitive = IsXMLToken(sValue, XML_TRUE);
             }
             break;
+            case XML_TOK_SORT_ATTR_RFC_LANGUAGE_TAG :
+                maLanguageTagODF.maRfcLanguageTag = sValue;
+            break;
             case XML_TOK_SORT_ATTR_LANGUAGE :
-                sLanguage = sValue;
+                maLanguageTagODF.maLanguage = sValue;
+            break;
+            case XML_TOK_SORT_ATTR_SCRIPT :
+                maLanguageTagODF.maScript = sValue;
             break;
             case XML_TOK_SORT_ATTR_COUNTRY :
-                sCountry = sValue;
+                maLanguageTagODF.maCountry = sValue;
             break;
             case XML_TOK_SORT_ATTR_ALGORITHM :
                 sAlgorithm = sValue;
@@ -130,11 +134,9 @@ SvXMLImportContext *ScXMLSortContext::CreateChildContext( sal_uInt16 nPrefix,
 
 void ScXMLSortContext::EndElement()
 {
-    sal_Int32 nLangLength(sLanguage.getLength());
-    sal_Int32 nCountryLength(sCountry.getLength());
     sal_Int32 nAlgoLength(sAlgorithm.getLength());
     sal_uInt8 i (0);
-    if (nLangLength || nCountryLength)
+    if (!maLanguageTagODF.isEmpty())
         ++i;
     if (nAlgoLength)
         ++i;
@@ -153,13 +155,10 @@ void ScXMLSortContext::EndElement()
     aSortDescriptor[5].Value <<= nUserListIndex;
     aSortDescriptor[6].Name = OUString(SC_UNONAME_SORTFLD);
     aSortDescriptor[6].Value <<= aSortFields;
-    if (nLangLength || nCountryLength)
+    if (!maLanguageTagODF.isEmpty())
     {
-        lang::Locale aLocale;
-        aLocale.Language = sLanguage;
-        aLocale.Country = sCountry;
         aSortDescriptor[7].Name = OUString(SC_UNONAME_COLLLOC);
-        aSortDescriptor[7].Value <<= aLocale;
+        aSortDescriptor[7].Value <<= maLanguageTagODF.getLanguageTag().getLocale( false);
     }
     if (nAlgoLength)
     {
diff --git a/sc/source/filter/xml/xmlsorti.hxx b/sc/source/filter/xml/xmlsorti.hxx
index 4197968..de952a4 100644
--- a/sc/source/filter/xml/xmlsorti.hxx
+++ b/sc/source/filter/xml/xmlsorti.hxx
@@ -21,6 +21,7 @@
 
 #include <xmloff/xmlictxt.hxx>
 #include <xmloff/xmlimp.hxx>
+#include <xmloff/languagetagodf.hxx>
 #include <com/sun/star/util/SortField.hpp>
 #include <com/sun/star/table/CellAddress.hpp>
 
@@ -34,8 +35,7 @@ class ScXMLSortContext : public SvXMLImportContext
 
     com::sun::star::uno::Sequence <com::sun::star::util::SortField> aSortFields;
     com::sun::star::table::CellAddress aOutputPosition;
-    OUString   sCountry;
-    OUString   sLanguage;
+    LanguageTagODF maLanguageTagODF;
     OUString   sAlgorithm;
     sal_Int16   nUserListIndex;
     bool        bCopyOutputData;
diff --git a/xmloff/inc/XMLIndexBibliographyConfigurationContext.hxx b/xmloff/inc/XMLIndexBibliographyConfigurationContext.hxx
index 2c6e671..cc0234e 100644
--- a/xmloff/inc/XMLIndexBibliographyConfigurationContext.hxx
+++ b/xmloff/inc/XMLIndexBibliographyConfigurationContext.hxx
@@ -21,6 +21,7 @@
 #define _XMLOFF_XMLINDEXBIBLIOGRAPHYCONFIGURATIONCONTEXT_HXX_
 
 #include <xmloff/xmlstyle.hxx>
+#include <xmloff/languagetagodf.hxx>
 #include <com/sun/star/uno/Reference.h>
 #include <com/sun/star/uno/Sequence.h>
 #include <com/sun/star/beans/PropertyValue.hpp>
@@ -56,7 +57,7 @@ class XMLIndexBibliographyConfigurationContext : public SvXMLStyleContext
     OUString sSuffix;
     OUString sPrefix;
     OUString sAlgorithm;
-    ::com::sun::star::lang::Locale aLocale;
+    LanguageTagODF maLanguageTagODF;
     sal_Bool bNumberedEntries;
     sal_Bool bSortByPosition;
 
diff --git a/xmloff/source/core/xmlexp.cxx b/xmloff/source/core/xmlexp.cxx
index 7892901..357999b 100644
--- a/xmloff/source/core/xmlexp.cxx
+++ b/xmloff/source/core/xmlexp.cxx
@@ -34,6 +34,7 @@
 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
 #include <com/sun/star/uri/UriReferenceFactory.hpp>
 #include <com/sun/star/util/MeasureUnit.hpp>
+#include <i18nlangtag/languagetag.hxx>
 #include <comphelper/processfactory.hxx>
 #include <xmloff/attrlist.hxx>
 #include <xmloff/nmspmap.hxx>
@@ -1021,6 +1022,110 @@ void SvXMLExport::AddAttribute( const OUString& rQName,
         GetXMLToken(eValue) );
 }
 
+void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc,
+        const ::com::sun::star::lang::Locale& rLocale, bool bWriteEmpty,
+        enum ::xmloff::token::XMLTokenEnum eClass )
+{
+    if (rLocale.Variant.isEmpty())
+    {
+        // Per convention The BCP 47 string is always stored in Variant, if
+        // that is empty we have a plain language-country combination, no need
+        // to convert to LanguageTag first. Also catches the case of empty
+        // locale denoting system locale.
+        xmloff::token::XMLTokenEnum eLanguage, eCountry;
+        switch (eClass)
+        {
+            default:
+            case XML_LANGUAGE:
+                eLanguage = XML_LANGUAGE;
+                eCountry  = XML_COUNTRY;
+                break;
+            case XML_LANGUAGE_ASIAN:
+                eLanguage = XML_LANGUAGE_ASIAN;
+                eCountry  = XML_COUNTRY_ASIAN;
+                if (nPrefix == XML_NAMESPACE_FO)
+                    nPrefix = XML_NAMESPACE_STYLE;
+                break;
+            case XML_LANGUAGE_COMPLEX:
+                eLanguage = XML_LANGUAGE_COMPLEX;
+                eCountry  = XML_COUNTRY_COMPLEX;
+                if (nPrefix == XML_NAMESPACE_FO)
+                    nPrefix = XML_NAMESPACE_STYLE;
+                break;
+        }
+        if (bWriteEmpty || !rLocale.Language.isEmpty())
+            AddAttribute( nPrefix, eLanguage, rLocale.Language);
+        if (bWriteEmpty || !rLocale.Country.isEmpty())
+            AddAttribute( nPrefix, eCountry, rLocale.Country);
+    }
+    else
+    {
+        LanguageTag aLanguageTag( rLocale);
+        AddLanguageTagAttributes( nPrefix, nPrefixRfc, aLanguageTag, bWriteEmpty, eClass);
+    }
+}
+
+void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc,
+        const LanguageTag& rLanguageTag, bool bWriteEmpty, xmloff::token::XMLTokenEnum eClass )
+{
+    xmloff::token::XMLTokenEnum eLanguage, eScript, eCountry, eRfcLanguageTag;
+    switch (eClass)
+    {
+        default:
+        case XML_LANGUAGE:
+            eLanguage       = XML_LANGUAGE;
+            eScript         = XML_SCRIPT;
+            eCountry        = XML_COUNTRY;
+            eRfcLanguageTag = XML_RFC_LANGUAGE_TAG;
+            break;
+        case XML_LANGUAGE_ASIAN:
+            eLanguage       = XML_LANGUAGE_ASIAN;
+            eScript         = XML_SCRIPT_ASIAN;
+            eCountry        = XML_COUNTRY_ASIAN;
+            eRfcLanguageTag = XML_RFC_LANGUAGE_TAG_ASIAN;
+            if (nPrefix == XML_NAMESPACE_FO)
+                nPrefix = XML_NAMESPACE_STYLE;
+            break;
+        case XML_LANGUAGE_COMPLEX:
+            eLanguage       = XML_LANGUAGE_COMPLEX;
+            eScript         = XML_SCRIPT_COMPLEX;
+            eCountry        = XML_COUNTRY_COMPLEX;
+            eRfcLanguageTag = XML_RFC_LANGUAGE_TAG_COMPLEX;
+            if (nPrefix == XML_NAMESPACE_FO)
+                nPrefix = XML_NAMESPACE_STYLE;
+            break;
+    }
+    if (rLanguageTag.isIsoODF())
+    {
+        if (bWriteEmpty || !rLanguageTag.isSystemLocale())
+        {
+            AddAttribute( nPrefix, eLanguage, rLanguageTag.getLanguage());
+            if (rLanguageTag.hasScript())
+                AddAttribute( nPrefix, eScript, rLanguageTag.getScript());
+            if (bWriteEmpty || !rLanguageTag.getCountry().isEmpty())
+                AddAttribute( nPrefix, eCountry, rLanguageTag.getCountry());
+        }
+    }
+    else
+    {
+        AddAttribute( nPrefixRfc, eRfcLanguageTag, rLanguageTag.getBcp47());
+        // Also in case of non-pure-ISO tag store best matching fo: attributes
+        // for consumers not handling *:rfc-language-tag, ensuring that only
+        // valid ISO codes are stored. Here the bWriteEmpty parameter has no
+        // meaning.
+        OUString aLanguage, aCountry;
+        rLanguageTag.getIsoLanguageCountry( aLanguage, aCountry);
+        if (!aLanguage.isEmpty())
+        {
+            AddAttribute( nPrefix, eLanguage, aLanguage);
+            if (rLanguageTag.hasScript())
+                AddAttribute( nPrefix, eScript, rLanguageTag.getScript());
+            if (!aCountry.isEmpty())
+                AddAttribute( nPrefix, eCountry, aCountry);
+        }
+    }
+}
+
 void SvXMLExport::AddAttributeList( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
 {
     if( xAttrList.is())
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 07934bb..2c97507 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1553,6 +1553,8 @@ namespace xmloff { namespace token {
         TOKEN( "scientific-number",               XML_SCIENTIFIC_NUMBER ),
         TOKEN( "score-spaces",                    XML_SCORE_SPACES ),
         TOKEN( "script",                          XML_SCRIPT ),
+        TOKEN( "script-asian",                    XML_SCRIPT_ASIAN ),
+        TOKEN( "script-complex",                  XML_SCRIPT_COMPLEX ),
         TOKEN( "scroll",                          XML_SCROLL ),
         TOKEN( "sdev",                            XML_SDEV ),
         TOKEN( "search-criteria-must-apply-to-whole-cell",        XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL ),
diff --git a/xmloff/source/style/chrlohdl.cxx b/xmloff/source/style/chrlohdl.cxx
index 9a70272..9fd0cfe 100644
--- a/xmloff/source/style/chrlohdl.cxx
+++ b/xmloff/source/style/chrlohdl.cxx
@@ -20,6 +20,7 @@
 #include <chrlohdl.hxx>
 #include <xmloff/xmltoken.hxx>
 #include <xmloff/xmluconv.hxx>
+#include <i18nlangtag/languagetag.hxx>
 #include <rtl/ustrbuf.hxx>
 #include <com/sun/star/uno/Any.hxx>
 #include <com/sun/star/lang/Locale.hpp>
@@ -28,10 +29,19 @@
 using namespace ::com::sun::star;
 using namespace ::xmloff::token;
 
-///////////////////////////////////////////////////////////////////////////////
-//
-// class XMLEscapementPropHdl
-//
+
+/* TODO-BCP47: this fiddling with Locale is quite ugly and fragile, especially
+ * for the fo:script temporarily stored in Variant, it would be better to use
+ * LanguageTagODF but we have that nasty UNO API requirement here.
+ * => make LanguageTagODF (unpublished) API? */
+
+
+// For runtime performance, instead of converting back and forth between
+// com::sun::star::Locale and LanguageTag to decide if script or tag are
+// needed, this code takes advantage of knowledge about the internal
+// representation of BCP 47 language tags in a Locale if present as done in a
+// LanguageTag.
+
 
 XMLCharLanguageHdl::~XMLCharLanguageHdl()
 {
@@ -44,7 +54,25 @@ bool XMLCharLanguageHdl::equals( const ::com::sun::star::uno::Any& r1, const ::c
     lang::Locale aLocale1, aLocale2;
 
     if( ( r1 >>= aLocale1 ) && ( r2 >>= aLocale2 ) )
-        bRet = ( aLocale1.Language == aLocale2.Language );
+    {
+        bool bEmptyOrScriptVariant1 = (aLocale1.Variant.isEmpty() || aLocale1.Variant[0] == '-');
+        bool bEmptyOrScriptVariant2 = (aLocale2.Variant.isEmpty() || aLocale2.Variant[0] == '-');
+        if (bEmptyOrScriptVariant1 && bEmptyOrScriptVariant2)
+            bRet = ( aLocale1.Language == aLocale2.Language );
+        else
+        {
+            OUString aLanguage1, aLanguage2;
+            if (bEmptyOrScriptVariant1)
+                aLanguage1 = aLocale1.Language;
+            else
+                aLanguage1 = LanguageTag( aLocale1).getLanguage();
+            if (bEmptyOrScriptVariant2)
+                aLanguage2 = aLocale2.Language;
+            else
+                aLanguage2 = LanguageTag( aLocale2).getLanguage();
+            bRet = ( aLanguage1 == aLanguage2 );
+        }
+    }
 
     return bRet;
 }
@@ -52,11 +80,25 @@ bool XMLCharLanguageHdl::equals( const ::com::sun::star::uno::Any& r1, const ::c
 sal_Bool XMLCharLanguageHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& ) const
 {
     lang::Locale aLocale;
-
     rValue >>= aLocale;
 
     if( !IsXMLToken(rStrImpValue, XML_NONE) )
-        aLocale.Language = rStrImpValue;
+    {
+        if (aLocale.Variant.isEmpty())
+            aLocale.Language = rStrImpValue;
+        else
+        {
+            if (!aLocale.Language.isEmpty() || aLocale.Variant[0] != '-')
+                SAL_WARN( "xmloff.style", "XMLCharLanguageHdl::importXML - attempt to import language twice");
+            else
+            {
+                aLocale.Variant = rStrImpValue + aLocale.Variant;
+                if (!aLocale.Country.isEmpty())
+                    aLocale.Variant += "-" + aLocale.Country;
+                aLocale.Language = I18NLANGTAG_QLT;
+            }
+        }
+    }
 
     rValue <<= aLocale;
     return sal_True;
@@ -68,7 +110,127 @@ sal_Bool XMLCharLanguageHdl::exportXML( OUString& rStrExpValue, const uno::Any&
     if(!(rValue >>= aLocale))
         return sal_False;
 
-    rStrExpValue = aLocale.Language;
+    if (aLocale.Variant.isEmpty())
+        rStrExpValue = aLocale.Language;
+    else
+    {
+        LanguageTag aLanguageTag( aLocale);
+        OUString aCountry;
+        aLanguageTag.getIsoLanguageCountry( rStrExpValue, aCountry);
+    }
+
+    if( rStrExpValue.isEmpty() )
+        rStrExpValue = GetXMLToken( XML_NONE );
+
+    return sal_True;
+}
+
+// ===========================================================================
+
+XMLCharScriptHdl::~XMLCharScriptHdl()
+{
+    // nothing to do
+}
+
+bool XMLCharScriptHdl::equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const
+{
+    sal_Bool bRet = sal_False;
+    lang::Locale aLocale1, aLocale2;
+
+    if( ( r1 >>= aLocale1 ) && ( r2 >>= aLocale2 ) )
+    {
+        bool bEmptyVariant1 = aLocale1.Variant.isEmpty();
+        bool bEmptyVariant2 = aLocale2.Variant.isEmpty();
+        if (bEmptyVariant1 && bEmptyVariant2)
+            bRet = sal_True;
+        else if ((bEmptyVariant1 && !bEmptyVariant2) || (!bEmptyVariant1 && bEmptyVariant2))
+            ;   // stays false
+        else
+        {
+            OUString aScript1, aScript2;
+            if (aLocale1.Variant[0] == '-')
+                aScript1 = aLocale1.Variant.copy(1);
+            else
+                aScript1 = LanguageTag( aLocale1).getScript();
+            if (aLocale2.Variant[0] == '-')
+                aScript2 = aLocale2.Variant.copy(1);
+            else
+                aScript2 = LanguageTag( aLocale2).getScript();
+            bRet = ( aScript1 == aScript2 );
+        }
+    }
+
+    return bRet;
+}
+
+sal_Bool XMLCharScriptHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& ) const
+{
+    lang::Locale aLocale;
+    rValue >>= aLocale;
+
+    if( !IsXMLToken( rStrImpValue, XML_NONE ) )
+    {
+        // Import the script only if we don't have a full BCP 47 language tag
+        // in Variant yet.
+        if (aLocale.Variant.isEmpty())
+        {
+            if (aLocale.Language.isEmpty())
+            {
+                SAL_INFO( "xmloff.style", "XMLCharScriptHdl::importXML - script but no language yet");
+                // Temporarily store in Variant and hope the best (we will get
+                // a language later, yes?)
+                aLocale.Variant = "-" + rStrImpValue;
+            }
+            else
+            {
+                aLocale.Variant = aLocale.Language + "-" + rStrImpValue;
+                if (!aLocale.Country.isEmpty())
+                    aLocale.Variant += "-" + aLocale.Country;
+                aLocale.Language = I18NLANGTAG_QLT;
+            }
+        }
+        else if (aLocale.Variant[0] == '-')
+        {
+            SAL_WARN( "xmloff.style", "XMLCharScriptHdl::importXML - attempt to insert script twice: "
+                    << rStrImpValue << " -> " << aLocale.Variant);
+        }
+        else
+        {
+            // Assume that if there already is a script or anything else BCP 47
+            // it was read by XMLCharRfcLanguageTagHdl() and takes precedence.
+            // On the other hand, an *:rfc-language-tag without script and a
+            // *:script ?!?
+#if OSL_DEBUG_LEVEL > 0 || defined(DBG_UTIL)
+            LanguageTag aLanguageTag( aLocale);
+            if (!aLanguageTag.hasScript())
+            {
+                SAL_WARN( "xmloff.style", "XMLCharScriptHdl::importXML - attempt to insert script over bcp47: "
+                        << rStrImpValue << " -> " << aLanguageTag.getBcp47());
+            }
+#endif
+        }
+    }
+
+    rValue <<= aLocale;
+    return sal_True;
+}
+
+sal_Bool XMLCharScriptHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& ) const
+{
+    lang::Locale aLocale;
+    if(!(rValue >>= aLocale))
+        return sal_False;
+
+    // Do not write script='none' for default script.
+
+    if (aLocale.Variant.isEmpty())
+        return sal_False;
+
+    LanguageTag aLanguageTag( aLocale);
+    if (!aLanguageTag.hasScript())
+        return sal_False;
+
+    rStrExpValue = aLanguageTag.getScript();
 
     if( rStrExpValue.isEmpty() )
         rStrExpValue = GetXMLToken( XML_NONE );
@@ -76,10 +238,7 @@ sal_Bool XMLCharLanguageHdl::exportXML( OUString& rStrExpValue, const uno::Any&
     return sal_True;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-//
-// class XMLEscapementHeightPropHdl
-//
+// ===========================================================================
 
 XMLCharCountryHdl::~XMLCharCountryHdl()
 {
@@ -100,11 +259,27 @@ bool XMLCharCountryHdl::equals( const ::com::sun::star::uno::Any& r1, const ::co
 sal_Bool XMLCharCountryHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& ) const
 {
     lang::Locale aLocale;
-
     rValue >>= aLocale;
 
     if( !IsXMLToken( rStrImpValue, XML_NONE ) )
-        aLocale.Country = rStrImpValue;
+    {
+        if (aLocale.Country.isEmpty())
+        {
+            aLocale.Country = rStrImpValue;
+            if (aLocale.Variant.getLength() >= 7 && aLocale.Language == I18NLANGTAG_QLT)
+            {
+                // already assembled language tag, at least ll-Ssss and not
+                // ll-CC or lll-CC
+                sal_Int32 i = aLocale.Variant.indexOf('-');     // separator to script
+                if (2 <= i && i < aLocale.Variant.getLength())
+                {
+                    i = aLocale.Variant.indexOf( '-', i+1);
+                    if (i < 0)                                  // no other separator
+                        aLocale.Variant += "-" + rStrImpValue;  // append country
+                }
+            }
+        }
+    }
 
     rValue <<= aLocale;
     return sal_True;
@@ -116,7 +291,14 @@ sal_Bool XMLCharCountryHdl::exportXML( OUString& rStrExpValue, const uno::Any& r
     if(!(rValue >>= aLocale))
         return sal_False;
 
-    rStrExpValue = aLocale.Country;
+    if (aLocale.Variant.isEmpty())
+        rStrExpValue = aLocale.Country;
+    else
+    {
+        LanguageTag aLanguageTag( aLocale);
+        OUString aLanguage;
+        aLanguageTag.getIsoLanguageCountry( aLanguage, rStrExpValue);
+    }
 
     if( rStrExpValue.isEmpty() )
         rStrExpValue = GetXMLToken( XML_NONE );
@@ -124,4 +306,52 @@ sal_Bool XMLCharCountryHdl::exportXML( OUString& rStrExpValue, const uno::Any& r
     return sal_True;
 }
 
+// ===========================================================================
+
+XMLCharRfcLanguageTagHdl::~XMLCharRfcLanguageTagHdl()
+{
+    // nothing to do
+}
+
+bool XMLCharRfcLanguageTagHdl::equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const
+{
+    sal_Bool bRet = sal_False;
+    lang::Locale aLocale1, aLocale2;
+
+    if( ( r1 >>= aLocale1 ) && ( r2 >>= aLocale2 ) )
+        bRet = ( aLocale1.Variant == aLocale2.Variant );
+
+    return bRet;
+}
+
+sal_Bool XMLCharRfcLanguageTagHdl::importXML( const OUString& rStrImpValue, uno::Any& rValue, const SvXMLUnitConverter& ) const
+{
+    lang::Locale aLocale;
+    rValue >>= aLocale;
+
+    if( !IsXMLToken( rStrImpValue, XML_NONE ) )
+    {
+        aLocale.Variant = rStrImpValue;
+        aLocale.Language = I18NLANGTAG_QLT;
+    }
+
+    rValue <<= aLocale;
+    return sal_True;
+}
+
+sal_Bool XMLCharRfcLanguageTagHdl::exportXML( OUString& rStrExpValue, const uno::Any& rValue, const SvXMLUnitConverter& ) const
+{
+    lang::Locale aLocale;
+    if(!(rValue >>= aLocale))
+        return sal_False;
+
+    // Do not write rfc-language-tag='none' if BCP 47 is not needed.
+    if (aLocale.Variant.isEmpty())
+        return sal_False;
+
+    rStrExpValue = aLocale.Variant;
+
+    return sal_True;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/style/chrlohdl.hxx b/xmloff/source/style/chrlohdl.hxx
index 241b962..2588769 100644
--- a/xmloff/source/style/chrlohdl.hxx
+++ b/xmloff/source/style/chrlohdl.hxx
@@ -36,6 +36,17 @@ public:
     virtual sal_Bool exportXML( OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
 };
 
+class XMLCharScriptHdl : public XMLPropertyHandler
+{
+public:
+    virtual ~XMLCharScriptHdl();
+
+    virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+
+    virtual sal_Bool importXML( const OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+    virtual sal_Bool exportXML( OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
 class XMLCharCountryHdl : public XMLPropertyHandler
 {
 public:
@@ -47,6 +58,17 @@ public:
     virtual sal_Bool exportXML( OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
 };
 
+class XMLCharRfcLanguageTagHdl : public XMLPropertyHandler
+{
+public:
+    virtual ~XMLCharRfcLanguageTagHdl();
+
+    virtual bool equals( const ::com::sun::star::uno::Any& r1, const ::com::sun::star::uno::Any& r2 ) const;
+
+    virtual sal_Bool importXML( const OUString& rStrImpValue, ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+    virtual sal_Bool exportXML( OUString& rStrExpValue, const ::com::sun::star::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter ) const;
+};
+
 #endif      // _XMLOFF_PROPERTYHANDLER_CHARLOCALETYPES_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/style/prhdlfac.cxx b/xmloff/source/style/prhdlfac.cxx
index c6bb25f..305a5da 100644
--- a/xmloff/source/style/prhdlfac.cxx
+++ b/xmloff/source/style/prhdlfac.cxx
@@ -368,9 +368,15 @@ const XMLPropertyHandler* XMLPropertyHandlerFactory::CreatePropertyHandler( sal_
         case XML_TYPE_CHAR_HEIGHT_DIFF:
             pPropHdl = new XMLCharHeightDiffHdl;
             break;
+        case XML_TYPE_CHAR_RFC_LANGUAGE_TAG:
+            pPropHdl = new XMLCharRfcLanguageTagHdl;
+            break;
         case XML_TYPE_CHAR_LANGUAGE:
             pPropHdl = new XMLCharLanguageHdl;
             break;
+        case XML_TYPE_CHAR_SCRIPT:
+            pPropHdl = new XMLCharScriptHdl;
+            break;
         case XML_TYPE_CHAR_COUNTRY:
             pPropHdl = new XMLCharCountryHdl;
             break;
diff --git a/xmloff/source/style/xmlnumfe.cxx b/xmloff/source/style/xmlnumfe.cxx
index a71042f..a23e94b 100644
--- a/xmloff/source/style/xmlnumfe.cxx
+++ b/xmloff/source/style/xmlnumfe.cxx
@@ -340,19 +340,8 @@ void SvXMLNumFmtExport::AddLanguageAttr_Impl( sal_Int32 nLang )
 {
     if ( nLang != LANGUAGE_SYSTEM )
     {
-        /* FIXME-BCP47: handle language tags!
-         * ODF now provides fo:script, and rfc-language-tag attribute in case a
-         * locale can't be expressed using these three ISO codes.
-         * Of course these need to be read in xmlnumfi.cxx then..
-         * In general all places using XML_LANGUAGE and XML_COUNTRY need to be
-         * adapted once we really support bcp47. */
-        OUString aLangStr, aCountryStr;
-        LanguageTag( (LanguageType)nLang ).getIsoLanguageCountry( aLangStr, aCountryStr );
-
-        if (!aLangStr.isEmpty())
-            rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_LANGUAGE, aLangStr );
-        if (!aCountryStr.isEmpty())
-            rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_COUNTRY, aCountryStr );
+        rExport.AddLanguageTagAttributes( XML_NAMESPACE_NUMBER, XML_NAMESPACE_NUMBER,
+                LanguageTag( (LanguageType)nLang), false);
     }
 }
 
@@ -1118,6 +1107,8 @@ void SvXMLNumFmtExport::ExportPart_Impl( const SvNumberformat& rFormat, sal_uInt
     rFormat.GetNatNumXml( aAttr, nPart );
     if ( !aAttr.Format.isEmpty() )
     {
+        /* FIXME-BCP47: ODF defines no transliteration-script or
+         * transliteration-rfc-language-tag */
         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_FORMAT,
                               aAttr.Format );
         rExport.AddAttribute( XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_LANGUAGE,
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index 9747063..5d7a98c 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -42,6 +42,7 @@
 #include <xmloff/nmspmap.hxx>
 #include <xmloff/families.hxx>
 #include <xmloff/xmltoken.hxx>
+#include <xmloff/languagetagodf.hxx>
 
 #include <boost/ptr_container/ptr_vector.hpp>
 #include <boost/ptr_container/ptr_set.hpp>
@@ -263,7 +264,9 @@ enum SvXMLStyleTokens
 enum SvXMLStyleAttrTokens
 {
     XML_TOK_STYLE_ATTR_NAME,
+    XML_TOK_STYLE_ATTR_RFC_LANGUAGE_TAG,
     XML_TOK_STYLE_ATTR_LANGUAGE,
+    XML_TOK_STYLE_ATTR_SCRIPT,
     XML_TOK_STYLE_ATTR_COUNTRY,
     XML_TOK_STYLE_ATTR_TITLE,
     XML_TOK_STYLE_ATTR_AUTOMATIC_ORDER,
@@ -271,7 +274,9 @@ enum SvXMLStyleAttrTokens
     XML_TOK_STYLE_ATTR_TRUNCATE_ON_OVERFLOW,
     XML_TOK_STYLE_ATTR_VOLATILE,
     XML_TOK_STYLE_ATTR_TRANSL_FORMAT,
+    XML_TOK_STYLE_ATTR_TRANSL_RFC_LANGUAGE_TAG,
     XML_TOK_STYLE_ATTR_TRANSL_LANGUAGE,
+    XML_TOK_STYLE_ATTR_TRANSL_SCRIPT,
     XML_TOK_STYLE_ATTR_TRANSL_COUNTRY,
     XML_TOK_STYLE_ATTR_TRANSL_STYLE
 };
@@ -287,7 +292,9 @@ enum SvXMLStyleElemAttrTokens
     XML_TOK_ELEM_ATTR_MIN_EXPONENT_DIGITS,
     XML_TOK_ELEM_ATTR_MIN_NUMERATOR_DIGITS,
     XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS,
+    XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG,
     XML_TOK_ELEM_ATTR_LANGUAGE,
+    XML_TOK_ELEM_ATTR_SCRIPT,
     XML_TOK_ELEM_ATTR_COUNTRY,
     XML_TOK_ELEM_ATTR_STYLE,
     XML_TOK_ELEM_ATTR_TEXTUAL,
@@ -545,7 +552,9 @@ const SvXMLTokenMap& SvXMLNumImpData::GetStyleAttrTokenMap()
         {
             //  attributes for a style
             { XML_NAMESPACE_STYLE,  XML_NAME,                  XML_TOK_STYLE_ATTR_NAME                  },
+            { XML_NAMESPACE_NUMBER, XML_RFC_LANGUAGE_TAG,      XML_TOK_STYLE_ATTR_RFC_LANGUAGE_TAG,     },
             { XML_NAMESPACE_NUMBER, XML_LANGUAGE,              XML_TOK_STYLE_ATTR_LANGUAGE              },
+            { XML_NAMESPACE_NUMBER, XML_SCRIPT,                XML_TOK_STYLE_ATTR_SCRIPT                },
             { XML_NAMESPACE_NUMBER, XML_COUNTRY,               XML_TOK_STYLE_ATTR_COUNTRY               },
             { XML_NAMESPACE_NUMBER, XML_TITLE,                 XML_TOK_STYLE_ATTR_TITLE                 },
             { XML_NAMESPACE_NUMBER, XML_AUTOMATIC_ORDER,       XML_TOK_STYLE_ATTR_AUTOMATIC_ORDER       },
@@ -553,7 +562,9 @@ const SvXMLTokenMap& SvXMLNumImpData::GetStyleAttrTokenMap()
             { XML_NAMESPACE_NUMBER, XML_TRUNCATE_ON_OVERFLOW,  XML_TOK_STYLE_ATTR_TRUNCATE_ON_OVERFLOW  },
             { XML_NAMESPACE_STYLE,  XML_VOLATILE,              XML_TOK_STYLE_ATTR_VOLATILE              },
             { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_FORMAT,     XML_TOK_STYLE_ATTR_TRANSL_FORMAT    },
+            // not defined in ODF { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_RFC_LANGUAGE_TAG, XML_TOK_STYLE_ATTR_TRANSL_RFC_LANGUAGE_TAG   },
             { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_LANGUAGE,   XML_TOK_STYLE_ATTR_TRANSL_LANGUAGE  },
+            // not defined in ODF { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_SCRIPT,     XML_TOK_STYLE_ATTR_TRANSL_SCRIPT    },
             { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_COUNTRY,    XML_TOK_STYLE_ATTR_TRANSL_COUNTRY   },
             { XML_NAMESPACE_NUMBER, XML_TRANSLITERATION_STYLE,      XML_TOK_STYLE_ATTR_TRANSL_STYLE     },
             XML_TOKEN_MAP_END
@@ -580,7 +591,9 @@ const SvXMLTokenMap& SvXMLNumImpData::GetStyleElemAttrTokenMap()
             { XML_NAMESPACE_NUMBER, XML_MIN_EXPONENT_DIGITS,     XML_TOK_ELEM_ATTR_MIN_EXPONENT_DIGITS  },
             { XML_NAMESPACE_NUMBER, XML_MIN_NUMERATOR_DIGITS,    XML_TOK_ELEM_ATTR_MIN_NUMERATOR_DIGITS },
             { XML_NAMESPACE_NUMBER, XML_MIN_DENOMINATOR_DIGITS,  XML_TOK_ELEM_ATTR_MIN_DENOMINATOR_DIGITS },
+            { XML_NAMESPACE_NUMBER, XML_RFC_LANGUAGE_TAG,        XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG     },
             { XML_NAMESPACE_NUMBER, XML_LANGUAGE,                XML_TOK_ELEM_ATTR_LANGUAGE             },
+            { XML_NAMESPACE_NUMBER, XML_SCRIPT,                  XML_TOK_ELEM_ATTR_SCRIPT               },
             { XML_NAMESPACE_NUMBER, XML_COUNTRY,                 XML_TOK_ELEM_ATTR_COUNTRY              },
             { XML_NAMESPACE_NUMBER, XML_STYLE,                   XML_TOK_ELEM_ATTR_STYLE                },
             { XML_NAMESPACE_NUMBER, XML_TEXTUAL,                 XML_TOK_ELEM_ATTR_TEXTUAL              },
@@ -925,7 +938,7 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
     bLong( sal_False ),
     bTextual( sal_False )
 {
-    OUString sLanguage, sCountry;
+    LanguageTagODF aLanguageTagODF;
     sal_Int32 nAttrVal;
     bool bAttrBool(false);
     sal_uInt16 nAttrEnum;
@@ -982,11 +995,17 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
                 if (::sax::Converter::convertNumber( nAttrVal, sValue, 0 ))
                     aNumInfo.nFracDenominator = nAttrVal;
                 break;
+            case XML_TOK_ELEM_ATTR_RFC_LANGUAGE_TAG:
+                aLanguageTagODF.maRfcLanguageTag = sValue;
+                break;
             case XML_TOK_ELEM_ATTR_LANGUAGE:
-                sLanguage = sValue;
+                aLanguageTagODF.maLanguage = sValue;
+                break;
+            case XML_TOK_ELEM_ATTR_SCRIPT:
+                aLanguageTagODF.maScript = sValue;
                 break;
             case XML_TOK_ELEM_ATTR_COUNTRY:
-                sCountry = sValue;
+                aLanguageTagODF.maCountry = sValue;
                 break;
             case XML_TOK_ELEM_ATTR_STYLE:
                 if ( SvXMLUnitConverter::convertEnum( nAttrEnum, sValue, aStyleValueMap ) )
@@ -1002,11 +1021,11 @@ SvXMLNumFmtElementContext::SvXMLNumFmtElementContext( SvXMLImport& rImport,
         }
     }
 
-    if ( !sLanguage.isEmpty() || !sCountry.isEmpty() )
+    if ( !aLanguageTagODF.isEmpty() )
     {
-        nElementLang = LanguageTag( sLanguage, sCountry ).getLanguageType( false);
+        nElementLang = aLanguageTagODF.getLanguageTag().getLanguageType( false);
         if ( nElementLang == LANGUAGE_DONTKNOW )
-            nElementLang = LANGUAGE_SYSTEM;         //! error handling for invalid locales?
+            nElementLang = LANGUAGE_SYSTEM;         //! error handling for unknown locales?
     }
 }
 
@@ -1305,7 +1324,8 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
     eDateSecs( XML_DEA_NONE ),
     bDateNoDefault( sal_False )
 {
-    OUString sLanguage, sCountry;
+    LanguageTagODF aLanguageTagODF;
+    OUString sNatNumAttrScript, sNatNumAttrRfcLanguageTag;
     ::com::sun::star::i18n::NativeNumberXmlAttributes aNatNumAttr;
     bool bAttrBool(false);
     sal_uInt16 nAttrEnum;
@@ -1324,11 +1344,17 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
         {
             case XML_TOK_STYLE_ATTR_NAME:
                 break;
+            case XML_TOK_STYLE_ATTR_RFC_LANGUAGE_TAG:
+                aLanguageTagODF.maRfcLanguageTag = sValue;
+                break;
             case XML_TOK_STYLE_ATTR_LANGUAGE:
-                sLanguage = sValue;
+                aLanguageTagODF.maLanguage = sValue;
+                break;
+            case XML_TOK_STYLE_ATTR_SCRIPT:
+                aLanguageTagODF.maScript = sValue;
                 break;
             case XML_TOK_STYLE_ATTR_COUNTRY:
-                sCountry = sValue;
+                aLanguageTagODF.maCountry = sValue;
                 break;
             case XML_TOK_STYLE_ATTR_TITLE:
                 sFormatTitle = sValue;
@@ -1354,9 +1380,15 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
             case XML_TOK_STYLE_ATTR_TRANSL_FORMAT:
                 aNatNumAttr.Format = sValue;
                 break;
+            case XML_TOK_STYLE_ATTR_TRANSL_RFC_LANGUAGE_TAG:
+                sNatNumAttrRfcLanguageTag = sValue;
+                break;
             case XML_TOK_STYLE_ATTR_TRANSL_LANGUAGE:
                 aNatNumAttr.Locale.Language = sValue;
                 break;
+            case XML_TOK_STYLE_ATTR_TRANSL_SCRIPT:
+                sNatNumAttrScript = sValue;
+                break;
             case XML_TOK_STYLE_ATTR_TRANSL_COUNTRY:
                 aNatNumAttr.Locale.Country = sValue;
                 break;
@@ -1366,11 +1398,11 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
         }
     }
 
-    if ( !sLanguage.isEmpty() || !sCountry.isEmpty() )
+    if (!aLanguageTagODF.isEmpty())
     {
-        nFormatLang = LanguageTag( sLanguage, sCountry ).getLanguageType( false);
+        nFormatLang = aLanguageTagODF.getLanguageTag().getLanguageType( false);
         if ( nFormatLang == LANGUAGE_DONTKNOW )
-            nFormatLang = LANGUAGE_SYSTEM;          //! error handling for invalid locales?
+            nFormatLang = LANGUAGE_SYSTEM;          //! error handling for unknown locales?
     }
 
     if ( !aNatNumAttr.Format.isEmpty() )
@@ -1378,13 +1410,17 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
         SvNumberFormatter* pFormatter = pData->GetNumberFormatter();
         if ( pFormatter )
         {
+            LanguageTag aLanguageTag( sNatNumAttrRfcLanguageTag, aNatNumAttr.Locale.Language,
+                    sNatNumAttrScript, aNatNumAttr.Locale.Country);
+            aNatNumAttr.Locale = aLanguageTag.getLocale( false);
+
             sal_Int32 nNatNum = pFormatter->GetNatNum()->convertFromXmlAttributes( aNatNumAttr );
             aFormatCode.append( "[NatNum" );
             aFormatCode.append( nNatNum, 10 );
 
-            LanguageType eLang = LanguageTag( aNatNumAttr.Locale ).getLanguageType( false);
+            LanguageType eLang = aLanguageTag.getLanguageType( false);
             if ( eLang == LANGUAGE_DONTKNOW )
-                eLang = LANGUAGE_SYSTEM;            //! error handling for invalid locales?
+                eLang = LANGUAGE_SYSTEM;            //! error handling for unknown locales?
             if ( eLang != nFormatLang && eLang != LANGUAGE_SYSTEM )
             {
                 aFormatCode.append( "][$-" );
diff --git a/xmloff/source/text/XMLIndexAlphabeticalSourceContext.cxx b/xmloff/source/text/XMLIndexAlphabeticalSourceContext.cxx
index 28acc59..b6d71d2 100644
--- a/xmloff/source/text/XMLIndexAlphabeticalSourceContext.cxx
+++ b/xmloff/source/text/XMLIndexAlphabeticalSourceContext.cxx
@@ -172,11 +172,17 @@ void XMLIndexAlphabeticalSourceContext::ProcessAttribute(
         case XML_TOK_INDEXSOURCE_SORT_ALGORITHM:
             sAlgorithm = rValue;
             break;
+        case XML_TOK_INDEXSOURCE_RFC_LANGUAGE_TAG:
+            maLanguageTagODF.maRfcLanguageTag = rValue;
+            break;
         case XML_TOK_INDEXSOURCE_LANGUAGE:
-            aLocale.Language = rValue;
+            maLanguageTagODF.maLanguage = rValue;
+            break;
+        case XML_TOK_INDEXSOURCE_SCRIPT:
+            maLanguageTagODF.maScript = rValue;
             break;
         case XML_TOK_INDEXSOURCE_COUNTRY:
-            aLocale.Country = rValue;
+            maLanguageTagODF.maCountry = rValue;
             break;
 
         default:
@@ -228,9 +234,9 @@ void XMLIndexAlphabeticalSourceContext::EndElement()
         rIndexPropertySet->setPropertyValue(sSortAlgorithm, aAny);
     }
 
-    if ( !aLocale.Language.isEmpty()  && !aLocale.Country.isEmpty() )
+    if ( !maLanguageTagODF.isEmpty() )
     {
-        aAny <<= aLocale;
+        aAny <<= maLanguageTagODF.getLanguageTag().getLocale( false);
         rIndexPropertySet->setPropertyValue(sLocale, aAny);
     }
 
diff --git a/xmloff/source/text/XMLIndexAlphabeticalSourceContext.hxx b/xmloff/source/text/XMLIndexAlphabeticalSourceContext.hxx
index cfc1573..44a1a60 100644
--- a/xmloff/source/text/XMLIndexAlphabeticalSourceContext.hxx
+++ b/xmloff/source/text/XMLIndexAlphabeticalSourceContext.hxx
@@ -21,6 +21,7 @@
 #define _XMLOFF_XMLINDEXALPHABETICALSOURCECONTEXT_HXX_
 
 #include "XMLIndexSourceBaseContext.hxx"
+#include <xmloff/languagetagodf.hxx>
 #include <com/sun/star/uno/Reference.h>
 #include <com/sun/star/lang/Locale.hpp>
 
@@ -48,7 +49,7 @@ class XMLIndexAlphabeticalSourceContext : public XMLIndexSourceBaseContext
     const OUString sSortAlgorithm;
     const OUString sLocale;
 
-    ::com::sun::star::lang::Locale aLocale;
+    LanguageTagODF maLanguageTagODF;
     OUString sAlgorithm;
 
     OUString sMainEntryStyleName;
diff --git a/xmloff/source/text/XMLIndexBibliographyConfigurationContext.cxx b/xmloff/source/text/XMLIndexBibliographyConfigurationContext.cxx
index e838485..1fb9cdf 100644
--- a/xmloff/source/text/XMLIndexBibliographyConfigurationContext.cxx
+++ b/xmloff/source/text/XMLIndexBibliographyConfigurationContext.cxx
@@ -66,7 +66,7 @@ XMLIndexBibliographyConfigurationContext::XMLIndexBibliographyConfigurationConte
         sSuffix(),
         sPrefix(),
         sAlgorithm(),
-        aLocale(),
+        maLanguageTagODF(),
         bNumberedEntries(sal_False),
         bSortByPosition(sal_True)
 {
@@ -133,11 +133,22 @@ void XMLIndexBibliographyConfigurationContext::ProcessAttribute(
     {
         if( IsXMLToken(sLocalName, XML_LANGUAGE) )
         {
-            aLocale.Language = sValue;
+            maLanguageTagODF.maLanguage = sValue;
+        }
+        else if( IsXMLToken(sLocalName, XML_SCRIPT) )
+        {
+            maLanguageTagODF.maScript = sValue;
         }
         else if( IsXMLToken(sLocalName, XML_COUNTRY) )
         {
-            aLocale.Country = sValue;
+            maLanguageTagODF.maCountry = sValue;
+        }
+    }
+    else if( XML_NAMESPACE_STYLE == nPrefix )
+    {
+        if( IsXMLToken(sLocalName, XML_RFC_LANGUAGE_TAG) )
+        {
+            maLanguageTagODF.maRfcLanguageTag = sValue;
         }
     }
 }
@@ -255,9 +266,9 @@ void XMLIndexBibliographyConfigurationContext::CreateAndInsert(sal_Bool)
                 aAny.setValue(&bSortByPosition, ::getBooleanCppuType());
                 xPropSet->setPropertyValue(sIsSortByPosition, aAny);
 
-                if( !aLocale.Language.isEmpty() && !aLocale.Country.isEmpty() )
+                if( !maLanguageTagODF.isEmpty() )
                 {
-                    aAny <<= aLocale;
+                    aAny <<= maLanguageTagODF.getLanguageTag().getLocale( false);
                     xPropSet->setPropertyValue(sLocale, aAny);
                 }
 
diff --git a/xmloff/source/text/XMLIndexSourceBaseContext.cxx b/xmloff/source/text/XMLIndexSourceBaseContext.cxx
index eb44e58..8f93b70 100644
--- a/xmloff/source/text/XMLIndexSourceBaseContext.cxx
+++ b/xmloff/source/text/XMLIndexSourceBaseContext.cxx
@@ -132,7 +132,9 @@ static SvXMLTokenMapEntry aIndexSourceTokenMap[] =
           XML_TOK_INDEXSOURCE_USE_INDEX_SOURCE_STYLES },
     { XML_NAMESPACE_TEXT, XML_SORT_ALGORITHM,
           XML_TOK_INDEXSOURCE_SORT_ALGORITHM },
+    { XML_NAMESPACE_STYLE, XML_RFC_LANGUAGE_TAG, XML_TOK_INDEXSOURCE_RFC_LANGUAGE_TAG },
     { XML_NAMESPACE_FO, XML_LANGUAGE, XML_TOK_INDEXSOURCE_LANGUAGE },
+    { XML_NAMESPACE_FO, XML_SCRIPT, XML_TOK_INDEXSOURCE_SCRIPT },
     { XML_NAMESPACE_FO, XML_COUNTRY, XML_TOK_INDEXSOURCE_COUNTRY },
     { XML_NAMESPACE_TEXT, XML_INDEX_NAME, XML_TOK_INDEXSOURCE_USER_INDEX_NAME },
     { XML_NAMESPACE_TEXT,
diff --git a/xmloff/source/text/XMLIndexSourceBaseContext.hxx b/xmloff/source/text/XMLIndexSourceBaseContext.hxx
index 31ffd26..539338c 100644
--- a/xmloff/source/text/XMLIndexSourceBaseContext.hxx
+++ b/xmloff/source/text/XMLIndexSourceBaseContext.hxx
@@ -61,7 +61,9 @@ enum IndexSourceParamEnum
     XML_TOK_INDEXSOURCE_COMMA_SEPARATED,
     XML_TOK_INDEXSOURCE_USE_INDEX_SOURCE_STYLES,
     XML_TOK_INDEXSOURCE_SORT_ALGORITHM,
+    XML_TOK_INDEXSOURCE_RFC_LANGUAGE_TAG,
     XML_TOK_INDEXSOURCE_LANGUAGE,
+    XML_TOK_INDEXSOURCE_SCRIPT,
     XML_TOK_INDEXSOURCE_COUNTRY,
     XML_TOK_INDEXSOURCE_USER_INDEX_NAME,
     XML_TOK_INDEXSOURCE_USE_OUTLINE_LEVEL
diff --git a/xmloff/source/text/XMLSectionExport.cxx b/xmloff/source/text/XMLSectionExport.cxx
index 38330c7..f5f763d 100644
--- a/xmloff/source/text/XMLSectionExport.cxx
+++ b/xmloff/source/text/XMLSectionExport.cxx
@@ -710,10 +710,7 @@ void XMLSectionExport::ExportAlphabeticalIndexStart(
         aAny = rPropertySet->getPropertyValue(sLocale);
         Locale aLocale;
         aAny >>= aLocale;
-        GetExport().AddAttribute(XML_NAMESPACE_FO, XML_LANGUAGE,
-                                 aLocale.Language);
-        GetExport().AddAttribute(XML_NAMESPACE_FO, XML_COUNTRY,
-                                 aLocale.Country);
+        GetExport().AddLanguageTagAttributes( XML_NAMESPACE_FO, XML_NAMESPACE_STYLE, aLocale, true);
 
         ExportBaseIndexSource(TEXT_SECTION_TYPE_ALPHABETICAL, rPropertySet);
     }
@@ -1696,10 +1693,7 @@ void XMLSectionExport::ExportBibliographyConfiguration(SvXMLExport& rExport)
             aAny = xPropSet->getPropertyValue(sLocale);
             Locale aLocale;
             aAny >>= aLocale;
-            rExport.AddAttribute(XML_NAMESPACE_FO, XML_LANGUAGE,
-                                     aLocale.Language);
-            rExport.AddAttribute(XML_NAMESPACE_FO, XML_COUNTRY,
-                                     aLocale.Country);
+            rExport.AddLanguageTagAttributes( XML_NAMESPACE_FO, XML_NAMESPACE_STYLE, aLocale, true);
 
             // configuration element
             SvXMLElementExport aElement(rExport, XML_NAMESPACE_TEXT,
diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx
index def8335..079f01b 100644
--- a/xmloff/source/text/txtprmap.cxx
+++ b/xmloff/source/text/txtprmap.cxx
@@ -119,7 +119,9 @@ XMLPropertyMapEntry aXMLParaPropMap[] =
     // RES_CHRATR_KERNING
     MT_E( "CharKerning",        FO,     LETTER_SPACING,     XML_TYPE_TEXT_KERNING, 0 ),
     // RES_CHRATR_LANGUAGE
+    MT_ED( "CharLocale",     STYLE,     RFC_LANGUAGE_TAG,   XML_TYPE_CHAR_RFC_LANGUAGE_TAG|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocale",        FO,     LANGUAGE,           XML_TYPE_CHAR_LANGUAGE|MID_FLAG_MERGE_PROPERTY, 0 ),
+    MT_ED( "CharLocale",        FO,     SCRIPT,             XML_TYPE_CHAR_SCRIPT|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocale",        FO,     COUNTRY,            XML_TYPE_CHAR_COUNTRY|MID_FLAG_MERGE_PROPERTY, 0 ),
     // RES_CHRATR_POSTURE
     MT_E( "CharPosture",        FO,     FONT_STYLE,         XML_TYPE_TEXT_POSTURE, 0 ),
@@ -167,7 +169,9 @@ XMLPropertyMapEntry aXMLParaPropMap[] =
     MT_ED( "CharPropHeightAsian",STYLE, FONT_SIZE_ASIAN,            XML_TYPE_CHAR_HEIGHT_PROP|MID_FLAG_MULTI_PROPERTY, CTF_CHARHEIGHT_REL_CJK ),
     MT_ED( "CharDiffHeightAsian",STYLE,FONT_SIZE_REL_ASIAN,     XML_TYPE_CHAR_HEIGHT_DIFF, CTF_CHARHEIGHT_DIFF_CJK ),
     // RES_CHRATR_CJK_LANGUAGE
+    MT_ED( "CharLocaleAsian",       STYLE,      RFC_LANGUAGE_TAG_ASIAN, XML_TYPE_CHAR_RFC_LANGUAGE_TAG|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocaleAsian",       STYLE,      LANGUAGE_ASIAN,             XML_TYPE_CHAR_LANGUAGE|MID_FLAG_MERGE_PROPERTY, 0 ),
+    MT_ED( "CharLocaleAsian",       STYLE,      SCRIPT_ASIAN,           XML_TYPE_CHAR_SCRIPT|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocaleAsian",       STYLE,      COUNTRY_ASIAN,          XML_TYPE_CHAR_COUNTRY|MID_FLAG_MERGE_PROPERTY, 0 ),
     // RES_CHRATR_CJK_POSTURE
     MT_E( "CharPostureAsian",       STYLE,      FONT_STYLE_ASIAN,           XML_TYPE_TEXT_POSTURE, 0 ),
@@ -185,7 +189,9 @@ XMLPropertyMapEntry aXMLParaPropMap[] =
     MT_ED( "CharPropHeightComplex",STYLE,   FONT_SIZE_COMPLEX,          XML_TYPE_CHAR_HEIGHT_PROP|MID_FLAG_MULTI_PROPERTY, CTF_CHARHEIGHT_REL_CTL ),
     MT_ED( "CharDiffHeightComplex",STYLE,FONT_SIZE_REL_COMPLEX,     XML_TYPE_CHAR_HEIGHT_DIFF, CTF_CHARHEIGHT_DIFF_CTL ),
     // RES_CHRATR_CTL_LANGUAGE
+    MT_ED( "CharLocaleComplex",     STYLE,      RFC_LANGUAGE_TAG_COMPLEX,   XML_TYPE_CHAR_RFC_LANGUAGE_TAG|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocaleComplex",     STYLE,      LANGUAGE_COMPLEX,           XML_TYPE_CHAR_LANGUAGE|MID_FLAG_MERGE_PROPERTY, 0 ),
+    MT_ED( "CharLocaleComplex",     STYLE,      SCRIPT_COMPLEX,             XML_TYPE_CHAR_SCRIPT|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocaleComplex",     STYLE,      COUNTRY_COMPLEX,            XML_TYPE_CHAR_COUNTRY|MID_FLAG_MERGE_PROPERTY, 0 ),
     // RES_CHRATR_CTL_POSTURE
     MT_E( "CharPostureComplex",     STYLE,      FONT_STYLE_COMPLEX,         XML_TYPE_TEXT_POSTURE, 0 ),
@@ -416,7 +422,9 @@ XMLPropertyMapEntry aXMLTextPropMap[] =
     // RES_CHRATR_KERNING
     MT_E( "CharKerning",        FO,     LETTER_SPACING,     XML_TYPE_TEXT_KERNING, 0 ),
     // RES_CHRATR_LANGUAGE
+    MT_ED( "CharLocale",     STYLE,     RFC_LANGUAGE_TAG,   XML_TYPE_CHAR_RFC_LANGUAGE_TAG|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocale",        FO,     LANGUAGE,           XML_TYPE_CHAR_LANGUAGE|MID_FLAG_MERGE_PROPERTY, 0 ),
+    MT_ED( "CharLocale",        FO,     SCRIPT,             XML_TYPE_CHAR_SCRIPT|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocale",        FO,     COUNTRY,            XML_TYPE_CHAR_COUNTRY|MID_FLAG_MERGE_PROPERTY, 0 ),
     // RES_CHRATR_POSTURE
     MT_E( "CharPosture",        FO,     FONT_STYLE,         XML_TYPE_TEXT_POSTURE, 0 ),
@@ -465,7 +473,9 @@ XMLPropertyMapEntry aXMLTextPropMap[] =
     MT_ED( "CharPropHeightAsian",STYLE, FONT_SIZE_ASIAN,            XML_TYPE_CHAR_HEIGHT_PROP|MID_FLAG_MULTI_PROPERTY, CTF_CHARHEIGHT_REL_CJK ),
     MT_ED( "CharDiffHeightAsian",STYLE,FONT_SIZE_REL_ASIAN,     XML_TYPE_CHAR_HEIGHT_DIFF, CTF_CHARHEIGHT_DIFF_CJK ),
     // RES_CHRATR_CJK_LANGUAGE
+    MT_ED( "CharLocaleAsian",       STYLE,      RFC_LANGUAGE_TAG_ASIAN, XML_TYPE_CHAR_RFC_LANGUAGE_TAG|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocaleAsian",       STYLE,      LANGUAGE_ASIAN,             XML_TYPE_CHAR_LANGUAGE|MID_FLAG_MERGE_PROPERTY, 0 ),
+    MT_ED( "CharLocaleAsian",       STYLE,      SCRIPT_ASIAN,           XML_TYPE_CHAR_SCRIPT|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocaleAsian",       STYLE,      COUNTRY_ASIAN,          XML_TYPE_CHAR_COUNTRY|MID_FLAG_MERGE_PROPERTY, 0 ),
     // RES_CHRATR_CJK_POSTURE
     MT_E( "CharPostureAsian",       STYLE,      FONT_STYLE_ASIAN,           XML_TYPE_TEXT_POSTURE, 0 ),
@@ -483,7 +493,9 @@ XMLPropertyMapEntry aXMLTextPropMap[] =
     MT_ED( "CharPropHeightComplex",STYLE,   FONT_SIZE_COMPLEX,          XML_TYPE_CHAR_HEIGHT_PROP|MID_FLAG_MULTI_PROPERTY, CTF_CHARHEIGHT_REL_CTL ),
     MT_ED( "CharDiffHeightComplex",STYLE,FONT_SIZE_REL_COMPLEX,     XML_TYPE_CHAR_HEIGHT_DIFF, CTF_CHARHEIGHT_DIFF_CTL ),
     // RES_CHRATR_CTL_LANGUAGE
+    MT_ED( "CharLocaleComplex",     STYLE,      RFC_LANGUAGE_TAG_COMPLEX,   XML_TYPE_CHAR_RFC_LANGUAGE_TAG|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocaleComplex",     STYLE,      LANGUAGE_COMPLEX,           XML_TYPE_CHAR_LANGUAGE|MID_FLAG_MERGE_PROPERTY, 0 ),
+    MT_ED( "CharLocaleComplex",     STYLE,      SCRIPT_COMPLEX,             XML_TYPE_CHAR_SCRIPT|MID_FLAG_MERGE_PROPERTY, 0 ),
     MT_ED( "CharLocaleComplex",     STYLE,      COUNTRY_COMPLEX,            XML_TYPE_CHAR_COUNTRY|MID_FLAG_MERGE_PROPERTY, 0 ),
     // RES_CHRATR_CTL_POSTURE
     MT_E( "CharPostureComplex",     STYLE,      FONT_STYLE_COMPLEX,         XML_TYPE_TEXT_POSTURE, 0 ),


More information about the Libreoffice-commits mailing list