tdf#132970 SMP bullets mangled

working:
a) bullet preview
b) writer rendering
c) save to odt
a) load from odt

Change-Id: I2f85576389fe4f0437f81799c14dfd98c8c40b2e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103129
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/cui/source/dialogs/cuicharmap.cxx b/cui/source/dialogs/cuicharmap.cxx
index 13d3c8e..5042a20 100644
--- a/cui/source/dialogs/cuicharmap.cxx
+++ b/cui/source/dialogs/cuicharmap.cxx
@@ -209,7 +209,8 @@ void SvxCharacterMap::SetChar( sal_UCS4 c )

sal_UCS4 SvxCharacterMap::GetChar() const
{
   return m_aShowChar.GetText().toChar();
    sal_Int32 nIndexUtf16 = 0;
    return m_aShowChar.GetText().iterateCodePoints(&nIndexUtf16);
}

void SvxCharacterMap::DisableFontSelection()
diff --git a/cui/source/tabpages/numpages.cxx b/cui/source/tabpages/numpages.cxx
index 6086cb0..1410216 100644
--- a/cui/source/tabpages/numpages.cxx
+++ b/cui/source/tabpages/numpages.cxx
@@ -1928,7 +1928,7 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
    sal_uInt16 nMask = 1;
    const vcl::Font* pFmtFont = nullptr;
    bool bSameBullet = true;
    sal_Unicode cBullet = 0;
    sal_UCS4 cBullet = 0;
    bool bFirst = true;
    for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
    {
@@ -1971,7 +1971,7 @@ IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
        {
            SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
            aNumFmt.SetBulletFont(&aActBulletFont);
            aNumFmt.SetBulletChar( static_cast<sal_Unicode>(aMap.GetChar()) );
            aNumFmt.SetBulletChar(aMap.GetChar());
            pActNum->SetLevel(i, aNumFmt);
        }
        _nMask <<= 1;
@@ -2164,7 +2164,8 @@ static long lcl_DrawBullet(VirtualDevice* pVDev,
        aBulletColor.Invert();
    aFont.SetColor(aBulletColor);
    pVDev->SetFont( aFont );
    OUString aText(rFmt.GetBulletChar());
    sal_UCS4 cChar = rFmt.GetBulletChar();
    OUString aText(&cChar, 1);
    long nY = nYStart;
    nY -= ((aTmpSize.Height() - rSize.Height())/ 2);
    pVDev->DrawText( Point(nXStart, nY), aText );
diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx
index 27d8660..ca97d10 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -1839,7 +1839,8 @@ void Outliner::ImplCalcBulletText( sal_Int32 nPara, bool bRecalcLevel, bool bRec
            aBulletText += pFmt->GetPrefix();
            if( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
            {
                aBulletText += OUStringChar(pFmt->GetBulletChar());
                sal_UCS4 cChar = pFmt->GetBulletChar();
                aBulletText += OUString(&cChar, 1);
            }
            else if( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE )
            {
diff --git a/include/editeng/numitem.hxx b/include/editeng/numitem.hxx
index 38dbfe9..46b34bd 100644
--- a/include/editeng/numitem.hxx
+++ b/include/editeng/numitem.hxx
@@ -30,6 +30,7 @@
#include <unotools/fontcvt.hxx>
#include <editeng/editengdllapi.h>
#include <o3tl/typed_flags_set.hxx>
#include <vcl/vclenum.hxx>
#include <memory>
#include <optional>
#include <algorithm>
@@ -113,7 +114,7 @@ private:
    sal_uInt8           nInclUpperLevels;   // Take over numbers from the previous level.
    sal_uInt16          nStart;             // Start of counting

    sal_Unicode         cBullet;            // Symbol
    sal_UCS4            cBullet;            // Symbol
    sal_uInt16          nBulletRelSize;     // percentage size of bullets
    Color               nBulletColor;       // Bullet color

@@ -180,8 +181,8 @@ public:

    void            SetBulletFont(const vcl::Font* pFont);
    const vcl::Font* GetBulletFont() const {return pBulletFont.get();}
    void            SetBulletChar(sal_Unicode cSet){cBullet = cSet;}
    sal_Unicode     GetBulletChar()const {return cBullet;}
    void            SetBulletChar(sal_UCS4 cSet){cBullet = cSet;}
    sal_UCS4        GetBulletChar()const {return cBullet;}
    void            SetBulletRelSize(sal_uInt16 nSet) {nBulletRelSize = std::max(nSet,sal_uInt16(SVX_NUM_REL_SIZE_MIN));}
    sal_uInt16      GetBulletRelSize() const { return nBulletRelSize;}
    void            SetBulletColor(Color nSet){nBulletColor = nSet;}
diff --git a/sd/source/ui/dlg/BulletAndPositionDlg.cxx b/sd/source/ui/dlg/BulletAndPositionDlg.cxx
index cfc7db7..4fa1414 100644
--- a/sd/source/ui/dlg/BulletAndPositionDlg.cxx
+++ b/sd/source/ui/dlg/BulletAndPositionDlg.cxx
@@ -962,7 +962,7 @@ IMPL_LINK_NOARG(SvxBulletAndPositionDlg, BulletHdl_Impl, weld::Button&, void)
        {
            SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
            aNumFmt.SetBulletFont(&aActBulletFont);
            aNumFmt.SetBulletChar(static_cast<sal_Unicode>(aMap.GetChar()));
            aNumFmt.SetBulletChar(aMap.GetChar());
            pActNum->SetLevel(i, aNumFmt);
        }
        _nMask <<= 1;
diff --git a/sw/source/core/edit/edattr.cxx b/sw/source/core/edit/edattr.cxx
index fb982cd..f5c332a 100644
--- a/sw/source/core/edit/edattr.cxx
+++ b/sw/source/core/edit/edattr.cxx
@@ -617,7 +617,10 @@ static bool lcl_IsNoEndTextAttrAtPos(SwRootFrame const& rLayout,
                if( SVX_NUM_BITMAP != rNumFormat.GetNumberingType() )
                {
                    if ( SVX_NUM_CHAR_SPECIAL == rNumFormat.GetNumberingType() )
                        sExp = OUString(rNumFormat.GetBulletChar());
                    {
                        sal_UCS4 cBullet = rNumFormat.GetBulletChar();
                        sExp = OUString(&cBullet, 1);
                    }
                    else
                        sExp = pPropsNode->GetNumString(true, MAXLEVEL, &rLayout);
                }
diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
index d411c9e..6b9e164 100644
--- a/sw/source/core/text/porfld.cxx
+++ b/sw/source/core/text/porfld.cxx
@@ -734,14 +734,14 @@ void SwNumberPortion::Paint( const SwTextPaintInfo &rInf ) const
    }
}

SwBulletPortion::SwBulletPortion( const sal_Unicode cBullet,
SwBulletPortion::SwBulletPortion( const sal_UCS4 cBullet,
                                  const OUString& rBulletFollowedBy,
                                  std::unique_ptr<SwFont> pFont,
                                  const bool bLft,
                                  const bool bCntr,
                                  const sal_uInt16 nMinDst,
                                  const bool bLabelAlignmentPosAndSpaceModeActive )
    : SwNumberPortion( OUStringChar(cBullet) + rBulletFollowedBy,
    : SwNumberPortion( OUString(&cBullet, 1) + rBulletFollowedBy,
                       std::move(pFont), bLft, bCntr, nMinDst,
                       bLabelAlignmentPosAndSpaceModeActive )
{
diff --git a/sw/source/core/text/porfld.hxx b/sw/source/core/text/porfld.hxx
index ec70c66..cac7cbc 100644
--- a/sw/source/core/text/porfld.hxx
+++ b/sw/source/core/text/porfld.hxx
@@ -143,7 +143,7 @@ public:
class SwBulletPortion : public SwNumberPortion
{
public:
    SwBulletPortion( const sal_Unicode cCh,
    SwBulletPortion( const sal_UCS4 cCh,
                     const OUString& rBulletFollowedBy,
                     std::unique_ptr<SwFont> pFnt,
                     const bool bLeft,
diff --git a/sw/source/core/unocore/unosett.cxx b/sw/source/core/unocore/unosett.cxx
index 9664ff2..2690525 100644
--- a/sw/source/core/unocore/unosett.cxx
+++ b/sw/source/core/unocore/unosett.cxx
@@ -1411,14 +1411,16 @@ uno::Sequence<beans::PropertyValue> SwXNumberingRules::GetPropertiesForNumFormat
    {
        if(SVX_NUM_CHAR_SPECIAL == rFormat.GetNumberingType())
        {
            sal_UCS4 cBullet = rFormat.GetBulletChar();

            //BulletId
            nINT16 = rFormat.GetBulletChar();
            nINT16 = cBullet;
            aPropertyValues.push_back(comphelper::makePropertyValue("BulletId", nINT16));

            const vcl::Font* pFont = rFormat.GetBulletFont();

            //BulletChar
            aUString = OUString(rFormat.GetBulletChar());
            aUString = OUString(&cBullet, 1);
            aPropertyValues.push_back(comphelper::makePropertyValue("BulletChar", aUString));

            //BulletFontName
@@ -1790,18 +1792,19 @@ void SwXNumberingRules::SetPropertiesToNumFormat(
        {
            OUString aChar;
            rProp.Value >>= aChar;
            if(aChar.getLength() == 1)
            {
                aFormat.SetBulletChar(aChar.toChar());
            }
            else if(aChar.isEmpty())
            if (aChar.isEmpty())
            {
                // If w:lvlText's value is null - set bullet char to zero
                aFormat.SetBulletChar(u'\0');
            }
            else
            {
                bWrongArg = true;
                sal_Int32 nIndexUtf16 = 0;
                sal_UCS4 cBullet = aChar.iterateCodePoints(&nIndexUtf16);
                if (aChar.getLength() == nIndexUtf16)
                    aFormat.SetBulletChar(cBullet);
                else
                    bWrongArg = true;
            }
        }
        else if (rProp.Name == UNO_NAME_GRAPHIC)
diff --git a/sw/source/filter/html/htmlnumreader.cxx b/sw/source/filter/html/htmlnumreader.cxx
index 196057c..e3dab31 100644
--- a/sw/source/filter/html/htmlnumreader.cxx
+++ b/sw/source/filter/html/htmlnumreader.cxx
@@ -41,7 +41,7 @@
using namespace css;

// <UL TYPE=...>
HTMLOptionEnum<sal_Unicode> const aHTMLULTypeTable[] =
HTMLOptionEnum<sal_UCS4> const aHTMLULTypeTable[] =
{
    { OOO_STRING_SVTOOLS_HTML_ULTYPE_disc,    HTML_BULLETCHAR_DISC   },
    { OOO_STRING_SVTOOLS_HTML_ULTYPE_circle,  HTML_BULLETCHAR_CIRCLE },
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index ac952d8..9f6068b 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -3038,7 +3038,10 @@ void RtfAttributeOutput::ParaNumRule_Impl(const SwTextNode* pTextNd, sal_Int32 n
        OUString sText;
        if (SVX_NUM_CHAR_SPECIAL == pFormat->GetNumberingType()
            || SVX_NUM_BITMAP == pFormat->GetNumberingType())
            sText = OUString(pFormat->GetBulletChar());
        {
            sal_UCS4 cBullet = pFormat->GetBulletChar();
            sText = OUString(&cBullet, 1);
        }
        else
            sText = pTextNd->GetNumString();

diff --git a/sw/source/filter/ww8/wrtw8num.cxx b/sw/source/filter/ww8/wrtw8num.cxx
index a7f4276..3c13377 100644
--- a/sw/source/filter/ww8/wrtw8num.cxx
+++ b/sw/source/filter/ww8/wrtw8num.cxx
@@ -484,7 +484,8 @@ void MSWordExportBase::NumberingLevel(
        SVX_NUM_BITMAP == rFormat.GetNumberingType())
    {
        // Use bullet
        sNumStr = OUString(rFormat.GetBulletChar());
        sal_UCS4 cBullet = rFormat.GetBulletChar();
        sNumStr = OUString(&cBullet, 1);
    }
    else
    {
diff --git a/sw/source/ui/misc/outline.cxx b/sw/source/ui/misc/outline.cxx
index d957313..099b901 100644
--- a/sw/source/ui/misc/outline.cxx
+++ b/sw/source/ui/misc/outline.cxx
@@ -840,7 +840,8 @@ static long lcl_DrawBullet(vcl::RenderContext* pVDev, const SwNumFormat& rFormat
        aBulletColor.Invert();
    aFont.SetColor(aBulletColor);
    pVDev->SetFont( aFont );
    OUString aText(rFormat.GetBulletChar());
    sal_UCS4 cBullet = rFormat.GetBulletChar();
    OUString aText(&cBullet, 1);
    long nY = nYStart;
    nY -= ((aTmpSize.Height() - rSize.Height())/ 2);
    pVDev->DrawText( Point(nXStart, nY), aText );
diff --git a/xmloff/source/style/xmlnume.cxx b/xmloff/source/style/xmlnume.cxx
index 3eca9cd..9dd1571 100644
--- a/xmloff/source/style/xmlnume.cxx
+++ b/xmloff/source/style/xmlnume.cxx
@@ -50,7 +50,7 @@
#include <xmloff/xmlnume.hxx>
#include <xmloff/xmlexp.hxx>
#include <tools/fontenum.hxx>

#include <vcl/vclenum.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
@@ -90,7 +90,7 @@ void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel,

    sal_Int16 nStartValue = 1, nDisplayLevels = 1, nBullRelSize = 0;

    sal_Unicode cBullet = 0xf095;
    sal_UCS4 cBullet = 0xf095;
    OUString sBulletFontName, sBulletFontStyleName ;
    FontFamily eBulletFontFamily = FAMILY_DONTKNOW;
    FontPitch eBulletFontPitch = PITCH_DONTKNOW;
@@ -127,7 +127,8 @@ void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel,
            rProp.Value >>= sValue;
            if( !sValue.isEmpty() )
            {
                cBullet = sValue[0];
                sal_Int32 nIndexUtf16 = 0;
                cBullet = sValue.iterateCodePoints(&nIndexUtf16);
            }
        }
        else if( rProp.Name == "BulletRelSize" )
@@ -278,7 +279,7 @@ void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel,
                cBullet = 0xF000 + 149;
            }
            // text:bullet-char="..."
            sTmp.append( cBullet );
            sTmp.append(OUString(&cBullet, 1));
            GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_BULLET_CHAR,
                          sTmp.makeStringAndClear() );
        }
diff --git a/xmloff/source/style/xmlnumi.cxx b/xmloff/source/style/xmlnumi.cxx
index 9fdba38..bed36cb 100644
--- a/xmloff/source/style/xmlnumi.cxx
+++ b/xmloff/source/style/xmlnumi.cxx
@@ -45,6 +45,8 @@

#include <sax/tools/converter.hxx>

#include <vcl/vclenum.hxx>

#include <xmloff/xmltkmap.hxx>
#include <xmloff/namespacemap.hxx>
#include <xmloff/xmlnamespace.hxx>
@@ -152,7 +154,7 @@ class SvxXMLListLevelStyleContext_Impl : public SvXMLImportContext
    rtl_TextEncoding    eBulletFontEncoding;
    sal_Int16           eImageVertOrient;

    sal_Unicode         cBullet;
    sal_UCS4            cBullet;

    sal_Int16           nRelSize;
    Color               m_nColor;
@@ -292,7 +294,10 @@ SvxXMLListLevelStyleContext_Impl::SvxXMLListLevelStyleContext_Impl(
            break;
        case XML_ELEMENT(TEXT, XML_BULLET_CHAR):
            if (!sValue.isEmpty())
                cBullet = sValue[0];
            {
                sal_Int32 nIndexUtf16 = 0;
                cBullet = sValue.iterateCodePoints(&nIndexUtf16);
            }
            break;
        case XML_ELEMENT(XLINK, XML_HREF):
            if( bImage )
@@ -490,7 +495,7 @@ Sequence<beans::PropertyValue> SvxXMLListLevelStyleContext_Impl::GetProperties()
            // Must append 'cBullet' even if it is zero
            // if 'bBullet' is true and 'cBullet' is zero - BulletChar property must be 0.
            pProps[nPos].Name = "BulletChar";
            pProps[nPos++].Value <<= OUString( cBullet );
            pProps[nPos++].Value <<= OUString(&cBullet, 1);

            pProps[nPos].Name = "BulletFont";
            pProps[nPos++].Value <<= aFDesc;