editeng/inc/editattr.hxx                              |    8 
 editeng/source/editeng/editattr.cxx                   |    9 
 editeng/source/editeng/editdbg.cxx                    |   10 
 editeng/source/editeng/editdoc.cxx                    |    5 
 editeng/source/editeng/eerdll.cxx                     |    2 
 editeng/source/editeng/impedit2.cxx                   |   19 
 editeng/source/items/textitem.cxx                     |   88 +++
 forms/inc/pch/precompiled_frm.hxx                     |    2 
 forms/source/richtext/richtextimplcontrol.cxx         |    2 
 forms/source/richtext/rtattributehandler.cxx          |    2 
 i18nutil/qa/cppunit/test_scriptchangescanner.cxx      |  424 +++++++++++++++++-
 i18nutil/source/utility/scriptchangescanner.cxx       |   81 +++
 include/editeng/editids.hrc                           |    3 
 include/editeng/editrids.hrc                          |    7 
 include/editeng/eeitem.hxx                            |    4 
 include/editeng/memberids.h                           |    3 
 include/editeng/scripthintitem.hxx                    |   56 ++
 include/editeng/scriptsetitem.hxx                     |    5 
 include/editeng/unoprnms.hxx                          |    2 
 include/editeng/unotext.hxx                           |    3 
 include/i18nutil/scriptchangescanner.hxx              |   46 +
 include/svl/poolitem.hxx                              |    1 
 include/xmloff/xmltoken.hxx                           |    5 
 include/xmloff/xmltypes.hxx                           |    2 
 sc/source/ui/drawfunc/drtxtob.cxx                     |    2 
 sc/source/ui/view/editsh.cxx                          |    2 
 sc/source/ui/view/formatsh.cxx                        |    2 
 sc/source/ui/view/viewfun2.cxx                        |    2 
 sc/source/ui/view/viewutil.cxx                        |    2 
 sd/source/ui/view/drtxtob.cxx                         |    2 
 sd/source/ui/view/drtxtob1.cxx                        |    2 
 solenv/clang-format/excludelist                       |    2 
 sw/inc/charatr.hxx                                    |    3 
 sw/inc/hintids.hxx                                    |  396 ++++++++--------
 sw/inc/inspectorproperties.hrc                        |    1 
 sw/inc/swatrset.hxx                                   |    2 
 sw/inc/unoprnms.hxx                                   |    1 
 sw/qa/extras/odfexport/data/tdf166011.fodt            |  118 +++++
 sw/qa/extras/odfexport/data/tdf166011ee.fodt          |  128 +++++
 sw/qa/extras/odfexport/odfexport4.cxx                 |   26 +
 sw/qa/extras/uiwriter/uiwriter.cxx                    |    2 
 sw/source/core/bastyp/init.cxx                        |    2 
 sw/source/core/inc/swfntcch.hxx                       |    2 
 sw/source/core/text/atrhndl.hxx                       |    2 
 sw/source/core/text/atrstck.cxx                       |   28 -
 sw/source/core/text/porlay.cxx                        |   41 +
 sw/source/core/unocore/unomap1.cxx                    |    1 
 sw/source/core/unocore/unomapproperties.hxx           |    1 
 sw/source/filter/html/css1atr.cxx                     |    1 
 sw/source/filter/html/htmlatr.cxx                     |    1 
 sw/source/uibase/shells/annotsh.cxx                   |    2 
 sw/source/uibase/shells/basesh.cxx                    |    2 
 sw/source/uibase/shells/drwtxtex.cxx                  |    2 
 sw/source/uibase/shells/drwtxtsh.cxx                  |    2 
 sw/source/uibase/shells/textsh.cxx                    |    2 
 sw/source/uibase/shells/txtattr.cxx                   |    2 
 sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx |    1 
 xmloff/inc/xmlprop.hxx                                |    1 
 xmloff/source/core/xmltoken.cxx                       |    5 
 xmloff/source/style/prhdlfac.cxx                      |   10 
 xmloff/source/text/txtprmap.cxx                       |    4 
 xmloff/source/token/tokens.txt                        |    4 
 62 files changed, 1342 insertions(+), 256 deletions(-)

New commits:
commit 0b979c50b6fa72bae4344130e48f5503ac14a9c4
Author:     Jonathan Clark <jonat...@libreoffice.org>
AuthorDate: Mon Jun 2 14:37:26 2025 -0600
Commit:     Jonathan Clark <jonat...@libreoffice.org>
CommitDate: Tue Jun 10 07:09:17 2025 +0200

    tdf#166011 Implemented style:script-type
    
    Implemented the ODF 1.0 style:script-type text property. This property
    can be used by documents to influence which script type-dependent
    attributes are used when rendering certain characters.
    
    This implementation uses the following semantics:
    
    - If unset, the behavior is as it was in previous versions.
    - If set to latin, asian, or complex, those characters not mapped by the
      ODF standard to a script type are treated as latin, asian, or complex,
      respectively.
    - If set to ignore, all characters will be treated as latin. This value
      is intended to be used for interoperability with file formats that
      don't implement script types (e.g. HTML).
    
    Change-Id: If81a1390ee455fd971dea655d161d9c3f44fd08a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186309
    Tested-by: Jenkins
    Reviewed-by: Jonathan Clark <jonat...@libreoffice.org>

diff --git a/editeng/inc/editattr.hxx b/editeng/inc/editattr.hxx
index 806f97625d6c..19e52a44007d 100644
--- a/editeng/inc/editattr.hxx
+++ b/editeng/inc/editattr.hxx
@@ -307,6 +307,14 @@ public:
     virtual void SetFont(SvxFont& rFont, OutputDevice* pOutDev) override;
 };
 
+class EditCharAttribScriptHint final : public EditCharAttrib
+{
+public:
+    EditCharAttribScriptHint(SfxItemPool&, const SfxPoolItem&, sal_Int32 
nStart, sal_Int32 nEnd);
+
+    virtual void SetFont(SvxFont& rFont, OutputDevice* pOutDev) override;
+};
+
 class EditCharAttribTab final : public EditCharAttrib
 {
 public:
diff --git a/editeng/source/editeng/editattr.cxx 
b/editeng/source/editeng/editattr.cxx
index deab7b6b7dea..3a8b29f48e70 100644
--- a/editeng/source/editeng/editattr.cxx
+++ b/editeng/source/editeng/editattr.cxx
@@ -255,6 +255,15 @@ EditCharAttribRuby::EditCharAttribRuby(SfxItemPool& rPool, 
const SfxPoolItem& rI
 
 void EditCharAttribRuby::SetFont(SvxFont&, OutputDevice*) {}
 
+EditCharAttribScriptHint::EditCharAttribScriptHint(SfxItemPool& rPool, const 
SfxPoolItem& rItem,
+                                                   sal_Int32 nStartIn, 
sal_Int32 nEndIn)
+    : EditCharAttrib(rPool, rItem, nStartIn, nEndIn)
+{
+    assert(rItem.Which() == EE_CHAR_SCRIPT_HINT);
+}
+
+void EditCharAttribScriptHint::SetFont(SvxFont&, OutputDevice*) {}
+
 EditCharAttribShadow::EditCharAttribShadow(SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 _nStart, sal_Int32 _nEnd)
 : EditCharAttrib(rPool, rItem, _nStart, _nEnd)
 {
diff --git a/editeng/source/editeng/editdbg.cxx 
b/editeng/source/editeng/editdbg.cxx
index 6c9226d3e056..6acb59356320 100644
--- a/editeng/source/editeng/editdbg.cxx
+++ b/editeng/source/editeng/editdbg.cxx
@@ -48,6 +48,7 @@
 #include <editeng/charscaleitem.hxx>
 #include <editeng/charreliefitem.hxx>
 #include <editeng/frmdiritem.hxx>
+#include <editeng/scripthintitem.hxx>
 
 #include "impedit.hxx"
 #include <editeng/editeng.hxx>
@@ -183,6 +184,12 @@ struct DebOutBuffer
         str.append(OString::Concat(descr)
                    + OUStringToOString(rItem.GetText(), 
RTL_TEXTENCODING_UTF8));
     }
+    void append(std::string_view descr, const SvxScriptHintItem& rItem)
+    {
+        str.append(OString::Concat(descr)
+                   + 
OUStringToOString(SvxScriptHintItem::GetValueText(rItem.GetValue()),
+                                       RTL_TEXTENCODING_ASCII_US));
+    }
 };
 }
 
@@ -317,6 +324,9 @@ static OString DbgOutItem(const SfxItemPool& rPool, const 
SfxPoolItem& rItem)
         case EE_CHAR_RUBY:
             buffer.append("Ruby=", rItem.StaticWhichCast(EE_CHAR_RUBY));
         break;
+        case EE_CHAR_SCRIPT_HINT:
+            buffer.append("ScriptHint=", 
rItem.StaticWhichCast(EE_CHAR_SCRIPT_HINT));
+        break;
     }
     return buffer.str.makeStringAndClear();
 }
diff --git a/editeng/source/editeng/editdoc.cxx 
b/editeng/source/editeng/editdoc.cxx
index 8c7277f74224..8b4721478627 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -313,6 +313,11 @@ EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const 
SfxPoolItem& rAttr, sa
             return new EditCharAttribRuby(rPool, rAttr, nS, nE);
         }
         break;
+        case EE_CHAR_SCRIPT_HINT:
+        {
+            return new EditCharAttribScriptHint(rPool, rAttr, nS, nE);
+        }
+        break;
         default:
         break;
     }
diff --git a/editeng/source/editeng/eerdll.cxx 
b/editeng/source/editeng/eerdll.cxx
index d7ed5397ebb3..e828897160e1 100644
--- a/editeng/source/editeng/eerdll.cxx
+++ b/editeng/source/editeng/eerdll.cxx
@@ -59,6 +59,7 @@
 #include <editeng/numitem.hxx>
 #include <editeng/langitem.hxx>
 #include <editeng/cmapitem.hxx>
+#include <editeng/scripthintitem.hxx>
 #include <editeng/charscaleitem.hxx>
 #include <editeng/charreliefitem.hxx>
 #include <editeng/frmdiritem.hxx>
@@ -156,6 +157,7 @@ ItemInfoPackage& getItemInfoPackageEditEngine()
             { EE_CHAR_GRABBAG, new SfxGrabBagItem( EE_CHAR_GRABBAG ), 
SID_ATTR_CHAR_GRABBAG, SFX_ITEMINFOFLAG_NONE  },
             { EE_CHAR_BKGCOLOR, new SvxColorItem( COL_AUTO, EE_CHAR_BKGCOLOR 
), SID_ATTR_CHAR_BACK_COLOR, SFX_ITEMINFOFLAG_NONE  },
             { EE_CHAR_RUBY, new SvxRubyItem( EE_CHAR_RUBY ), 
SID_ATTR_CHAR_RUBY, SFX_ITEMINFOFLAG_NONE },
+            { EE_CHAR_SCRIPT_HINT, new SvxScriptHintItem( EE_CHAR_SCRIPT_HINT 
), SID_ATTR_CHAR_SCRIPT_HINT, SFX_ITEMINFOFLAG_NONE },
             { EE_FEATURE_TAB, new SfxVoidItem( EE_FEATURE_TAB ), 0, 
SFX_ITEMINFOFLAG_NONE  },
             { EE_FEATURE_LINEBR, new SfxVoidItem( EE_FEATURE_LINEBR ), 0, 
SFX_ITEMINFOFLAG_NONE  },
             { EE_FEATURE_NOTCONV, new SvxColorItem( COL_RED, 
EE_FEATURE_NOTCONV ), SID_ATTR_CHAR_CHARSETCOLOR, SFX_ITEMINFOFLAG_NONE  },
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index e231191b75d1..2d8c3a0be64c 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -42,6 +42,7 @@
 #include <editeng/frmdiritem.hxx>
 #include <editeng/justifyitem.hxx>
 #include <editeng/udlnitem.hxx>
+#include <editeng/scripthintitem.hxx>
 
 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
 #include <com/sun/star/i18n/WordType.hpp>
@@ -1744,10 +1745,26 @@ void ImpEditEngine::InitScriptTypes( sal_Int32 nPara )
         pField = pField->GetEnd() ? pNode->GetCharAttribs().FindNextAttrib( 
EE_FEATURE_FIELD, pField->GetEnd() ) : nullptr;
     }
 
+    i18nutil::ScriptHintProvider stScriptHints;
+    const EditCharAttrib* pScriptHint
+        = pNode->GetCharAttribs().FindNextAttrib(EE_CHAR_SCRIPT_HINT, 0);
+    while (pScriptHint)
+    {
+        const auto* pScriptHintValue
+            = static_cast<const SvxScriptHintItem*>(pScriptHint->GetItem());
+        stScriptHints.AddHint(pScriptHintValue->GetValue(), 
pScriptHint->GetStart(),
+                              pScriptHint->GetEnd());
+
+        pScriptHint = pScriptHint->GetEnd() ? 
pNode->GetCharAttribs().FindNextAttrib(
+                                                  EE_CHAR_SCRIPT_HINT, 
pScriptHint->GetEnd())
+                                            : nullptr;
+    }
+
     const UBiDiLevel nInitialBidiLevel = IsRightToLeft(nPara) ? 1 /*RTL*/ : 0 
/*LTR*/;
     auto pDirScanner = i18nutil::MakeDirectionChangeScanner(aText, 
nInitialBidiLevel);
     auto pScriptScanner = i18nutil::MakeScriptChangeScanner(
-        aText, 
SvtLanguageOptions::GetI18NScriptTypeOfLanguage(GetDefaultLanguage()), 
*pDirScanner);
+        aText, 
SvtLanguageOptions::GetI18NScriptTypeOfLanguage(GetDefaultLanguage()), 
*pDirScanner,
+        stScriptHints);
     while (!pScriptScanner->AtEnd() || rTypes.empty())
     {
         auto stChange = pScriptScanner->Peek();
diff --git a/editeng/source/items/textitem.cxx 
b/editeng/source/items/textitem.cxx
index e74187788407..e9c728fddb69 100644
--- a/editeng/source/items/textitem.cxx
+++ b/editeng/source/items/textitem.cxx
@@ -72,12 +72,13 @@
 #include <editeng/blinkitem.hxx>
 #include <editeng/emphasismarkitem.hxx>
 #include <editeng/twolinesitem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <editeng/charrotateitem.hxx>
 #include <editeng/charscaleitem.hxx>
 #include <editeng/charreliefitem.hxx>
 #include <editeng/rubyitem.hxx>
 #include <editeng/itemtype.hxx>
+#include <editeng/scripthintitem.hxx>
 #include <editeng/eerdll.hxx>
 #include <docmodel/color/ComplexColorJSON.hxx>
 #include <docmodel/uno/UnoComplexColor.hxx>
@@ -91,6 +92,7 @@ using namespace ::com::sun::star::text;
 SfxPoolItem* SvxFontItem::CreateDefault() {return new SvxFontItem(0);}
 SfxPoolItem* SvxPostureItem::CreateDefault() { return new 
SvxPostureItem(ITALIC_NONE, 0);}
 SfxPoolItem* SvxWeightItem::CreateDefault() {return new 
SvxWeightItem(WEIGHT_NORMAL, 0);}
+SfxPoolItem* SvxScriptHintItem::CreateDefault() {return new 
SvxScriptHintItem(0);}
 SfxPoolItem* SvxFontHeightItem::CreateDefault() {return new 
SvxFontHeightItem(240, 100, 0);}
 SfxPoolItem* SvxUnderlineItem::CreateDefault() {return new 
SvxUnderlineItem(LINESTYLE_NONE, 0);}
 SfxPoolItem* SvxOverlineItem::CreateDefault() {return new 
SvxOverlineItem(LINESTYLE_NONE, 0);}
@@ -652,6 +654,90 @@ void SvxWeightItem::dumpAsXml(xmlTextWriterPtr pWriter) 
const
     (void)xmlTextWriterEndElement(pWriter);
 }
 
+// class SvxScriptHintItem ---------------------------------------------------
+
+ItemInstanceManager* SvxScriptHintItem::getItemInstanceManager() const
+{
+    static DefaultItemInstanceManager aInstanceManager(ItemType());
+    return &aInstanceManager;
+}
+
+SvxScriptHintItem::SvxScriptHintItem(const sal_uInt16 nId)
+    : SfxEnumItem(nId, i18nutil::ScriptHintType::Automatic)
+{
+}
+
+sal_uInt16 SvxScriptHintItem::GetValueCount() const { return 5; }
+
+SvxScriptHintItem* SvxScriptHintItem::Clone(SfxItemPool*) const
+{
+    return new SvxScriptHintItem(*this);
+}
+
+bool SvxScriptHintItem::GetPresentation(SfxItemPresentation /*ePres*/, MapUnit 
/*eCoreUnit*/,
+                                        MapUnit /*ePresUnit*/, OUString& rText,
+                                        const IntlWrapper& /*rIntl*/) const
+{
+    rText = GetValueText(GetValue());
+    return true;
+}
+
+OUString SvxScriptHintItem::GetValueText(i18nutil::ScriptHintType eValue)
+{
+    static const std::array<TranslateId, 5> RID_SVXITEMS_TYPES{
+        { RID_SVXITEMS_SCRIPTHINTVAL_AUTO, RID_SVXITEMS_SCRIPTHINTVAL_IGNORE,
+          RID_SVXITEMS_SCRIPTHINTVAL_LATIN, RID_SVXITEMS_SCRIPTHINTVAL_ASIAN,
+          RID_SVXITEMS_SCRIPTHINTVAL_COMPLEX }
+    };
+
+    return EditResId(RID_SVXITEMS_TYPES.at(static_cast<size_t>(eValue)));
+}
+
+bool SvxScriptHintItem::QueryValue(uno::Any& rVal, sal_uInt8 nMemberId) const
+{
+    nMemberId &= ~CONVERT_TWIPS;
+    switch (nMemberId)
+    {
+        case MID_SCRIPTHINT:
+            rVal <<= static_cast<sal_uInt16>(GetValue());
+            break;
+    }
+
+    return true;
+}
+
+bool SvxScriptHintItem::PutValue(const uno::Any& rVal, sal_uInt8 nMemberId)
+{
+    sal_uInt16 nValue = 0;
+
+    nMemberId &= ~CONVERT_TWIPS;
+    switch (nMemberId)
+    {
+        case MID_SCRIPTHINT:
+            if (!(rVal >>= nValue))
+            {
+                return false;
+            }
+
+            ASSERT_CHANGE_REFCOUNTED_ITEM;
+            SetValue(i18nutil::ScriptHintType{ nValue });
+            break;
+    }
+
+    return true;
+}
+
+void SvxScriptHintItem::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxScriptHintItem"));
+    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("whichId"), 
"%d", Which());
+    (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("value"), "%d",
+                                            static_cast<int>(GetValue()));
+    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"),
+                                      
BAD_CAST(GetValueText(GetValue()).toUtf8().getStr()));
+    (void)xmlTextWriterEndElement(pWriter);
+}
+
 // class SvxFontHeightItem -----------------------------------------------
 
 ItemInstanceManager* SvxFontHeightItem::getItemInstanceManager() const
diff --git a/forms/inc/pch/precompiled_frm.hxx 
b/forms/inc/pch/precompiled_frm.hxx
index cbf7aa3cf8b6..bac82af9ad4d 100644
--- a/forms/inc/pch/precompiled_frm.hxx
+++ b/forms/inc/pch/precompiled_frm.hxx
@@ -208,7 +208,7 @@
 #include <editeng/editview.hxx>
 #include <editeng/eeitem.hxx>
 #include <editeng/fhgtitem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <editeng/svxenum.hxx>
 #include <i18nlangtag/lang.h>
 #include <i18nlangtag/languagetag.hxx>
diff --git a/forms/source/richtext/richtextimplcontrol.cxx 
b/forms/source/richtext/richtextimplcontrol.cxx
index 6125bd20e188..40f51b3422f4 100644
--- a/forms/source/richtext/richtextimplcontrol.cxx
+++ b/forms/source/richtext/richtextimplcontrol.cxx
@@ -26,7 +26,7 @@
 #include <editeng/editids.hrc>
 #include <editeng/editview.hxx>
 #include <editeng/editstat.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 
 #include <svl/itempool.hxx>
 #include <svl/itemset.hxx>
diff --git a/forms/source/richtext/rtattributehandler.cxx 
b/forms/source/richtext/rtattributehandler.cxx
index 0075bd914119..3af36d914033 100644
--- a/forms/source/richtext/rtattributehandler.cxx
+++ b/forms/source/richtext/rtattributehandler.cxx
@@ -33,7 +33,7 @@
 #include <editeng/lspcitem.hxx>
 #include <editeng/fhgtitem.hxx>
 #include <editeng/frmdiritem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 
 
 namespace frm
diff --git a/i18nutil/qa/cppunit/test_scriptchangescanner.cxx 
b/i18nutil/qa/cppunit/test_scriptchangescanner.cxx
index 805efd2bb53f..ae0c047b2fca 100644
--- a/i18nutil/qa/cppunit/test_scriptchangescanner.cxx
+++ b/i18nutil/qa/cppunit/test_scriptchangescanner.cxx
@@ -40,6 +40,17 @@ public:
     void testRtlRunEmbeddedLtrWeakComplex();
     void testRtlRunOverrideCJKAsian();
     void testTdf164493InfiniteLoop();
+    void testHintsDefault();
+    void testHintsParaOnly();
+    void testHintsRunAtStart();
+    void testHintsRunAfterSpace();
+    void testHintsRunsAdjacent();
+    void testHintsRunsSpaced();
+    void testHintIgnore();
+    void testHintLatin();
+    void testHintAsian();
+    void testHintComplex();
+    void testHintMultipleRuns();
 
     CPPUNIT_TEST_SUITE(ScriptChangeScannerTest);
     CPPUNIT_TEST(testEmpty);
@@ -59,14 +70,27 @@ public:
     CPPUNIT_TEST(testRtlRunEmbeddedLtrWeakComplex);
     CPPUNIT_TEST(testRtlRunOverrideCJKAsian);
     CPPUNIT_TEST(testTdf164493InfiniteLoop);
+    CPPUNIT_TEST(testHintsDefault);
+    CPPUNIT_TEST(testHintsParaOnly);
+    CPPUNIT_TEST(testHintsRunAtStart);
+    CPPUNIT_TEST(testHintsRunAfterSpace);
+    CPPUNIT_TEST(testHintsRunsAdjacent);
+    CPPUNIT_TEST(testHintsRunsSpaced);
+    CPPUNIT_TEST(testHintIgnore);
+    CPPUNIT_TEST(testHintLatin);
+    CPPUNIT_TEST(testHintAsian);
+    CPPUNIT_TEST(testHintComplex);
+    CPPUNIT_TEST(testHintMultipleRuns);
     CPPUNIT_TEST_SUITE_END();
 };
 
 void ScriptChangeScannerTest::testEmpty()
 {
     auto aText = u""_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
     CPPUNIT_ASSERT(pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pScanner->Peek().m_nStartIndex);
@@ -76,8 +100,10 @@ void ScriptChangeScannerTest::testEmpty()
 void ScriptChangeScannerTest::testTrivial()
 {
     auto aText = u"Trivial case with a single span of a script"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -91,8 +117,10 @@ void ScriptChangeScannerTest::testTrivial()
 void ScriptChangeScannerTest::testTrivialAppLang()
 {
     auto aText = u"Trivial case with a single span of a script"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::ASIAN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::ASIAN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -107,8 +135,10 @@ void ScriptChangeScannerTest::testWeakAtStart()
 {
     // The first-seen script type is used for weak characters at the start
     auto aText = u"“x”"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::COMPLEX, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::COMPLEX, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -124,8 +154,10 @@ void ScriptChangeScannerTest::testOnlyWeak()
 {
     // The application language is used for text containing only weak 
characters
     auto aText = u"“”"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::COMPLEX, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::COMPLEX, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::COMPLEX, 
pScanner->Peek().m_nScriptType);
@@ -140,8 +172,10 @@ void ScriptChangeScannerTest::testOnlyWeak()
 void ScriptChangeScannerTest::testStrongChange()
 {
     auto aText = u"wide 廣 vast"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -171,8 +205,10 @@ void ScriptChangeScannerTest::testMongolianAfterNNBSP()
 {
     // NNBSP before Mongolian text should be part of the Mongolian run
     auto aText = u"Before\u202f\u1822\u1822After"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -203,8 +239,10 @@ void ScriptChangeScannerTest::testNonspacingMark()
     // A preceding weak character should be included in the run
     // of a following non-spacing mark
     auto aText = u"Before \u0944\u0911\u0911 After"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -235,8 +273,10 @@ void 
ScriptChangeScannerTest::testSmartQuoteCompatibilityCJ()
     // tdf#166104: Weak-script quotes should take the previously-seen script 
type
 
     auto aText = u"Before \u201c水\u201d After"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -268,8 +308,10 @@ void 
ScriptChangeScannerTest::testSmartQuoteCompatibilityComplexAndCJ()
     // quotes are assigned in the usual greedy way.
 
     auto aText = u"Before \u201c水\u201d After \u05d0"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -305,8 +347,10 @@ void 
ScriptChangeScannerTest::testSmartQuoteCompatibilityComplexAndCJ()
 void ScriptChangeScannerTest::testSmartQuoteCJAtStart()
 {
     auto aText = u"“廣”"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::ASIAN, 
pScanner->Peek().m_nScriptType);
@@ -321,6 +365,7 @@ void ScriptChangeScannerTest::testSmartQuoteCJAtStart()
 void ScriptChangeScannerTest::testRtlRunTrivial()
 {
     auto aText = u"Before אאאאאא after"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
 
     CPPUNIT_ASSERT(!pDirScanner->AtEnd());
@@ -351,7 +396,8 @@ void ScriptChangeScannerTest::testRtlRunTrivial()
 
     pDirScanner->Reset();
 
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -380,6 +426,7 @@ void ScriptChangeScannerTest::testRtlRunTrivial()
 void ScriptChangeScannerTest::testRtlRunEmbeddedComplex()
 {
     auto aText = u"Before אא(א\"א)אא after"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
 
     CPPUNIT_ASSERT(!pDirScanner->AtEnd());
@@ -410,7 +457,8 @@ void ScriptChangeScannerTest::testRtlRunEmbeddedComplex()
 
     pDirScanner->Reset();
 
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
@@ -439,6 +487,7 @@ void ScriptChangeScannerTest::testRtlRunEmbeddedComplex()
 void ScriptChangeScannerTest::testRtlRunEmbeddedLtrStrong()
 {
     auto aText = u"אאא Inside אאא"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 1);
 
     CPPUNIT_ASSERT(!pDirScanner->AtEnd());
@@ -469,7 +518,8 @@ void ScriptChangeScannerTest::testRtlRunEmbeddedLtrStrong()
 
     pDirScanner->Reset();
 
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::COMPLEX, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::COMPLEX, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::COMPLEX, 
pScanner->Peek().m_nScriptType);
@@ -498,6 +548,7 @@ void ScriptChangeScannerTest::testRtlRunEmbeddedLtrStrong()
 void ScriptChangeScannerTest::testRtlRunEmbeddedLtrWeakComplex()
 {
     auto aText = u"אאא 123 אאא"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 1);
 
     CPPUNIT_ASSERT(!pDirScanner->AtEnd());
@@ -528,7 +579,8 @@ void 
ScriptChangeScannerTest::testRtlRunEmbeddedLtrWeakComplex()
 
     pDirScanner->Reset();
 
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::COMPLEX, 
pScanner->Peek().m_nScriptType);
@@ -545,6 +597,7 @@ void ScriptChangeScannerTest::testRtlRunOverrideCJKAsian()
     // tdf#163660: Asian-script characters following an RTL override should
     // still be treated as Asian script, rather than Complex script
     auto aText = u"一二\u202e三四五"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
 
     CPPUNIT_ASSERT(!pDirScanner->AtEnd());
@@ -567,7 +620,8 @@ void ScriptChangeScannerTest::testRtlRunOverrideCJKAsian()
 
     pDirScanner->Reset();
 
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::ASIAN, 
pScanner->Peek().m_nScriptType);
@@ -601,8 +655,10 @@ void ScriptChangeScannerTest::testTdf164493InfiniteLoop()
     // U+202E: RIGHT-TO-LEFT OVERRIDE
     // U+302E: HANGUL SINGLE DOT TONE MARK
     auto aText = u"\u202e\u302e"_ustr;
+    ScriptHintProvider stHints;
     auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
-    auto pScanner = MakeScriptChangeScanner(aText, 
css::i18n::ScriptType::LATIN, *pDirScanner);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
 
     CPPUNIT_ASSERT(!pScanner->AtEnd());
     CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::ASIAN, 
pScanner->Peek().m_nScriptType);
@@ -614,6 +670,340 @@ void ScriptChangeScannerTest::testTdf164493InfiniteLoop()
     CPPUNIT_ASSERT(pScanner->AtEnd());
 }
 
+void ScriptChangeScannerTest::testHintsDefault()
+{
+    ScriptHintProvider stHints;
+
+    stHints.Start();
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Automatic, stHints.Peek());
+
+    stHints.AdvanceTo(1);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Automatic, stHints.Peek());
+
+    stHints.AdvanceTo(2);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Automatic, stHints.Peek());
+}
+
+void ScriptChangeScannerTest::testHintsParaOnly()
+{
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Ignore);
+
+    stHints.Start();
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(1);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(2);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+}
+
+void ScriptChangeScannerTest::testHintsRunAtStart()
+{
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Ignore);
+    stHints.AddHint(ScriptHintType::Latin, 0, 3);
+
+    stHints.Start();
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(1);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(2);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(3);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(4);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+}
+
+void ScriptChangeScannerTest::testHintsRunAfterSpace()
+{
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Ignore);
+    stHints.AddHint(ScriptHintType::Latin, 2, 5);
+
+    stHints.Start();
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(1);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(2);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(3);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(4);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(5);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(6);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+}
+
+void ScriptChangeScannerTest::testHintsRunsAdjacent()
+{
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Ignore);
+    stHints.AddHint(ScriptHintType::Latin, 2, 5);
+    stHints.AddHint(ScriptHintType::Complex, 5, 7);
+
+    stHints.Start();
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(1);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(2);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(3);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(4);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(5);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Complex, stHints.Peek());
+
+    stHints.AdvanceTo(6);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Complex, stHints.Peek());
+
+    stHints.AdvanceTo(7);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(8);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+}
+
+void ScriptChangeScannerTest::testHintsRunsSpaced()
+{
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Ignore);
+    stHints.AddHint(ScriptHintType::Latin, 2, 5);
+    stHints.AddHint(ScriptHintType::Complex, 7, 9);
+
+    stHints.Start();
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(1);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(2);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(3);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(4);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Latin, stHints.Peek());
+
+    stHints.AdvanceTo(5);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(6);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(7);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Complex, stHints.Peek());
+
+    stHints.AdvanceTo(8);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Complex, stHints.Peek());
+
+    stHints.AdvanceTo(9);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+
+    stHints.AdvanceTo(10);
+    CPPUNIT_ASSERT_EQUAL(ScriptHintType::Ignore, stHints.Peek());
+}
+
+void ScriptChangeScannerTest::testHintIgnore()
+{
+    auto aText = u"Before \u201c水\u201d After"_ustr;
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Ignore);
+
+    auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(16), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(pScanner->AtEnd());
+}
+
+void ScriptChangeScannerTest::testHintLatin()
+{
+    auto aText = u"水 \u201c水\u201d After"_ustr;
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Latin);
+
+    auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::ASIAN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::ASIAN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(4), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(pScanner->AtEnd());
+}
+
+void ScriptChangeScannerTest::testHintAsian()
+{
+    auto aText = u"Before \u201c水\u201d After"_ustr;
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Asian);
+
+    auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::ASIAN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(16), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(pScanner->AtEnd());
+}
+
+void ScriptChangeScannerTest::testHintComplex()
+{
+    auto aText = u"Before \u201c水\u201d After"_ustr;
+    ScriptHintProvider stHints;
+    stHints.SetParagraphLevelHint(ScriptHintType::Complex);
+
+    auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::COMPLEX, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(6), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(8), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::ASIAN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(8), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(9), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::COMPLEX, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(9), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(16), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(pScanner->AtEnd());
+}
+
+void ScriptChangeScannerTest::testHintMultipleRuns()
+{
+    auto aText = u"““““““““““““““““"_ustr;
+    ScriptHintProvider stHints;
+    stHints.AddHint(ScriptHintType::Latin, 3, 5);
+    stHints.AddHint(ScriptHintType::Complex, 7, 9);
+    stHints.AddHint(ScriptHintType::Asian, 11, 13);
+
+    auto pDirScanner = MakeDirectionChangeScanner(aText, 0);
+    auto pScanner
+        = MakeScriptChangeScanner(aText, css::i18n::ScriptType::LATIN, 
*pDirScanner, stHints);
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::LATIN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::COMPLEX, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(7), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(!pScanner->AtEnd());
+    CPPUNIT_ASSERT_EQUAL(css::i18n::ScriptType::ASIAN, 
pScanner->Peek().m_nScriptType);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(11), pScanner->Peek().m_nStartIndex);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(16), pScanner->Peek().m_nEndIndex);
+
+    pScanner->Advance();
+
+    CPPUNIT_ASSERT(pScanner->AtEnd());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScriptChangeScannerTest);
 }
 
diff --git a/i18nutil/source/utility/scriptchangescanner.cxx 
b/i18nutil/source/utility/scriptchangescanner.cxx
index 0f53e16e0383..f65d7a9d19d7 100644
--- a/i18nutil/source/utility/scriptchangescanner.cxx
+++ b/i18nutil/source/utility/scriptchangescanner.cxx
@@ -21,6 +21,44 @@ namespace css = ::com::sun::star;
 
 namespace i18nutil
 {
+void ScriptHintProvider::SetParagraphLevelHint(ScriptHintType eType) { 
m_eParaHint = eType; }
+
+void ScriptHintProvider::AddHint(ScriptHintType eType, sal_Int32 nStartIndex, 
sal_Int32 nEndIndex)
+{
+    m_aHints.emplace_back(eType, nStartIndex, nEndIndex);
+}
+
+void ScriptHintProvider::Start()
+{
+    m_pCurrIt = m_aHints.begin();
+    m_nCurrIdx = 0;
+
+    m_eCurrHint = m_eParaHint;
+    if (m_pCurrIt != m_aHints.end() && m_pCurrIt->m_nStartIndex == 0 && 
m_pCurrIt->m_nEndIndex > 0)
+    {
+        m_eCurrHint = m_pCurrIt->m_eType;
+    }
+}
+
+void ScriptHintProvider::AdvanceTo(sal_Int32 nNextIdx)
+{
+    m_nCurrIdx = nNextIdx;
+
+    while (m_pCurrIt != m_aHints.end() && m_nCurrIdx >= m_pCurrIt->m_nEndIndex)
+    {
+        ++m_pCurrIt;
+    }
+
+    m_eCurrHint = m_eParaHint;
+    if (m_pCurrIt != m_aHints.end() && m_nCurrIdx >= m_pCurrIt->m_nStartIndex
+        && m_nCurrIdx < m_pCurrIt->m_nEndIndex)
+    {
+        m_eCurrHint = m_pCurrIt->m_eType;
+    }
+}
+
+i18nutil::ScriptHintType ScriptHintProvider::Peek() const { return 
m_eCurrHint; }
+
 namespace
 {
 constexpr sal_uInt32 CHAR_NNBSP = 0x202f;
@@ -131,6 +169,7 @@ class GreedyScriptChangeScanner : public ScriptChangeScanner
 private:
     ScriptChange m_stCurr;
     DirectionChangeScanner* m_pDirScanner;
+    ScriptHintProvider* m_pHints;
     const OUString& m_rText;
     sal_Int32 m_nIndex = 0;
     sal_Int32 m_nNextStart = 0;
@@ -174,15 +213,46 @@ private:
                 m_pDirScanner->Advance();
             }
 
+            m_pHints->AdvanceTo(m_nIndex);
+            auto eCurrHint = m_pHints->Peek();
+
             auto nChar = m_rText.iterateCodePoints(&m_nIndex);
             nScript = GetScriptClass(nChar);
 
+            // tdf#166011 Apply style:script-type rules per ODF standard:
+            if (eCurrHint == ScriptHintType::Ignore)
+            {
+                // The generic/latin font attributes are always used if the 
hint is ignore.
+                nScript = css::i18n::ScriptType::LATIN;
+            }
+            else if (nScript == css::i18n::ScriptType::WEAK)
+            {
+                switch (eCurrHint)
+                {
+                    case ScriptHintType::Latin:
+                        nScript = css::i18n::ScriptType::LATIN;
+                        break;
+
+                    case ScriptHintType::Asian:
+                        nScript = css::i18n::ScriptType::ASIAN;
+                        break;
+
+                    case ScriptHintType::Complex:
+                        nScript = css::i18n::ScriptType::COMPLEX;
+                        break;
+
+                    default:
+                        break;
+                }
+            }
+
             // #i16354# Change script type for RTL text to CTL:
             // 1. All text in RTL runs will use the CTL font
             // #i89825# change the script type also to CTL (hennerdrewes)
             // 2. Text in embedded LTR runs that does not have any strong LTR 
characters (numbers!)
             // tdf#163660 Asian-script characters inside RTL runs should still 
use Asian font
-            if (bCharIsRtl || (bCharIsRtlOrEmbedded && 
!bRunHasStrongEmbeddedLTR))
+            if (eCurrHint == ScriptHintType::Automatic
+                && (bCharIsRtl || (bCharIsRtlOrEmbedded && 
!bRunHasStrongEmbeddedLTR)))
             {
                 if (nScript != css::i18n::ScriptType::ASIAN)
                 {
@@ -233,8 +303,9 @@ private:
 
 public:
     GreedyScriptChangeScanner(const OUString& rText, sal_Int16 
nDefaultScriptType,
-                              DirectionChangeScanner* pDirScanner)
+                              DirectionChangeScanner* pDirScanner, 
ScriptHintProvider* pHints)
         : m_pDirScanner(pDirScanner)
+        , m_pHints(pHints)
         , m_rText(rText)
     {
         // tdf#66791: For compatibility with other programs, the Asian script 
is
@@ -261,6 +332,7 @@ public:
             m_nPrevScript = nDefaultScriptType;
         }
 
+        m_pHints->Start();
         Advance();
     }
 
@@ -287,9 +359,10 @@ i18nutil::MakeDirectionChangeScanner(const OUString& 
rText, sal_uInt8 nInitialDi
 
 std::unique_ptr<i18nutil::ScriptChangeScanner>
 i18nutil::MakeScriptChangeScanner(const OUString& rText, sal_Int16 
nDefaultScriptType,
-                                  DirectionChangeScanner& rDirScanner)
+                                  DirectionChangeScanner& rDirScanner, 
ScriptHintProvider& rHints)
 {
-    return std::make_unique<GreedyScriptChangeScanner>(rText, 
nDefaultScriptType, &rDirScanner);
+    return std::make_unique<GreedyScriptChangeScanner>(rText, 
nDefaultScriptType, &rDirScanner,
+                                                       &rHints);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/editeng/editids.hrc b/include/editeng/editids.hrc
index 84e8aab8ed2a..6a1a0e81f339 100644
--- a/include/editeng/editids.hrc
+++ b/include/editeng/editids.hrc
@@ -66,6 +66,7 @@ class SvxULSpaceItem;
 class SvxWeightItem;
 class SvxWidowsItem;
 class SvxWordLineModeItem;
+class SvxScriptHintItem;
 
 /*
   These SID_SVX_START entries came from include/svx/svxids.hrc, avoid
@@ -88,7 +89,7 @@ class SvxWordLineModeItem;
 #define SID_ATTR_CHAR_STRIKEOUT                         
TypedWhichId<SvxCrossedOutItem>( SID_SVX_START + 13 )
 #define SID_ATTR_CHAR_UNDERLINE                         
TypedWhichId<SvxUnderlineItem>( SID_SVX_START + 14 )
 #define SID_ATTR_CHAR_FONTHEIGHT                        
TypedWhichId<SvxFontHeightItem>( SID_SVX_START + 15 )
-  // free
+#define SID_ATTR_CHAR_SCRIPT_HINT                       
TypedWhichId<SvxScriptHintItem>( SID_SVX_START + 16 )
 #define SID_ATTR_CHAR_COLOR                             
TypedWhichId<SvxColorItem>( SID_SVX_START + 17 )
 #define SID_ATTR_CHAR_KERNING                           
TypedWhichId<SvxKerningItem>( SID_SVX_START + 18 )
 #define SID_ATTR_CHAR_CASEMAP                           
TypedWhichId<SvxCaseMapItem>( SID_SVX_START + 19 )
diff --git a/include/editeng/editrids.hrc b/include/editeng/editrids.hrc
index 46d87cc9556b..23c8ec932fd0 100644
--- a/include/editeng/editrids.hrc
+++ b/include/editeng/editrids.hrc
@@ -125,6 +125,13 @@
 #define RID_SVXITEMS_STRIKEOUT_SLASH            
NC_("RID_SVXITEMS_STRIKEOUT_SLASH", "Strike through with slash")
 #define RID_SVXITEMS_STRIKEOUT_X                
NC_("RID_SVXITEMS_STRIKEOUT_X", "Strike through with Xes")
 
+// enum ScriptTypeValue -------------------------------------------------------
+#define RID_SVXITEMS_SCRIPTHINTVAL_AUTO         
NC_("RID_SVXITEMS_SCRIPTHINTVAL_AUTO", "Automatic")
+#define RID_SVXITEMS_SCRIPTHINTVAL_IGNORE       
NC_("RID_SVXITEMS_SCRIPTHINTVAL_IGNORE", "Ignore")
+#define RID_SVXITEMS_SCRIPTHINTVAL_LATIN        
NC_("RID_SVXITEMS_SCRIPTHINTVAL_LATIN", "Latin")
+#define RID_SVXITEMS_SCRIPTHINTVAL_ASIAN        
NC_("RID_SVXITEMS_SCRIPTHINTVAL_ASIAN", "Asian")
+#define RID_SVXITEMS_SCRIPTHINTVAL_COMPLEX      
NC_("RID_SVXITEMS_SCRIPTHINTVAL_COMPLEX", "Complex")
+
 // enum CASEMAP ----------------------------------------------------------
 #define RID_SVXITEMS_CASEMAP_NONE               
NC_("RID_SVXITEMS_CASEMAP_NONE", "None")
 #define RID_SVXITEMS_CASEMAP_UPPERCASE          
NC_("RID_SVXITEMS_CASEMAP_VERSALIEN", "Caps")
diff --git a/include/editeng/eeitem.hxx b/include/editeng/eeitem.hxx
index 3bbc30a869f7..ce8315ec4e27 100644
--- a/include/editeng/eeitem.hxx
+++ b/include/editeng/eeitem.hxx
@@ -61,6 +61,7 @@ class SvxNumBulletItem;
 class SvxJustifyMethodItem;
 class SvxVerJustifyItem;
 class SvxRubyItem;
+class SvxScriptHintItem;
 
 /*
  * NOTE: Changes in this file will probably require
@@ -129,8 +130,9 @@ inline constexpr TypedWhichId<SvxCaseMapItem>         
EE_CHAR_CASEMAP        (EE
 inline constexpr TypedWhichId<SfxGrabBagItem>         EE_CHAR_GRABBAG        
(EE_CHAR_START+30);
 inline constexpr TypedWhichId<SvxColorItem>           EE_CHAR_BKGCOLOR       
(EE_CHAR_START+31);
 inline constexpr TypedWhichId<SvxRubyItem>            EE_CHAR_RUBY           
(EE_CHAR_START+32);
+inline constexpr TypedWhichId<SvxScriptHintItem>      EE_CHAR_SCRIPT_HINT    
(EE_CHAR_START+33);
 
-inline constexpr sal_uInt16                           EE_CHAR_END            
(EE_CHAR_START + 32);
+inline constexpr sal_uInt16                           EE_CHAR_END            
(EE_CHAR_START + 33);
 
 inline constexpr sal_uInt16 EE_FEATURE_START   (EE_CHAR_END + 1);
 inline constexpr sal_uInt16 EE_FEATURE_TAB     (EE_FEATURE_START + 0);
diff --git a/include/editeng/memberids.h b/include/editeng/memberids.h
index 2b75123d94d8..44387a9afc45 100644
--- a/include/editeng/memberids.h
+++ b/include/editeng/memberids.h
@@ -117,6 +117,9 @@
 #define MID_BOLD            0
 #define MID_WEIGHT          1
 
+//SvxScriptHintItem
+#define MID_SCRIPTHINT 0
+
 //SvxLanguageItem
 #define MID_LANG_INT            0
 #define MID_LANG_LOCALE         1
diff --git a/include/editeng/scripthintitem.hxx 
b/include/editeng/scripthintitem.hxx
new file mode 100644
index 000000000000..bdf36183d833
--- /dev/null
+++ b/include/editeng/scripthintitem.hxx
@@ -0,0 +1,56 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <tools/fontenum.hxx>
+#include <svl/eitem.hxx>
+#include <editeng/editengdllapi.h>
+#include <ostream>
+#include <i18nutil/scriptchangescanner.hxx>
+
+class EDITENG_DLLPUBLIC SvxScriptHintItem final : public 
SfxEnumItem<i18nutil::ScriptHintType>
+{
+protected:
+    virtual ItemInstanceManager* getItemInstanceManager() const override;
+
+public:
+    static SfxPoolItem* CreateDefault();
+
+    DECLARE_ITEM_TYPE_FUNCTION(SvxScriptHintItem)
+    SvxScriptHintItem(const sal_uInt16 nId);
+
+    // "pure virtual Methods" from SfxPoolItem + SfxEnumItem
+    virtual bool GetPresentation(SfxItemPresentation ePres, MapUnit 
eCoreMetric,
+                                 MapUnit ePresMetric, OUString& rText,
+                                 const IntlWrapper&) const override;
+
+    virtual SvxScriptHintItem* Clone(SfxItemPool* pPool = nullptr) const 
override;
+    static OUString GetValueText(i18nutil::ScriptHintType eValue);
+    virtual sal_uInt16 GetValueCount() const override;
+
+    virtual bool QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId = 0) 
const override;
+    virtual bool PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) 
override;
+
+    // enum cast
+    i18nutil::ScriptHintType GetScriptHintValue() const { return GetValue(); }
+
+    void dumpAsXml(xmlTextWriterPtr pWriter) const override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/editeng/scripttypeitem.hxx 
b/include/editeng/scriptsetitem.hxx
similarity index 95%
rename from include/editeng/scripttypeitem.hxx
rename to include/editeng/scriptsetitem.hxx
index f5ebe264d5ca..10f61e6052d5 100644
--- a/include/editeng/scripttypeitem.hxx
+++ b/include/editeng/scriptsetitem.hxx
@@ -16,8 +16,7 @@
  *   except in compliance with the License. You may obtain a copy of
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
-#ifndef INCLUDED_EDITENG_SCRIPTTYPEITEM_HXX
-#define INCLUDED_EDITENG_SCRIPTTYPEITEM_HXX
+#pragma once
 
 #include <svl/languageoptions.hxx>
 #include <svl/setitem.hxx>
@@ -48,6 +47,4 @@ public:
                                             sal_uInt16& rComplex );
 };
 
-#endif
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/editeng/unoprnms.hxx b/include/editeng/unoprnms.hxx
index 38c6525af39b..84599b643a61 100644
--- a/include/editeng/unoprnms.hxx
+++ b/include/editeng/unoprnms.hxx
@@ -363,6 +363,8 @@ inline constexpr OUString UNO_NAME_EDIT_CHAR_RUBY_TEXT = 
u"RubyText"_ustr;
 inline constexpr OUString UNO_NAME_EDIT_CHAR_RUBY_ADJUST = u"RubyAdjust"_ustr;
 inline constexpr OUString UNO_NAME_EDIT_CHAR_RUBY_POSITION = 
u"RubyPosition"_ustr;
 
+inline constexpr OUString UNO_NAME_EDIT_CHAR_SCRIPT_HINT = 
u"CharScriptHint"_ustr;
+
 inline constexpr OUString UNO_NAME_BITMAP = u"Bitmap"_ustr;
 
 inline constexpr OUString UNO_NAME_LINKDISPLAYNAME = u"LinkDisplayName"_ustr;
diff --git a/include/editeng/unotext.hxx b/include/editeng/unotext.hxx
index 64d53a97f999..4f9bd4f922f3 100644
--- a/include/editeng/unotext.hxx
+++ b/include/editeng/unotext.hxx
@@ -137,7 +137,8 @@ struct SfxItemPropertyMapEntry;
     { u"CharInteropGrabBag"_ustr,             EE_CHAR_GRABBAG,        
cppu::UnoType<css::uno::Sequence<css::beans::PropertyValue >>::get(), 0, 0 }, \
     { UNO_NAME_EDIT_CHAR_RUBY_TEXT,           EE_CHAR_RUBY,           
::cppu::UnoType<OUString>::get(), 0, MID_RUBY_TEXT }, \
     { UNO_NAME_EDIT_CHAR_RUBY_ADJUST,         EE_CHAR_RUBY,           
::cppu::UnoType<sal_Int16>::get(), 0, MID_RUBY_ADJUST }, \
-    { UNO_NAME_EDIT_CHAR_RUBY_POSITION,       EE_CHAR_RUBY,           
::cppu::UnoType<sal_Int16>::get(), 0, MID_RUBY_POSITION }
+    { UNO_NAME_EDIT_CHAR_RUBY_POSITION,       EE_CHAR_RUBY,           
::cppu::UnoType<sal_Int16>::get(), 0, MID_RUBY_POSITION }, \
+    { UNO_NAME_EDIT_CHAR_SCRIPT_HINT,         EE_CHAR_SCRIPT_HINT,    
::cppu::UnoType<sal_Int16>::get(), 0, MID_SCRIPTHINT }
 
 
 #define SVX_UNOEDIT_FONT_PROPERTIES \
diff --git a/include/i18nutil/scriptchangescanner.hxx 
b/include/i18nutil/scriptchangescanner.hxx
index 04bab9640b90..08ffc6e644da 100644
--- a/include/i18nutil/scriptchangescanner.hxx
+++ b/include/i18nutil/scriptchangescanner.hxx
@@ -6,11 +6,13 @@
  * 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/.
  */
+#pragma once
 
 #include <i18nutil/i18nutildllapi.h>
 #include <rtl/ustring.hxx>
 #include <optional>
 #include <memory>
+#include <vector>
 
 namespace i18nutil
 {
@@ -29,6 +31,48 @@ struct ScriptChange
     sal_Int16 m_nScriptType = 0;
 };
 
+enum class ScriptHintType : sal_uInt16
+{
+    Automatic = 0,
+    Ignore = 1,
+    Latin = 2,
+    Asian = 3,
+    Complex = 4
+};
+
+struct ScriptHint
+{
+    sal_Int32 m_nStartIndex = 0;
+    sal_Int32 m_nEndIndex = 0;
+    ScriptHintType m_eType = ScriptHintType::Automatic;
+
+    ScriptHint(ScriptHintType eType, sal_Int32 nStartIndex, sal_Int32 
nEndIndex)
+        : m_nStartIndex(nStartIndex)
+        , m_nEndIndex(nEndIndex)
+        , m_eType(eType)
+    {
+    }
+};
+
+class I18NUTIL_DLLPUBLIC ScriptHintProvider
+{
+private:
+    std::vector<ScriptHint> m_aHints;
+    ScriptHintType m_eParaHint = ScriptHintType::Automatic;
+
+    std::vector<ScriptHint>::iterator m_pCurrIt;
+    ScriptHintType m_eCurrHint = ScriptHintType::Automatic;
+    sal_Int32 m_nCurrIdx = 0;
+
+public:
+    void SetParagraphLevelHint(ScriptHintType eType);
+    void AddHint(ScriptHintType eType, sal_Int32 nStartIndex, sal_Int32 
nEndIndex);
+
+    void Start();
+    void AdvanceTo(sal_Int32 nNextIdx);
+    ScriptHintType Peek() const;
+};
+
 class I18NUTIL_DLLPUBLIC DirectionChangeScanner
 {
 public:
@@ -56,7 +100,7 @@ MakeDirectionChangeScanner(const OUString& rWord, sal_uInt8 
nInitialDirection);
 
 I18NUTIL_DLLPUBLIC std::unique_ptr<ScriptChangeScanner>
 MakeScriptChangeScanner(const OUString& rWord, sal_Int16 nDefaultScriptType,
-                        DirectionChangeScanner& rDirScanner);
+                        DirectionChangeScanner& rDirScanner, 
ScriptHintProvider& rHints);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx
index e7ea0d249c0c..ea75a108f26d 100644
--- a/include/svl/poolitem.hxx
+++ b/include/svl/poolitem.hxx
@@ -425,6 +425,7 @@ enum class SfxItemType : sal_uInt16
     SvxWritingModeItemType,
     SvxZoomItemType,
     SvxZoomSliderItemType,
+    SvxScriptHintItemType,
     SwAddPrinterItemType,
     SwChannelBGrfType,
     SwChannelGGrfType,
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 8212be5d8f74..a93b23f0e745 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1706,6 +1706,7 @@ namespace xmloff::token {
         XML_SCRIPT,
         XML_SCRIPT_ASIAN,
         XML_SCRIPT_COMPLEX,
+        XML_SCRIPT_TYPE,
         XML_SCROLL,
         XML_SDEV,
         XML_SEARCH_CRITERIA_MUST_APPLY_TO_WHOLE_CELL,
@@ -3582,6 +3583,10 @@ namespace xmloff::token {
         XML_COLOR_VALUE,
         XML_COLOR_TYPE,
 
+        XML_LATIN,
+        XML_ASIAN,
+        XML_COMPLEX,
+
         XML_TOKEN_END
     };
 
diff --git a/include/xmloff/xmltypes.hxx b/include/xmloff/xmltypes.hxx
index ee508e997312..69b00fa035c8 100644
--- a/include/xmloff/xmltypes.hxx
+++ b/include/xmloff/xmltypes.hxx
@@ -301,6 +301,8 @@
 #define XML_TYPE_HYPHENATION_KEEP_TYPE  (XML_TEXT_TYPES_START + 132)
 #define XML_TYPE_HYPHENATION_KEEP_LINE  (XML_TEXT_TYPES_START + 133)
 
+#define XML_TYPE_TEXT_SCRIPT_TYPE       (XML_TEXT_TYPES_START + 134)
+
 #endif // INCLUDED_XMLOFF_XMLTYPES_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/drawfunc/drtxtob.cxx 
b/sc/source/ui/drawfunc/drtxtob.cxx
index 57442c400e8a..0b416b6b1bb4 100644
--- a/sc/source/ui/drawfunc/drtxtob.cxx
+++ b/sc/source/ui/drawfunc/drtxtob.cxx
@@ -43,7 +43,7 @@
 #include <svx/svdoutl.hxx>
 #include <svx/sdooitm.hxx>
 #include <editeng/postitem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <editeng/shdditem.hxx>
 #include <editeng/udlnitem.hxx>
 #include <editeng/wghtitem.hxx>
diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx
index 8fe4e3b0aae1..f15ee1903f12 100644
--- a/sc/source/ui/view/editsh.cxx
+++ b/sc/source/ui/view/editsh.cxx
@@ -40,7 +40,7 @@
 #include <svx/hlnkitem.hxx>
 #include <vcl/EnumContext.hxx>
 #include <editeng/postitem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <editeng/shdditem.hxx>
 #include <editeng/udlnitem.hxx>
 #include <editeng/wghtitem.hxx>
diff --git a/sc/source/ui/view/formatsh.cxx b/sc/source/ui/view/formatsh.cxx
index f7c0e1284f2b..66df2025835a 100644
--- a/sc/source/ui/view/formatsh.cxx
+++ b/sc/source/ui/view/formatsh.cxx
@@ -44,7 +44,7 @@
 #include <editeng/colritem.hxx>
 #include <editeng/brushitem.hxx>
 #include <editeng/frmdiritem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <editeng/shaditem.hxx>
 #include <editeng/justifyitem.hxx>
 #include <editeng/fhgtitem.hxx>
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index 39f3b6a5fd9c..6dd70c5511e1 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -25,7 +25,7 @@
 #include <editeng/boxitem.hxx>
 #include <editeng/fontitem.hxx>
 #include <editeng/lineitem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <svl/srchitem.hxx>
 #include <sfx2/linkmgr.hxx>
 #include <sfx2/dispatch.hxx>
diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx
index 6ccf629c11a0..b3815789c5a8 100644
--- a/sc/source/ui/view/viewutil.cxx
+++ b/sc/source/ui/view/viewutil.cxx
@@ -23,7 +23,7 @@
 #include <sfx2/dispatch.hxx>
 #include <editeng/fontitem.hxx>
 #include <editeng/langitem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <i18nutil/transliteration.hxx>
 #include <svl/itempool.hxx>
 #include <svl/itemset.hxx>
diff --git a/sd/source/ui/view/drtxtob.cxx b/sd/source/ui/view/drtxtob.cxx
index a746a5d7ad0b..52372010b0be 100644
--- a/sd/source/ui/view/drtxtob.cxx
+++ b/sd/source/ui/view/drtxtob.cxx
@@ -44,7 +44,7 @@
 #include <sfx2/tplpitem.hxx>
 #include <editeng/escapementitem.hxx>
 #include <svx/svdoutl.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <editeng/writingmodeitem.hxx>
 #include <editeng/frmdiritem.hxx>
 #include <editeng/fhgtitem.hxx>
diff --git a/sd/source/ui/view/drtxtob1.cxx b/sd/source/ui/view/drtxtob1.cxx
index eddd320be984..b8f9bef30c0c 100644
--- a/sd/source/ui/view/drtxtob1.cxx
+++ b/sd/source/ui/view/drtxtob1.cxx
@@ -44,7 +44,7 @@
 #include <editeng/shdditem.hxx>
 #include <svx/svdpagv.hxx>
 #include <editeng/flstitem.hxx>
-#include <editeng/scripttypeitem.hxx>
+#include <editeng/scriptsetitem.hxx>
 #include <editeng/writingmodeitem.hxx>
 #include <editeng/frmdiritem.hxx>
 #include <editeng/cmapitem.hxx>
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index 5f636621b9a5..178e885130fc 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -5064,7 +5064,7 @@ include/editeng/prntitem.hxx
 include/editeng/protitem.hxx
 include/editeng/rsiditem.hxx
 include/editeng/scriptspaceitem.hxx
-include/editeng/scripttypeitem.hxx
+include/editeng/scriptsetitem.hxx
 include/editeng/shaditem.hxx
 include/editeng/shdditem.hxx
 include/editeng/sizeitem.hxx
diff --git a/sw/inc/charatr.hxx b/sw/inc/charatr.hxx
index 9b16277e284e..eb13fb982094 100644
--- a/sw/inc/charatr.hxx
+++ b/sw/inc/charatr.hxx
@@ -42,6 +42,7 @@
 #include <editeng/charhiddenitem.hxx>
 #include <editeng/langitem.hxx>
 #include <editeng/colritem.hxx>
+#include <editeng/scripthintitem.hxx>
 
 // implementation of the character attribute methods of SwAttrSet
 
@@ -111,6 +112,8 @@ inline const SvxCharReliefItem   &SwAttrSet::GetCharRelief( 
bool bInP ) const
     {   return Get( RES_CHRATR_RELIEF, bInP ); }
 inline const SvxCharHiddenItem   &SwAttrSet::GetCharHidden( bool bInP ) const
     {   return Get( RES_CHRATR_HIDDEN, bInP ); }
+inline const SvxScriptHintItem   &SwAttrSet::GetCharScriptTypeHint( bool bInP 
) const
+    {   return Get( RES_CHRATR_SCRIPT_HINT, bInP ); }
 
 // implementation of the character attribute methods of SwFormat
 
diff --git a/sw/inc/hintids.hxx b/sw/inc/hintids.hxx
index caf807f773be..61d5d546f079 100644
--- a/sw/inc/hintids.hxx
+++ b/sw/inc/hintids.hxx
@@ -85,6 +85,7 @@ class SvxPrintItem;
 class SvxProtectItem;
 class SvxRsidItem;
 class SvxScriptSpaceItem;
+class SvxScriptHintItem;
 class SvxShadowedItem;
 class SvxShadowItem;
 class SvxTabStopItem;
@@ -196,52 +197,53 @@ inline constexpr sal_uInt16 POOLATTR_BEGIN(HINT_BEGIN);
 // Ranges for the IDs of the format-attributes.
 // Which-values for character-format attributes.
 inline constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN);
-inline constexpr TypedWhichId<SvxCaseMapItem> 
RES_CHRATR_CASEMAP(RES_CHRATR_BEGIN); // 1
-inline constexpr TypedWhichId<SvxColorItem> RES_CHRATR_CHARSETCOLOR(2);
-inline constexpr TypedWhichId<SvxColorItem> RES_CHRATR_COLOR(3);
-inline constexpr TypedWhichId<SvxContourItem> RES_CHRATR_CONTOUR(4);
-inline constexpr TypedWhichId<SvxCrossedOutItem> RES_CHRATR_CROSSEDOUT(5);
-inline constexpr TypedWhichId<SvxEscapementItem> RES_CHRATR_ESCAPEMENT(6);
-inline constexpr TypedWhichId<SvxFontItem> RES_CHRATR_FONT(7);
-inline constexpr TypedWhichId<SvxFontHeightItem> RES_CHRATR_FONTSIZE(8);
-inline constexpr TypedWhichId<SvxKerningItem> RES_CHRATR_KERNING(9);
-inline constexpr TypedWhichId<SvxLanguageItem> RES_CHRATR_LANGUAGE(10);
-inline constexpr TypedWhichId<SvxPostureItem> RES_CHRATR_POSTURE(11);
-inline constexpr TypedWhichId<SfxVoidItem> RES_CHRATR_UNUSED1(12);
-inline constexpr TypedWhichId<SvxShadowedItem> RES_CHRATR_SHADOWED(13);
-inline constexpr TypedWhichId<SvxUnderlineItem> RES_CHRATR_UNDERLINE(14);
-inline constexpr TypedWhichId<SvxWeightItem> RES_CHRATR_WEIGHT(15);
-inline constexpr TypedWhichId<SvxWordLineModeItem> RES_CHRATR_WORDLINEMODE(16);
-inline constexpr TypedWhichId<SvxAutoKernItem> RES_CHRATR_AUTOKERN(17);
-inline constexpr TypedWhichId<SvxBlinkItem> RES_CHRATR_BLINK(18);
-inline constexpr TypedWhichId<SvxNoHyphenItem> RES_CHRATR_NOHYPHEN(19);
-inline constexpr TypedWhichId<SfxVoidItem> RES_CHRATR_UNUSED2(20);
-inline constexpr TypedWhichId<SvxBrushItem> RES_CHRATR_BACKGROUND(21);
-inline constexpr TypedWhichId<SvxFontItem> RES_CHRATR_CJK_FONT(22);
-inline constexpr TypedWhichId<SvxFontHeightItem> RES_CHRATR_CJK_FONTSIZE(23);
-inline constexpr TypedWhichId<SvxLanguageItem> RES_CHRATR_CJK_LANGUAGE(24);
-inline constexpr TypedWhichId<SvxPostureItem> RES_CHRATR_CJK_POSTURE(25);
-inline constexpr TypedWhichId<SvxWeightItem> RES_CHRATR_CJK_WEIGHT(26);
-inline constexpr TypedWhichId<SvxFontItem> RES_CHRATR_CTL_FONT(27);
-inline constexpr TypedWhichId<SvxFontHeightItem> RES_CHRATR_CTL_FONTSIZE(28);
-inline constexpr TypedWhichId<SvxLanguageItem> RES_CHRATR_CTL_LANGUAGE(29);
-inline constexpr TypedWhichId<SvxPostureItem> RES_CHRATR_CTL_POSTURE(30);
-inline constexpr TypedWhichId<SvxWeightItem> RES_CHRATR_CTL_WEIGHT(31);
-inline constexpr TypedWhichId<SvxCharRotateItem> RES_CHRATR_ROTATE(32);
-inline constexpr TypedWhichId<SvxEmphasisMarkItem> 
RES_CHRATR_EMPHASIS_MARK(33);
-inline constexpr TypedWhichId<SvxTwoLinesItem> RES_CHRATR_TWO_LINES(34);
-inline constexpr TypedWhichId<SvxCharScaleWidthItem> RES_CHRATR_SCALEW(35);
-inline constexpr TypedWhichId<SvxCharReliefItem> RES_CHRATR_RELIEF(36);
-inline constexpr TypedWhichId<SvxCharHiddenItem> RES_CHRATR_HIDDEN(37);
-inline constexpr TypedWhichId<SvxOverlineItem> RES_CHRATR_OVERLINE(38);
-inline constexpr TypedWhichId<SvxRsidItem> RES_CHRATR_RSID(39);
-inline constexpr TypedWhichId<SvxBoxItem> RES_CHRATR_BOX(40);
-inline constexpr TypedWhichId<SvxShadowItem> RES_CHRATR_SHADOW(41);
-inline constexpr TypedWhichId<SvxBrushItem> RES_CHRATR_HIGHLIGHT(42);
-inline constexpr TypedWhichId<SfxGrabBagItem> RES_CHRATR_GRABBAG(43);
-inline constexpr TypedWhichId<SfxInt16Item> RES_CHRATR_BIDIRTL(44);
-inline constexpr TypedWhichId<SfxInt16Item> RES_CHRATR_IDCTHINT(45);
-inline constexpr sal_uInt16 RES_CHRATR_END(46);
+inline constexpr TypedWhichId<SvxCaseMapItem> 
RES_CHRATR_CASEMAP(RES_CHRATR_BEGIN + 0); // 1
+inline constexpr TypedWhichId<SvxColorItem> 
RES_CHRATR_CHARSETCOLOR(RES_CHRATR_BEGIN + 1);
+inline constexpr TypedWhichId<SvxColorItem> RES_CHRATR_COLOR(RES_CHRATR_BEGIN 
+ 2);
+inline constexpr TypedWhichId<SvxContourItem> 
RES_CHRATR_CONTOUR(RES_CHRATR_BEGIN + 3);
+inline constexpr TypedWhichId<SvxCrossedOutItem> 
RES_CHRATR_CROSSEDOUT(RES_CHRATR_BEGIN + 4);
+inline constexpr TypedWhichId<SvxEscapementItem> 
RES_CHRATR_ESCAPEMENT(RES_CHRATR_BEGIN + 5);
+inline constexpr TypedWhichId<SvxFontItem> RES_CHRATR_FONT(RES_CHRATR_BEGIN + 
6);
+inline constexpr TypedWhichId<SvxFontHeightItem> 
RES_CHRATR_FONTSIZE(RES_CHRATR_BEGIN + 7);
+inline constexpr TypedWhichId<SvxKerningItem> 
RES_CHRATR_KERNING(RES_CHRATR_BEGIN + 8);
+inline constexpr TypedWhichId<SvxLanguageItem> 
RES_CHRATR_LANGUAGE(RES_CHRATR_BEGIN + 9);
+inline constexpr TypedWhichId<SvxPostureItem> 
RES_CHRATR_POSTURE(RES_CHRATR_BEGIN + 10);
+inline constexpr TypedWhichId<SfxVoidItem> RES_CHRATR_UNUSED1(RES_CHRATR_BEGIN 
+ 11);
+inline constexpr TypedWhichId<SvxShadowedItem> 
RES_CHRATR_SHADOWED(RES_CHRATR_BEGIN + 12);
+inline constexpr TypedWhichId<SvxUnderlineItem> 
RES_CHRATR_UNDERLINE(RES_CHRATR_BEGIN + 13);
+inline constexpr TypedWhichId<SvxWeightItem> 
RES_CHRATR_WEIGHT(RES_CHRATR_BEGIN + 14);
+inline constexpr TypedWhichId<SvxWordLineModeItem> 
RES_CHRATR_WORDLINEMODE(RES_CHRATR_BEGIN + 15);
+inline constexpr TypedWhichId<SvxAutoKernItem> 
RES_CHRATR_AUTOKERN(RES_CHRATR_BEGIN + 16);
+inline constexpr TypedWhichId<SvxBlinkItem> RES_CHRATR_BLINK(RES_CHRATR_BEGIN 
+ 17);
+inline constexpr TypedWhichId<SvxNoHyphenItem> 
RES_CHRATR_NOHYPHEN(RES_CHRATR_BEGIN + 18);
+inline constexpr TypedWhichId<SfxVoidItem> RES_CHRATR_UNUSED2(RES_CHRATR_BEGIN 
+ 19);
+inline constexpr TypedWhichId<SvxBrushItem> 
RES_CHRATR_BACKGROUND(RES_CHRATR_BEGIN + 20);
+inline constexpr TypedWhichId<SvxFontItem> 
RES_CHRATR_CJK_FONT(RES_CHRATR_BEGIN + 21);
+inline constexpr TypedWhichId<SvxFontHeightItem> 
RES_CHRATR_CJK_FONTSIZE(RES_CHRATR_BEGIN + 22);
+inline constexpr TypedWhichId<SvxLanguageItem> 
RES_CHRATR_CJK_LANGUAGE(RES_CHRATR_BEGIN + 23);
+inline constexpr TypedWhichId<SvxPostureItem> 
RES_CHRATR_CJK_POSTURE(RES_CHRATR_BEGIN + 24);
+inline constexpr TypedWhichId<SvxWeightItem> 
RES_CHRATR_CJK_WEIGHT(RES_CHRATR_BEGIN + 25);
+inline constexpr TypedWhichId<SvxFontItem> 
RES_CHRATR_CTL_FONT(RES_CHRATR_BEGIN + 26);
+inline constexpr TypedWhichId<SvxFontHeightItem> 
RES_CHRATR_CTL_FONTSIZE(RES_CHRATR_BEGIN + 27);
+inline constexpr TypedWhichId<SvxLanguageItem> 
RES_CHRATR_CTL_LANGUAGE(RES_CHRATR_BEGIN + 28);
+inline constexpr TypedWhichId<SvxPostureItem> 
RES_CHRATR_CTL_POSTURE(RES_CHRATR_BEGIN + 29);
+inline constexpr TypedWhichId<SvxWeightItem> 
RES_CHRATR_CTL_WEIGHT(RES_CHRATR_BEGIN + 30);
+inline constexpr TypedWhichId<SvxCharRotateItem> 
RES_CHRATR_ROTATE(RES_CHRATR_BEGIN + 31);
+inline constexpr TypedWhichId<SvxEmphasisMarkItem> 
RES_CHRATR_EMPHASIS_MARK(RES_CHRATR_BEGIN + 32);
+inline constexpr TypedWhichId<SvxTwoLinesItem> 
RES_CHRATR_TWO_LINES(RES_CHRATR_BEGIN + 33);
+inline constexpr TypedWhichId<SvxCharScaleWidthItem> 
RES_CHRATR_SCALEW(RES_CHRATR_BEGIN + 34);
+inline constexpr TypedWhichId<SvxCharReliefItem> 
RES_CHRATR_RELIEF(RES_CHRATR_BEGIN + 35);
+inline constexpr TypedWhichId<SvxCharHiddenItem> 
RES_CHRATR_HIDDEN(RES_CHRATR_BEGIN + 36);
+inline constexpr TypedWhichId<SvxOverlineItem> 
RES_CHRATR_OVERLINE(RES_CHRATR_BEGIN + 37);
+inline constexpr TypedWhichId<SvxRsidItem> RES_CHRATR_RSID(RES_CHRATR_BEGIN + 
38);
+inline constexpr TypedWhichId<SvxBoxItem> RES_CHRATR_BOX(RES_CHRATR_BEGIN + 
39);
+inline constexpr TypedWhichId<SvxShadowItem> 
RES_CHRATR_SHADOW(RES_CHRATR_BEGIN + 40);
+inline constexpr TypedWhichId<SvxBrushItem> 
RES_CHRATR_HIGHLIGHT(RES_CHRATR_BEGIN + 41);
+inline constexpr TypedWhichId<SfxGrabBagItem> 
RES_CHRATR_GRABBAG(RES_CHRATR_BEGIN + 42);
+inline constexpr TypedWhichId<SfxInt16Item> 
RES_CHRATR_BIDIRTL(RES_CHRATR_BEGIN + 43);
+inline constexpr TypedWhichId<SfxInt16Item> 
RES_CHRATR_IDCTHINT(RES_CHRATR_BEGIN + 44);
+inline constexpr TypedWhichId<SvxScriptHintItem> 
RES_CHRATR_SCRIPT_HINT(RES_CHRATR_BEGIN + 45);
+inline constexpr sal_uInt16 RES_CHRATR_END(RES_CHRATR_BEGIN + 46);
 
 // this Attribute used only in a TextNodes SwpAttr-Array
 inline constexpr sal_uInt16 RES_TXTATR_BEGIN(RES_CHRATR_END);
@@ -263,188 +265,200 @@ inline constexpr sal_uInt16 
RES_TXTATR_BEGIN(RES_CHRATR_END);
    - META and METAFIELD must precede CJK_RUBY and INETFMT
  */
 inline constexpr sal_uInt16 RES_TXTATR_WITHEND_BEGIN(RES_TXTATR_BEGIN);
-inline constexpr TypedWhichId<SwFormatRefMark> 
RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN); // 46
-inline constexpr TypedWhichId<SwTOXMark> RES_TXTATR_TOXMARK(47);
-inline constexpr TypedWhichId<SwFormatMeta> RES_TXTATR_META(48);
-inline constexpr TypedWhichId<SwFormatMeta> RES_TXTATR_METAFIELD(49);
-inline constexpr TypedWhichId<SwFormatAutoFormat> RES_TXTATR_AUTOFMT(50);
-inline constexpr TypedWhichId<SwFormatINetFormat> RES_TXTATR_INETFMT(51);
-inline constexpr TypedWhichId<SwFormatCharFormat> RES_TXTATR_CHARFMT(52);
-inline constexpr TypedWhichId<SwFormatRuby> RES_TXTATR_CJK_RUBY(53);
-inline constexpr TypedWhichId<SvXMLAttrContainerItem> 
RES_TXTATR_UNKNOWN_CONTAINER(54);
-inline constexpr TypedWhichId<SwFormatField> RES_TXTATR_INPUTFIELD(55);
-inline constexpr TypedWhichId<SwFormatContentControl> 
RES_TXTATR_CONTENTCONTROL(56);
-inline constexpr sal_uInt16 RES_TXTATR_WITHEND_END(57);
+inline constexpr TypedWhichId<SwFormatRefMark> 
RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN
+                                                                  + 0); // 47
+inline constexpr TypedWhichId<SwTOXMark> 
RES_TXTATR_TOXMARK(RES_TXTATR_WITHEND_BEGIN + 1);
+inline constexpr TypedWhichId<SwFormatMeta> 
RES_TXTATR_META(RES_TXTATR_WITHEND_BEGIN + 2);
+inline constexpr TypedWhichId<SwFormatMeta> 
RES_TXTATR_METAFIELD(RES_TXTATR_WITHEND_BEGIN + 3);
+inline constexpr TypedWhichId<SwFormatAutoFormat> 
RES_TXTATR_AUTOFMT(RES_TXTATR_WITHEND_BEGIN + 4);
+inline constexpr TypedWhichId<SwFormatINetFormat> 
RES_TXTATR_INETFMT(RES_TXTATR_WITHEND_BEGIN + 5);
+inline constexpr TypedWhichId<SwFormatCharFormat> 
RES_TXTATR_CHARFMT(RES_TXTATR_WITHEND_BEGIN + 6);
+inline constexpr TypedWhichId<SwFormatRuby> 
RES_TXTATR_CJK_RUBY(RES_TXTATR_WITHEND_BEGIN + 7);
+inline constexpr TypedWhichId<SvXMLAttrContainerItem>
+    RES_TXTATR_UNKNOWN_CONTAINER(RES_TXTATR_WITHEND_BEGIN + 8);
+inline constexpr TypedWhichId<SwFormatField> 
RES_TXTATR_INPUTFIELD(RES_TXTATR_WITHEND_BEGIN + 9);
+inline constexpr TypedWhichId<SwFormatContentControl>
+    RES_TXTATR_CONTENTCONTROL(RES_TXTATR_WITHEND_BEGIN + 10);
+inline constexpr sal_uInt16 RES_TXTATR_WITHEND_END(RES_TXTATR_WITHEND_BEGIN + 
11);
 
 // all TextAttributes without an end
 inline constexpr sal_uInt16 RES_TXTATR_NOEND_BEGIN(RES_TXTATR_WITHEND_END);
-inline constexpr TypedWhichId<SwFormatField> 
RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN); // 57
-inline constexpr TypedWhichId<SwFormatFlyCnt> RES_TXTATR_FLYCNT(58);
-inline constexpr TypedWhichId<SwFormatFootnote> RES_TXTATR_FTN(59);
-inline constexpr TypedWhichId<SwFormatField> RES_TXTATR_ANNOTATION(60);
-inline constexpr TypedWhichId<SwFormatLineBreak> RES_TXTATR_LINEBREAK(61);
-inline constexpr TypedWhichId<SfxBoolItem> RES_TXTATR_DUMMY1(62);
-inline constexpr sal_uInt16 RES_TXTATR_NOEND_END(63);
+inline constexpr TypedWhichId<SwFormatField> 
RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN + 0); // 58
+inline constexpr TypedWhichId<SwFormatFlyCnt> 
RES_TXTATR_FLYCNT(RES_TXTATR_NOEND_BEGIN + 1);
+inline constexpr TypedWhichId<SwFormatFootnote> 
RES_TXTATR_FTN(RES_TXTATR_NOEND_BEGIN + 2);
+inline constexpr TypedWhichId<SwFormatField> 
RES_TXTATR_ANNOTATION(RES_TXTATR_NOEND_BEGIN + 3);
+inline constexpr TypedWhichId<SwFormatLineBreak> 
RES_TXTATR_LINEBREAK(RES_TXTATR_NOEND_BEGIN + 4);
+inline constexpr TypedWhichId<SfxBoolItem> 
RES_TXTATR_DUMMY1(RES_TXTATR_NOEND_BEGIN + 5);
+inline constexpr sal_uInt16 RES_TXTATR_NOEND_END(RES_TXTATR_NOEND_BEGIN + 6);
 inline constexpr sal_uInt16 RES_TXTATR_END(RES_TXTATR_NOEND_END);
 
 inline constexpr sal_uInt16 RES_PARATR_BEGIN(RES_TXTATR_END);
-inline constexpr TypedWhichId<SvxLineSpacingItem> 
RES_PARATR_LINESPACING(RES_PARATR_BEGIN); // 63
-inline constexpr TypedWhichId<SvxAdjustItem> RES_PARATR_ADJUST(64);
-inline constexpr TypedWhichId<SvxFormatSplitItem> RES_PARATR_SPLIT(65);
-inline constexpr TypedWhichId<SvxOrphansItem> RES_PARATR_ORPHANS(66);
-inline constexpr TypedWhichId<SvxWidowsItem> RES_PARATR_WIDOWS(67);
-inline constexpr TypedWhichId<SvxTabStopItem> RES_PARATR_TABSTOP(68);
-inline constexpr TypedWhichId<SvxHyphenZoneItem> RES_PARATR_HYPHENZONE(69);
-inline constexpr TypedWhichId<SwFormatDrop> RES_PARATR_DROP(70);
-inline constexpr TypedWhichId<SwRegisterItem> RES_PARATR_REGISTER(71);
-inline constexpr TypedWhichId<SwNumRuleItem> RES_PARATR_NUMRULE(72);
-inline constexpr TypedWhichId<SvxScriptSpaceItem> RES_PARATR_SCRIPTSPACE(73);
-inline constexpr TypedWhichId<SvxHangingPunctuationItem> 
RES_PARATR_HANGINGPUNCTUATION(74);
-inline constexpr TypedWhichId<SvxForbiddenRuleItem> 
RES_PARATR_FORBIDDEN_RULES(75);
-inline constexpr TypedWhichId<SvxParaVertAlignItem> RES_PARATR_VERTALIGN(76);
-inline constexpr TypedWhichId<SvxParaGridItem> RES_PARATR_SNAPTOGRID(77);
-inline constexpr TypedWhichId<SwParaConnectBorderItem> 
RES_PARATR_CONNECT_BORDER(78);
-inline constexpr TypedWhichId<SfxUInt16Item> RES_PARATR_OUTLINELEVEL(79);
-inline constexpr TypedWhichId<SvxRsidItem> RES_PARATR_RSID(80);
-inline constexpr TypedWhichId<SfxGrabBagItem> RES_PARATR_GRABBAG(81);
-inline constexpr sal_uInt16 RES_PARATR_END(82);
+inline constexpr TypedWhichId<SvxLineSpacingItem> 
RES_PARATR_LINESPACING(RES_PARATR_BEGIN
+                                                                         + 0); 
// 64
+inline constexpr TypedWhichId<SvxAdjustItem> 
RES_PARATR_ADJUST(RES_PARATR_BEGIN + 1);
+inline constexpr TypedWhichId<SvxFormatSplitItem> 
RES_PARATR_SPLIT(RES_PARATR_BEGIN + 2);
+inline constexpr TypedWhichId<SvxOrphansItem> 
RES_PARATR_ORPHANS(RES_PARATR_BEGIN + 3);
+inline constexpr TypedWhichId<SvxWidowsItem> 
RES_PARATR_WIDOWS(RES_PARATR_BEGIN + 4);
+inline constexpr TypedWhichId<SvxTabStopItem> 
RES_PARATR_TABSTOP(RES_PARATR_BEGIN + 5);
+inline constexpr TypedWhichId<SvxHyphenZoneItem> 
RES_PARATR_HYPHENZONE(RES_PARATR_BEGIN + 6);
+inline constexpr TypedWhichId<SwFormatDrop> RES_PARATR_DROP(RES_PARATR_BEGIN + 
7);
+inline constexpr TypedWhichId<SwRegisterItem> 
RES_PARATR_REGISTER(RES_PARATR_BEGIN + 8);
+inline constexpr TypedWhichId<SwNumRuleItem> 
RES_PARATR_NUMRULE(RES_PARATR_BEGIN + 9);
+inline constexpr TypedWhichId<SvxScriptSpaceItem> 
RES_PARATR_SCRIPTSPACE(RES_PARATR_BEGIN + 10);
+inline constexpr TypedWhichId<SvxHangingPunctuationItem>
+    RES_PARATR_HANGINGPUNCTUATION(RES_PARATR_BEGIN + 11);
+inline constexpr TypedWhichId<SvxForbiddenRuleItem> 
RES_PARATR_FORBIDDEN_RULES(RES_PARATR_BEGIN
+                                                                               
+ 12);
+inline constexpr TypedWhichId<SvxParaVertAlignItem> 
RES_PARATR_VERTALIGN(RES_PARATR_BEGIN + 13);
+inline constexpr TypedWhichId<SvxParaGridItem> 
RES_PARATR_SNAPTOGRID(RES_PARATR_BEGIN + 14);
+inline constexpr TypedWhichId<SwParaConnectBorderItem> 
RES_PARATR_CONNECT_BORDER(RES_PARATR_BEGIN
+                                                                               
  + 15);
+inline constexpr TypedWhichId<SfxUInt16Item> 
RES_PARATR_OUTLINELEVEL(RES_PARATR_BEGIN + 16);
+inline constexpr TypedWhichId<SvxRsidItem> RES_PARATR_RSID(RES_PARATR_BEGIN + 
17);
+inline constexpr TypedWhichId<SfxGrabBagItem> 
RES_PARATR_GRABBAG(RES_PARATR_BEGIN + 18);
+inline constexpr sal_uInt16 RES_PARATR_END(RES_PARATR_BEGIN + 19);
 
 // list attributes for paragraphs.
 // intentionally these list attributes are not contained in paragraph styles
 inline constexpr sal_uInt16 RES_PARATR_LIST_BEGIN(RES_PARATR_END);
-inline constexpr TypedWhichId<SfxStringItem> 
RES_PARATR_LIST_ID(RES_PARATR_LIST_BEGIN); // 82
-inline constexpr TypedWhichId<SfxInt16Item> RES_PARATR_LIST_LEVEL(83);
-inline constexpr TypedWhichId<SfxBoolItem> RES_PARATR_LIST_ISRESTART(84);
-inline constexpr TypedWhichId<SfxInt16Item> RES_PARATR_LIST_RESTARTVALUE(85);
-inline constexpr TypedWhichId<SfxBoolItem> RES_PARATR_LIST_ISCOUNTED(86);
+inline constexpr TypedWhichId<SfxStringItem> 
RES_PARATR_LIST_ID(RES_PARATR_LIST_BEGIN + 0); // 83
+inline constexpr TypedWhichId<SfxInt16Item> 
RES_PARATR_LIST_LEVEL(RES_PARATR_LIST_BEGIN + 1);
+inline constexpr TypedWhichId<SfxBoolItem> 
RES_PARATR_LIST_ISRESTART(RES_PARATR_LIST_BEGIN + 2);
+inline constexpr TypedWhichId<SfxInt16Item> 
RES_PARATR_LIST_RESTARTVALUE(RES_PARATR_LIST_BEGIN + 3);
+inline constexpr TypedWhichId<SfxBoolItem> 
RES_PARATR_LIST_ISCOUNTED(RES_PARATR_LIST_BEGIN + 4);
 inline constexpr TypedWhichId<SwFormatAutoFormat>
-    RES_PARATR_LIST_AUTOFMT(87); //TypedWhichId<SfxSetItem>(87)
-inline constexpr sal_uInt16 RES_PARATR_LIST_END(88);
+    RES_PARATR_LIST_AUTOFMT(RES_PARATR_LIST_BEGIN + 5); 
//TypedWhichId<SfxSetItem>(88)
+inline constexpr sal_uInt16 RES_PARATR_LIST_END(RES_PARATR_LIST_BEGIN + 6);
 
 inline constexpr sal_uInt16 RES_FRMATR_BEGIN(RES_PARATR_LIST_END);
-inline constexpr TypedWhichId<SwFormatFillOrder> 
RES_FILL_ORDER(RES_FRMATR_BEGIN);
-inline constexpr TypedWhichId<SwFormatFrameSize> RES_FRM_SIZE(89);
-inline constexpr TypedWhichId<SvxPaperBinItem> RES_PAPER_BIN(90);
-inline constexpr TypedWhichId<SvxFirstLineIndentItem> RES_MARGIN_FIRSTLINE(91);
-inline constexpr TypedWhichId<SvxTextLeftMarginItem> RES_MARGIN_TEXTLEFT(92);
-inline constexpr TypedWhichId<SvxRightMarginItem> RES_MARGIN_RIGHT(93);
-inline constexpr TypedWhichId<SvxLeftMarginItem> RES_MARGIN_LEFT(94);
-inline constexpr TypedWhichId<SvxGutterLeftMarginItem> RES_MARGIN_GUTTER(95);
-inline constexpr TypedWhichId<SvxGutterRightMarginItem> 
RES_MARGIN_GUTTER_RIGHT(96);
-inline constexpr TypedWhichId<SvxLRSpaceItem> RES_LR_SPACE(97);
-inline constexpr TypedWhichId<SvxULSpaceItem> RES_UL_SPACE(98);
-inline constexpr TypedWhichId<SwFormatPageDesc> RES_PAGEDESC(99);
-inline constexpr TypedWhichId<SvxFormatBreakItem> RES_BREAK(100);
-inline constexpr TypedWhichId<SwFormatContent> RES_CNTNT(101);
-inline constexpr TypedWhichId<SwFormatHeader> RES_HEADER(102);
-inline constexpr TypedWhichId<SwFormatFooter> RES_FOOTER(103);
-inline constexpr TypedWhichId<SvxPrintItem> RES_PRINT(104);
-inline constexpr TypedWhichId<SvxOpaqueItem> RES_OPAQUE(105);
-inline constexpr TypedWhichId<SvxProtectItem> RES_PROTECT(106);
-inline constexpr TypedWhichId<SwFormatSurround> RES_SURROUND(107);
-inline constexpr TypedWhichId<SwFormatVertOrient> RES_VERT_ORIENT(108);
-inline constexpr TypedWhichId<SwFormatHoriOrient> RES_HORI_ORIENT(109);
-inline constexpr TypedWhichId<SwFormatAnchor> RES_ANCHOR(110);
-inline constexpr TypedWhichId<SvxBrushItem> RES_BACKGROUND(111);
-inline constexpr TypedWhichId<SvxBoxItem> RES_BOX(112);
-inline constexpr TypedWhichId<SvxShadowItem> RES_SHADOW(113);
-inline constexpr TypedWhichId<SvxMacroItem> RES_FRMMACRO(114);
-inline constexpr TypedWhichId<SwFormatCol> RES_COL(115);
-inline constexpr TypedWhichId<SvxFormatKeepItem> RES_KEEP(116);
-inline constexpr TypedWhichId<SwFormatURL> RES_URL(117);
-inline constexpr TypedWhichId<SwFormatEditInReadonly> 
RES_EDIT_IN_READONLY(118);
-inline constexpr TypedWhichId<SwFormatLayoutSplit> RES_LAYOUT_SPLIT(119);
-inline constexpr TypedWhichId<SwFormatChain> RES_CHAIN(120);
-inline constexpr TypedWhichId<SwTextGridItem> RES_TEXTGRID(121);
-inline constexpr TypedWhichId<SwFormatLineNumber> RES_LINENUMBER(122);
-inline constexpr TypedWhichId<SwFormatFootnoteAtTextEnd> 
RES_FTN_AT_TXTEND(123);
-inline constexpr TypedWhichId<SwFormatEndAtTextEnd> RES_END_AT_TXTEND(124);
-inline constexpr TypedWhichId<SwFormatNoBalancedColumns> 
RES_COLUMNBALANCE(125);
-inline constexpr TypedWhichId<SvxFrameDirectionItem> RES_FRAMEDIR(126);
-inline constexpr TypedWhichId<SwHeaderAndFooterEatSpacingItem> 
RES_HEADER_FOOTER_EAT_SPACING(127);
-inline constexpr TypedWhichId<SwFormatRowSplit> RES_ROW_SPLIT(128);
-inline constexpr TypedWhichId<SwFormatFlySplit> RES_FLY_SPLIT(129);
-inline constexpr TypedWhichId<SwFormatFollowTextFlow> 
RES_FOLLOW_TEXT_FLOW(130);
-inline constexpr TypedWhichId<SfxBoolItem> RES_COLLAPSING_BORDERS(131);
-inline constexpr TypedWhichId<SwFormatWrapInfluenceOnObjPos> 
RES_WRAP_INFLUENCE_ON_OBJPOS(132);
-inline constexpr TypedWhichId<SwFormatAutoFormat> RES_AUTO_STYLE(133);
-inline constexpr TypedWhichId<SfxStringItem> RES_FRMATR_STYLE_NAME(134);
-inline constexpr TypedWhichId<SfxStringItem> 
RES_FRMATR_CONDITIONAL_STYLE_NAME(135);
-inline constexpr TypedWhichId<SfxGrabBagItem> RES_FRMATR_GRABBAG(136);
-inline constexpr TypedWhichId<SdrTextVertAdjustItem> RES_TEXT_VERT_ADJUST(137);
-inline constexpr TypedWhichId<SfxBoolItem> RES_BACKGROUND_FULL_SIZE(138);
-inline constexpr TypedWhichId<SfxBoolItem> RES_RTL_GUTTER(139);
-inline constexpr TypedWhichId<SfxBoolItem> RES_DECORATIVE(140);
-inline constexpr TypedWhichId<SwFormatWrapTextAtFlyStart> 
RES_WRAP_TEXT_AT_FLY_START(141);
-inline constexpr sal_uInt16 RES_FRMATR_END(142);
+inline constexpr TypedWhichId<SwFormatFillOrder> 
RES_FILL_ORDER(RES_FRMATR_BEGIN + 0);
+inline constexpr TypedWhichId<SwFormatFrameSize> RES_FRM_SIZE(RES_FRMATR_BEGIN 
+ 1);
+inline constexpr TypedWhichId<SvxPaperBinItem> RES_PAPER_BIN(RES_FRMATR_BEGIN 
+ 2);
+inline constexpr TypedWhichId<SvxFirstLineIndentItem> 
RES_MARGIN_FIRSTLINE(RES_FRMATR_BEGIN + 3);
+inline constexpr TypedWhichId<SvxTextLeftMarginItem> 
RES_MARGIN_TEXTLEFT(RES_FRMATR_BEGIN + 4);
+inline constexpr TypedWhichId<SvxRightMarginItem> 
RES_MARGIN_RIGHT(RES_FRMATR_BEGIN + 5);
+inline constexpr TypedWhichId<SvxLeftMarginItem> 
RES_MARGIN_LEFT(RES_FRMATR_BEGIN + 6);
+inline constexpr TypedWhichId<SvxGutterLeftMarginItem> 
RES_MARGIN_GUTTER(RES_FRMATR_BEGIN + 7);
+inline constexpr TypedWhichId<SvxGutterRightMarginItem> 
RES_MARGIN_GUTTER_RIGHT(RES_FRMATR_BEGIN
+                                                                               
 + 8);
+inline constexpr TypedWhichId<SvxLRSpaceItem> RES_LR_SPACE(RES_FRMATR_BEGIN + 
9);
+inline constexpr TypedWhichId<SvxULSpaceItem> RES_UL_SPACE(RES_FRMATR_BEGIN + 
10);
+inline constexpr TypedWhichId<SwFormatPageDesc> RES_PAGEDESC(RES_FRMATR_BEGIN 
+ 11);
+inline constexpr TypedWhichId<SvxFormatBreakItem> RES_BREAK(RES_FRMATR_BEGIN + 
12);
+inline constexpr TypedWhichId<SwFormatContent> RES_CNTNT(RES_FRMATR_BEGIN + 
13);
+inline constexpr TypedWhichId<SwFormatHeader> RES_HEADER(RES_FRMATR_BEGIN + 
14);
+inline constexpr TypedWhichId<SwFormatFooter> RES_FOOTER(RES_FRMATR_BEGIN + 
15);
+inline constexpr TypedWhichId<SvxPrintItem> RES_PRINT(RES_FRMATR_BEGIN + 16);
+inline constexpr TypedWhichId<SvxOpaqueItem> RES_OPAQUE(RES_FRMATR_BEGIN + 17);
+inline constexpr TypedWhichId<SvxProtectItem> RES_PROTECT(RES_FRMATR_BEGIN + 
18);
+inline constexpr TypedWhichId<SwFormatSurround> RES_SURROUND(RES_FRMATR_BEGIN 
+ 19);
+inline constexpr TypedWhichId<SwFormatVertOrient> 
RES_VERT_ORIENT(RES_FRMATR_BEGIN + 20);
+inline constexpr TypedWhichId<SwFormatHoriOrient> 
RES_HORI_ORIENT(RES_FRMATR_BEGIN + 21);
+inline constexpr TypedWhichId<SwFormatAnchor> RES_ANCHOR(RES_FRMATR_BEGIN + 
22);
+inline constexpr TypedWhichId<SvxBrushItem> RES_BACKGROUND(RES_FRMATR_BEGIN + 
23);
+inline constexpr TypedWhichId<SvxBoxItem> RES_BOX(RES_FRMATR_BEGIN + 24);
+inline constexpr TypedWhichId<SvxShadowItem> RES_SHADOW(RES_FRMATR_BEGIN + 25);
+inline constexpr TypedWhichId<SvxMacroItem> RES_FRMMACRO(RES_FRMATR_BEGIN + 
26);
+inline constexpr TypedWhichId<SwFormatCol> RES_COL(RES_FRMATR_BEGIN + 27);
+inline constexpr TypedWhichId<SvxFormatKeepItem> RES_KEEP(RES_FRMATR_BEGIN + 
28);
+inline constexpr TypedWhichId<SwFormatURL> RES_URL(RES_FRMATR_BEGIN + 29);
+inline constexpr TypedWhichId<SwFormatEditInReadonly> 
RES_EDIT_IN_READONLY(RES_FRMATR_BEGIN + 30);
+inline constexpr TypedWhichId<SwFormatLayoutSplit> 
RES_LAYOUT_SPLIT(RES_FRMATR_BEGIN + 31);
+inline constexpr TypedWhichId<SwFormatChain> RES_CHAIN(RES_FRMATR_BEGIN + 32);
+inline constexpr TypedWhichId<SwTextGridItem> RES_TEXTGRID(RES_FRMATR_BEGIN + 
33);
+inline constexpr TypedWhichId<SwFormatLineNumber> 
RES_LINENUMBER(RES_FRMATR_BEGIN + 34);
+inline constexpr TypedWhichId<SwFormatFootnoteAtTextEnd> 
RES_FTN_AT_TXTEND(RES_FRMATR_BEGIN + 35);
+inline constexpr TypedWhichId<SwFormatEndAtTextEnd> 
RES_END_AT_TXTEND(RES_FRMATR_BEGIN + 36);
+inline constexpr TypedWhichId<SwFormatNoBalancedColumns> 
RES_COLUMNBALANCE(RES_FRMATR_BEGIN + 37);
+inline constexpr TypedWhichId<SvxFrameDirectionItem> 
RES_FRAMEDIR(RES_FRMATR_BEGIN + 38);
+inline constexpr TypedWhichId<SwHeaderAndFooterEatSpacingItem>
+    RES_HEADER_FOOTER_EAT_SPACING(RES_FRMATR_BEGIN + 39);
+inline constexpr TypedWhichId<SwFormatRowSplit> RES_ROW_SPLIT(RES_FRMATR_BEGIN 
+ 40);
+inline constexpr TypedWhichId<SwFormatFlySplit> RES_FLY_SPLIT(RES_FRMATR_BEGIN 
+ 41);
+inline constexpr TypedWhichId<SwFormatFollowTextFlow> 
RES_FOLLOW_TEXT_FLOW(RES_FRMATR_BEGIN + 42);
+inline constexpr TypedWhichId<SfxBoolItem> 
RES_COLLAPSING_BORDERS(RES_FRMATR_BEGIN + 43);
+inline constexpr TypedWhichId<SwFormatWrapInfluenceOnObjPos>
+    RES_WRAP_INFLUENCE_ON_OBJPOS(RES_FRMATR_BEGIN + 44);
+inline constexpr TypedWhichId<SwFormatAutoFormat> 
RES_AUTO_STYLE(RES_FRMATR_BEGIN + 45);
+inline constexpr TypedWhichId<SfxStringItem> 
RES_FRMATR_STYLE_NAME(RES_FRMATR_BEGIN + 46);
+inline constexpr TypedWhichId<SfxStringItem> 
RES_FRMATR_CONDITIONAL_STYLE_NAME(RES_FRMATR_BEGIN
+                                                                               
+ 47);
+inline constexpr TypedWhichId<SfxGrabBagItem> 
RES_FRMATR_GRABBAG(RES_FRMATR_BEGIN + 48);
+inline constexpr TypedWhichId<SdrTextVertAdjustItem> 
RES_TEXT_VERT_ADJUST(RES_FRMATR_BEGIN + 49);
+inline constexpr TypedWhichId<SfxBoolItem> 
RES_BACKGROUND_FULL_SIZE(RES_FRMATR_BEGIN + 50);
+inline constexpr TypedWhichId<SfxBoolItem> RES_RTL_GUTTER(RES_FRMATR_BEGIN + 
51);
+inline constexpr TypedWhichId<SfxBoolItem> RES_DECORATIVE(RES_FRMATR_BEGIN + 
52);
+inline constexpr TypedWhichId<SwFormatWrapTextAtFlyStart>
+    RES_WRAP_TEXT_AT_FLY_START(RES_FRMATR_BEGIN + 53);
+inline constexpr sal_uInt16 RES_FRMATR_END(RES_FRMATR_BEGIN + 54);
 
 inline constexpr sal_uInt16 RES_GRFATR_BEGIN(RES_FRMATR_END);
-inline constexpr TypedWhichId<SwMirrorGrf> 
RES_GRFATR_MIRRORGRF(RES_GRFATR_BEGIN);
-inline constexpr TypedWhichId<SwCropGrf> RES_GRFATR_CROPGRF(143);
-
-inline constexpr TypedWhichId<SwRotationGrf> RES_GRFATR_ROTATION(144);
-inline constexpr TypedWhichId<SwLuminanceGrf> RES_GRFATR_LUMINANCE(145);
-inline constexpr TypedWhichId<SwContrastGrf> RES_GRFATR_CONTRAST(146);
-inline constexpr TypedWhichId<SwChannelRGrf> RES_GRFATR_CHANNELR(147);
-inline constexpr TypedWhichId<SwChannelGGrf> RES_GRFATR_CHANNELG(148);
-inline constexpr TypedWhichId<SwChannelBGrf> RES_GRFATR_CHANNELB(149);
-inline constexpr TypedWhichId<SwGammaGrf> RES_GRFATR_GAMMA(150);
-inline constexpr TypedWhichId<SwInvertGrf> RES_GRFATR_INVERT(151);
-inline constexpr TypedWhichId<SwTransparencyGrf> RES_GRFATR_TRANSPARENCY(152);
-inline constexpr TypedWhichId<SwDrawModeGrf> RES_GRFATR_DRAWMODE(153);
-
-inline constexpr TypedWhichId<SfxBoolItem> RES_GRFATR_DUMMY4(154);
-inline constexpr TypedWhichId<SfxBoolItem> RES_GRFATR_DUMMY5(155);
-inline constexpr sal_uInt16 RES_GRFATR_END(156);
+inline constexpr TypedWhichId<SwMirrorGrf> 
RES_GRFATR_MIRRORGRF(RES_GRFATR_BEGIN + 0);
+inline constexpr TypedWhichId<SwCropGrf> RES_GRFATR_CROPGRF(RES_GRFATR_BEGIN + 
1);
+
+inline constexpr TypedWhichId<SwRotationGrf> 
RES_GRFATR_ROTATION(RES_GRFATR_BEGIN + 2);
+inline constexpr TypedWhichId<SwLuminanceGrf> 
RES_GRFATR_LUMINANCE(RES_GRFATR_BEGIN + 3);
+inline constexpr TypedWhichId<SwContrastGrf> 
RES_GRFATR_CONTRAST(RES_GRFATR_BEGIN + 4);
+inline constexpr TypedWhichId<SwChannelRGrf> 
RES_GRFATR_CHANNELR(RES_GRFATR_BEGIN + 5);
+inline constexpr TypedWhichId<SwChannelGGrf> 
RES_GRFATR_CHANNELG(RES_GRFATR_BEGIN + 6);
+inline constexpr TypedWhichId<SwChannelBGrf> 
RES_GRFATR_CHANNELB(RES_GRFATR_BEGIN + 7);
+inline constexpr TypedWhichId<SwGammaGrf> RES_GRFATR_GAMMA(RES_GRFATR_BEGIN + 
8);
+inline constexpr TypedWhichId<SwInvertGrf> RES_GRFATR_INVERT(RES_GRFATR_BEGIN 
+ 9);
+inline constexpr TypedWhichId<SwTransparencyGrf> 
RES_GRFATR_TRANSPARENCY(RES_GRFATR_BEGIN + 10);
+inline constexpr TypedWhichId<SwDrawModeGrf> 
RES_GRFATR_DRAWMODE(RES_GRFATR_BEGIN + 11);
+
+inline constexpr TypedWhichId<SfxBoolItem> RES_GRFATR_DUMMY4(RES_GRFATR_BEGIN 
+ 12);
+inline constexpr TypedWhichId<SfxBoolItem> RES_GRFATR_DUMMY5(RES_GRFATR_BEGIN 
+ 13);
+inline constexpr sal_uInt16 RES_GRFATR_END(RES_GRFATR_BEGIN + 14);
 
 inline constexpr sal_uInt16 RES_BOXATR_BEGIN(RES_GRFATR_END);
-inline constexpr TypedWhichId<SwTableBoxNumFormat> 
RES_BOXATR_FORMAT(RES_BOXATR_BEGIN);
-inline constexpr TypedWhichId<SwTableBoxFormula> RES_BOXATR_FORMULA(157);
-inline constexpr TypedWhichId<SwTableBoxValue> RES_BOXATR_VALUE(158);
-inline constexpr sal_uInt16 RES_BOXATR_END(159);
+inline constexpr TypedWhichId<SwTableBoxNumFormat> 
RES_BOXATR_FORMAT(RES_BOXATR_BEGIN + 0);
+inline constexpr TypedWhichId<SwTableBoxFormula> 
RES_BOXATR_FORMULA(RES_BOXATR_BEGIN + 1);
+inline constexpr TypedWhichId<SwTableBoxValue> 
RES_BOXATR_VALUE(RES_BOXATR_BEGIN + 2);
+inline constexpr sal_uInt16 RES_BOXATR_END(RES_BOXATR_BEGIN + 3);
 
 inline constexpr sal_uInt16 RES_UNKNOWNATR_BEGIN(RES_BOXATR_END);
-inline constexpr TypedWhichId<SvXMLAttrContainerItem>
-    RES_UNKNOWNATR_CONTAINER(RES_UNKNOWNATR_BEGIN);
-inline constexpr sal_uInt16 RES_UNKNOWNATR_END(160);
+inline constexpr TypedWhichId<SvXMLAttrContainerItem> 
RES_UNKNOWNATR_CONTAINER(RES_UNKNOWNATR_BEGIN
+                                                                               
+ 0);
+inline constexpr sal_uInt16 RES_UNKNOWNATR_END(RES_UNKNOWNATR_BEGIN + 1);
 
 inline constexpr sal_uInt16 POOLATTR_END(RES_UNKNOWNATR_END);
 
 // Format IDs
 inline constexpr sal_uInt16 RES_FMT_BEGIN(RES_UNKNOWNATR_END);
-inline constexpr TypedWhichId<SwCharFormat> RES_CHRFMT(RES_FMT_BEGIN);
-inline constexpr TypedWhichId<SwFrameFormat> RES_FRMFMT(161);
-inline constexpr TypedWhichId<SwFlyFrameFormat> RES_FLYFRMFMT(162);
-inline constexpr TypedWhichId<SwTextFormatColl> RES_TXTFMTCOLL(163);
-inline constexpr TypedWhichId<SwGrfFormatColl> RES_GRFFMTCOLL(164);
-inline constexpr TypedWhichId<SwDrawFrameFormat> RES_DRAWFRMFMT(165);
-inline constexpr TypedWhichId<SwConditionTextFormatColl> 
RES_CONDTXTFMTCOLL(166);
-inline constexpr sal_uInt16 RES_FMT_END(167);
+inline constexpr TypedWhichId<SwCharFormat> RES_CHRFMT(RES_FMT_BEGIN + 0);
+inline constexpr TypedWhichId<SwFrameFormat> RES_FRMFMT(RES_FMT_BEGIN + 1);
+inline constexpr TypedWhichId<SwFlyFrameFormat> RES_FLYFRMFMT(RES_FMT_BEGIN + 
2);
+inline constexpr TypedWhichId<SwTextFormatColl> RES_TXTFMTCOLL(RES_FMT_BEGIN + 
3);
+inline constexpr TypedWhichId<SwGrfFormatColl> RES_GRFFMTCOLL(RES_FMT_BEGIN + 
4);
+inline constexpr TypedWhichId<SwDrawFrameFormat> RES_DRAWFRMFMT(RES_FMT_BEGIN 
+ 5);
+inline constexpr TypedWhichId<SwConditionTextFormatColl> 
RES_CONDTXTFMTCOLL(RES_FMT_BEGIN + 6);
+inline constexpr sal_uInt16 RES_FMT_END(RES_FMT_BEGIN + 7);
 
 // ID's for Messages in the Formats
 inline constexpr sal_uInt16 RES_FORMAT_MSG_BEGIN(RES_FMT_END);
 inline constexpr sal_uInt16 RES_UPDATEATTR_FMT_CHG(
-    167); // used by SwUpdateAttr just as an ID to communicate what has changed
+    RES_FORMAT_MSG_BEGIN + 0); // used by SwUpdateAttr just as an ID to 
communicate what has changed
 inline constexpr sal_uInt16 RES_UPDATEATTR_ATTRSET_CHG(
-    168); // used by SwUpdateAttr just as an ID to communicate what has changed
+    RES_FORMAT_MSG_BEGIN + 1); // used by SwUpdateAttr just as an ID to 
communicate what has changed
 inline constexpr sal_uInt16 RES_UPDATEATTR_OBJECTDYING(
-    169); // used by SwUpdateAttr just as an ID to communicate what has changed
+    RES_FORMAT_MSG_BEGIN + 2); // used by SwUpdateAttr just as an ID to 
communicate what has changed
 // empty
-inline constexpr sal_uInt16 RES_FORMAT_MSG_END(190);
+inline constexpr sal_uInt16 RES_FORMAT_MSG_END(RES_FORMAT_MSG_BEGIN + 3);
 
 // An ID for the RTF-reader. The stylesheets are treated like attributes,
 // i.e. there is a StyleSheet-attribute. To avoid collision with other
 // Which()-values, the value is listed here. (The help system too defines
 // new attributes!)
 inline constexpr sal_uInt16 RES_FLTRATTR_BEGIN(RES_FORMAT_MSG_END);
-inline constexpr TypedWhichId<SfxStringItem> 
RES_FLTR_BOOKMARK(RES_FLTRATTR_BEGIN);
-inline constexpr TypedWhichId<SwFltAnchor> RES_FLTR_ANCHOR(191);
-inline constexpr TypedWhichId<SfxStringItem> RES_FLTR_NUMRULE(192);
-inline constexpr TypedWhichId<SwFltTOX> RES_FLTR_TOX(193);
-inline constexpr TypedWhichId<SwFltRedline> RES_FLTR_REDLINE(194);
-inline constexpr TypedWhichId<CntUInt16Item> RES_FLTR_ANNOTATIONMARK(195);
-inline constexpr TypedWhichId<SwFltRDFMark> RES_FLTR_RDFMARK(196);
-inline constexpr sal_uInt16 RES_FLTRATTR_END(197);
+inline constexpr TypedWhichId<SfxStringItem> 
RES_FLTR_BOOKMARK(RES_FLTRATTR_BEGIN + 0);
+inline constexpr TypedWhichId<SwFltAnchor> RES_FLTR_ANCHOR(RES_FLTRATTR_BEGIN 
+ 1);
+inline constexpr TypedWhichId<SfxStringItem> 
RES_FLTR_NUMRULE(RES_FLTRATTR_BEGIN + 2);
+inline constexpr TypedWhichId<SwFltTOX> RES_FLTR_TOX(RES_FLTRATTR_BEGIN + 3);
+inline constexpr TypedWhichId<SwFltRedline> 
RES_FLTR_REDLINE(RES_FLTRATTR_BEGIN + 4);
+inline constexpr TypedWhichId<CntUInt16Item> 
RES_FLTR_ANNOTATIONMARK(RES_FLTRATTR_BEGIN + 5);
+inline constexpr TypedWhichId<SwFltRDFMark> 
RES_FLTR_RDFMARK(RES_FLTRATTR_BEGIN + 6);
+inline constexpr sal_uInt16 RES_FLTRATTR_END(RES_FLTRATTR_BEGIN + 7);
 
 inline constexpr sal_uInt16 RES_TBX_DUMMY(RES_FLTRATTR_END + 1);
 
diff --git a/sw/inc/inspectorproperties.hrc b/sw/inc/inspectorproperties.hrc
index b218cb946ca1..225fe28bd1c3 100644
--- a/sw/inc/inspectorproperties.hrc
+++ b/sw/inc/inspectorproperties.hrc
@@ -109,6 +109,7 @@
 #define RID_CHAR_ROTATION                                   
NC_("RID_ATTRIBUTE_NAMES_MAP", "Char Rotation")
 #define RID_CHAR_ROTATION_IS_FIT_TO_LINE                    
NC_("RID_ATTRIBUTE_NAMES_MAP", "Char Rotation is Fit To Line")
 #define RID_CHAR_SCALE_WIDTH                                
NC_("RID_ATTRIBUTE_NAMES_MAP", "Char Scale Width")
+#define RID_CHAR_SCRIPT_HINT                                
NC_("RID_ATTRIBUTE_NAMES_MAP", "Char Script Type Hint")
 #define RID_CHAR_SHADING_VALUE                              
NC_("RID_ATTRIBUTE_NAMES_MAP", "Char Shading Value")
 #define RID_CHAR_SHADOW_FORMAT                              
NC_("RID_ATTRIBUTE_NAMES_MAP", "Char Shadow Format")
 #define RID_CHAR_SHADOWED                                   
NC_("RID_ATTRIBUTE_NAMES_MAP", "Char Shadowed")
diff --git a/sw/inc/swatrset.hxx b/sw/inc/swatrset.hxx
index 96bae5e9645c..8475e5dd95ab 100644
--- a/sw/inc/swatrset.hxx
+++ b/sw/inc/swatrset.hxx
@@ -50,6 +50,7 @@ class SvxCharScaleWidthItem;
 class SvxCharRotateItem;
 class SvxCharReliefItem;
 class SvxCharHiddenItem;
+class SvxScriptHintItem;
 
 // Frame attributes
 class SwFormatFillOrder;
@@ -241,6 +242,7 @@ public:
     inline const SvxCharRotateItem        &GetCharRotate( bool = true ) const;
     inline const SvxCharReliefItem        &GetCharRelief( bool = true ) const;
     inline const SvxCharHiddenItem      &GetCharHidden( bool = true ) const;
+    inline const SvxScriptHintItem& GetCharScriptTypeHint(bool = true) const;
 
     // Frame attributes. Implementation in frmatr.hxx.
     inline const SwFormatFillOrder       &GetFillOrder( bool = true ) const;
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 192120f4eefa..d343006249db 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -136,6 +136,7 @@ inline constexpr OUString 
UNO_NAME_CHAR_UNDERLINE_COMPLEX_COLOR = u"CharUnderlin
 inline constexpr OUString UNO_NAME_CHAR_UNDERLINE_HAS_COLOR = 
u"CharUnderlineHasColor"_ustr;
 inline constexpr OUString UNO_NAME_CHAR_ESCAPEMENT = u"CharEscapement"_ustr;
 inline constexpr OUString UNO_NAME_CHAR_CASE_MAP = u"CharCaseMap"_ustr;
+inline constexpr OUString UNO_NAME_CHAR_SCRIPT_HINT = u"CharScriptHint"_ustr;
 inline constexpr OUString UNO_NAME_CHAR_STRIKEOUT = u"CharStrikeout"_ustr;
 inline constexpr OUString UNO_NAME_CHAR_CROSSED_OUT = u"CharCrossedOut"_ustr;
 inline constexpr OUString UNO_NAME_CHAR_NO_HYPHENATION = 
u"CharNoHyphenation"_ustr;
diff --git a/sw/qa/extras/odfexport/data/tdf166011.fodt 
b/sw/qa/extras/odfexport/data/tdf166011.fodt
new file mode 100644
index 000000000000..048ec5d83c38
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/tdf166011.fodt
@@ -0,0 +1,118 @@
+<?xml version='1.0' encoding='UTF-8'?>
-e 
... etc. - the rest is truncated

Reply via email to