tdf#159254 import paper bin/paper source from rtf/docx files

Imports \binfsxn and \binsxn from RTF and
w:paperSrc from docx files and applies paper tray to the page style
if the printer supports the imported tray value.
Works only on Windows.

Change-Id: Ie1170c58f7114f0dbf6bdd2721d4e077886cbe16
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162236
Tested-by: Jenkins
Tested-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de>
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
diff --git a/include/vcl/print.hxx b/include/vcl/print.hxx
index d6ce772..e23cf8d 100644
--- a/include/vcl/print.hxx
+++ b/include/vcl/print.hxx
@@ -227,6 +227,7 @@ public:

    bool                        SetPaperBin( sal_uInt16 nPaperBin );
    sal_uInt16                  GetPaperBin() const;
    sal_uInt16                  GetPaperBinBySourceIndex(sal_uInt16 nPaperSource) const;
    void                        SetPaper( Paper ePaper );
    bool                        SetPaperSizeUser( const Size& rSize );
    /** @return The paper format of the printer's current "jobsetup". Note that if PAPER_USER the actual size can be anything. */
diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx
index 396e8e3..a6a2cf3 100644
--- a/sw/inc/unoprnms.hxx
+++ b/sw/inc/unoprnms.hxx
@@ -205,6 +205,7 @@ inline constexpr OUString UNO_NAME_POSITION_PROTECTED = u"PositionProtected"_ust
inline constexpr OUString UNO_NAME_ALTERNATIVE_TEXT = u"AlternativeText"_ustr;
inline constexpr OUString UNO_NAME_PRIMARY_KEY = u"PrimaryKey"_ustr;
inline constexpr OUString UNO_NAME_PRINTER_PAPER_TRAY = u"PrinterPaperTray"_ustr;
inline constexpr OUString UNO_NAME_PRINTER_PAPER_TRAY_INDEX = u"PrinterPaperTrayIndex"_ustr;
inline constexpr OUString UNO_NAME_RELATIVE_WIDTH = u"RelativeWidth"_ustr;
inline constexpr OUString UNO_NAME_RELATIVE_WIDTH_RELATION = u"RelativeWidthRelation"_ustr;
inline constexpr OUString UNO_NAME_RELATIVE_HEIGHT = u"RelativeHeight"_ustr;
diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx
index ee4422a..12db464 100644
--- a/sw/source/core/unocore/unomap1.cxx
+++ b/sw/source/core/unocore/unomap1.cxx
@@ -537,6 +537,7 @@ std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetPageStyleP
        { UNO_NAME_NUMBERING_TYPE, SID_ATTR_PAGE,             cppu::UnoType<sal_Int16>::get(),           PROPERTY_NONE , MID_PAGE_NUMTYPE       },
        { UNO_NAME_PAGE_STYLE_LAYOUT, SID_ATTR_PAGE,          cppu::UnoType<css::style::PageStyleLayout>::get(),    PROPERTY_NONE ,MID_PAGE_LAYOUT     },
        { UNO_NAME_PRINTER_PAPER_TRAY, RES_PAPER_BIN,             cppu::UnoType<OUString>::get(),            PROPERTY_NONE , 0 },
        { UNO_NAME_PRINTER_PAPER_TRAY_INDEX, RES_PAPER_BIN,       cppu::UnoType<sal_Int32>::get(),            PROPERTY_NONE , 0 },
//                  { UNO_NAME_REGISTER_MODE_ACTIVE, SID_SWREGISTER_MODE,     cppu::UnoType<bool>::get(),             PROPERTY_NONE , 0 },
        { UNO_NAME_REGISTER_PARAGRAPH_STYLE, SID_SWREGISTER_COLLECTION,   cppu::UnoType<OUString>::get(),        PROPERTY_NONE , 0 },
        { UNO_NAME_SIZE, SID_ATTR_PAGE_SIZE,  cppu::UnoType<css::awt::Size>::get(),             PROPERTY_NONE,   MID_SIZE_SIZE|CONVERT_TWIPS},
diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx
index c4fa8a3..a68424c 100644
--- a/sw/source/core/unocore/unostyle.cxx
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -1669,27 +1669,37 @@ void SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE>(const SfxItemPropertyMapE
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
    if(!rValue.has<OUString>())
    if (!rValue.has<OUString>() && !rValue.has<sal_Int32>())
        throw lang::IllegalArgumentException();
    SfxPrinter* pPrinter = m_pDoc->getIDocumentDeviceAccess().getPrinter(true);
    OUString sValue(rValue.get<OUString>());
    using printeridx_t = decltype(pPrinter->GetPaperBinCount());
    printeridx_t nBin = std::numeric_limits<printeridx_t>::max();
    if(sValue == "[From printer settings]")
        nBin = std::numeric_limits<printeridx_t>::max()-1;
    else if(pPrinter)
    if(rValue.has<OUString>())
    {
        for(sal_uInt16 i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i)
        OUString sValue(rValue.get<OUString>());
        if(sValue == "[From printer settings]")
            nBin = std::numeric_limits<printeridx_t>::max()-1;
        else if(pPrinter)
        {
            if (sValue == pPrinter->GetPaperBinName(i))
            for(printeridx_t i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i)
            {
                nBin = i;
                break;
                if (sValue == pPrinter->GetPaperBinName(i))
                {
                    nBin = i;
                    break;
                }
            }
        }
    }
    else if (rValue.has<sal_Int32>() && pPrinter)
    {
        sal_Int32 nValue (rValue.get<sal_Int32>());
        nBin = pPrinter->GetPaperBinBySourceIndex(nValue);
    }

    if(nBin == std::numeric_limits<printeridx_t>::max())
        throw lang::IllegalArgumentException();

    SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
    SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID);
    aSet.SetParent(&rStyleSet);
diff --git a/vcl/inc/osx/salprn.h b/vcl/inc/osx/salprn.h
index 7bfd417..9c26e17 100644
--- a/vcl/inc/osx/salprn.h
+++ b/vcl/inc/osx/salprn.h
@@ -82,6 +82,8 @@ class AquaSalInfoPrinter : public SalInfoPrinter
    virtual sal_uInt32          GetCapabilities( const ImplJobSetup* i_pSetupData, PrinterCapType i_nType ) override;
    virtual sal_uInt16          GetPaperBinCount( const ImplJobSetup* i_pSetupData ) override;
    virtual OUString            GetPaperBinName( const ImplJobSetup* i_pSetupData, sal_uInt16 i_nPaperBin ) override;
    virtual sal_uInt16          GetPaperBinBySourceIndex(const ImplJobSetup* pSetupData,
                                                             sal_uInt16 nPaperSource) override;
    virtual void                InitPaperFormats( const ImplJobSetup* i_pSetupData ) override;
    virtual int                 GetLandscapeAngle( const ImplJobSetup* i_pSetupData ) override;

diff --git a/vcl/inc/salprn.hxx b/vcl/inc/salprn.hxx
index 97a0fe1..ae0b313 100644
--- a/vcl/inc/salprn.hxx
+++ b/vcl/inc/salprn.hxx
@@ -82,6 +82,9 @@ public:
    virtual sal_uInt32              GetCapabilities( const ImplJobSetup* pSetupData, PrinterCapType nType ) = 0;
    virtual sal_uInt16              GetPaperBinCount( const ImplJobSetup* pSetupData ) = 0;
    virtual OUString                GetPaperBinName( const ImplJobSetup* pSetupData, sal_uInt16 nPaperBin ) = 0;
    virtual sal_uInt16              GetPaperBinBySourceIndex(const ImplJobSetup* pSetupData,
                                                             sal_uInt16 nPaperSource) = 0;

    // fills m_aPaperFormats and sets m_bPapersInit to true
    virtual void                    InitPaperFormats( const ImplJobSetup* pSetupData ) = 0;
    // returns angle that a landscape page will be turned counterclockwise wrt to portrait
diff --git a/vcl/inc/unx/genprn.h b/vcl/inc/unx/genprn.h
index d030c46..abe84b7 100644
--- a/vcl/inc/unx/genprn.h
+++ b/vcl/inc/unx/genprn.h
@@ -45,6 +45,8 @@ public:
    virtual sal_uInt32              GetCapabilities( const ImplJobSetup* pSetupData, PrinterCapType nType ) override;
    virtual sal_uInt16              GetPaperBinCount( const ImplJobSetup* pSetupData ) override;
    virtual OUString                GetPaperBinName( const ImplJobSetup* pSetupData, sal_uInt16 nPaperBin ) override;
    virtual sal_uInt16              GetPaperBinBySourceIndex(const ImplJobSetup* pSetupData,
                                                             sal_uInt16 nPaperSource) override;
    virtual void                    InitPaperFormats( const ImplJobSetup* pSetupData ) override;
    virtual int                     GetLandscapeAngle( const ImplJobSetup* pSetupData ) override;
};
diff --git a/vcl/inc/win/salprn.h b/vcl/inc/win/salprn.h
index e1bbb66..b0ec169 100644
--- a/vcl/inc/win/salprn.h
+++ b/vcl/inc/win/salprn.h
@@ -69,6 +69,9 @@ public:
    virtual sal_uInt32              GetCapabilities( const ImplJobSetup* pSetupData, PrinterCapType nType ) override;
    virtual sal_uInt16              GetPaperBinCount( const ImplJobSetup* pSetupData ) override;
    virtual OUString                GetPaperBinName( const ImplJobSetup* pSetupData, sal_uInt16 nPaperBin ) override;
    virtual sal_uInt16              GetPaperBinBySourceIndex(const ImplJobSetup* pSetupData,
                                                             sal_uInt16 nPaperSource) override;

    virtual void                    InitPaperFormats( const ImplJobSetup* pSetupData ) override;
    virtual int                     GetLandscapeAngle( const ImplJobSetup* pSetupData ) override;
};
diff --git a/vcl/osx/salprn.cxx b/vcl/osx/salprn.cxx
index 9f9c8c0..3de45d9 100644
--- a/vcl/osx/salprn.cxx
+++ b/vcl/osx/salprn.cxx
@@ -265,6 +265,11 @@ OUString AquaSalInfoPrinter::GetPaperBinName( const ImplJobSetup*, sal_uInt16 )
    return OUString();
}

sal_uInt16 AquaSalInfoPrinter::GetPaperBinBySourceIndex( const ImplJobSetup*, sal_uInt16 )
{
    return 0xffff;
}

sal_uInt32 AquaSalInfoPrinter::GetCapabilities( const ImplJobSetup*, PrinterCapType i_nType )
{
    switch( i_nType )
diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx
index eff94a9..401d381 100644
--- a/vcl/source/gdi/print.cxx
+++ b/vcl/source/gdi/print.cxx
@@ -1479,6 +1479,14 @@ OUString Printer::GetPaperBinName( sal_uInt16 nPaperBin ) const
        return OUString();
}

sal_uInt16 Printer::GetPaperBinBySourceIndex(sal_uInt16 nPaperSource) const
{
    if ( IsDisplayPrinter() )
        return 0;

    return mpInfoPrinter->GetPaperBinBySourceIndex( &maJobSetup.ImplGetConstData(), nPaperSource );
}

void Printer::SetCopyCount( sal_uInt16 nCopy, bool bCollate )
{
    mnCopyCount = nCopy;
diff --git a/vcl/unx/generic/print/genprnpsp.cxx b/vcl/unx/generic/print/genprnpsp.cxx
index 33990de..ce5a456 100644
--- a/vcl/unx/generic/print/genprnpsp.cxx
+++ b/vcl/unx/generic/print/genprnpsp.cxx
@@ -638,6 +638,11 @@ OUString PspSalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, sal_
    return OUString();
}

sal_uInt16 PspSalInfoPrinter::GetPaperBinBySourceIndex( const ImplJobSetup*, sal_uInt16 )
{
    return 0xffff;
}

sal_uInt32 PspSalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, PrinterCapType nType )
{
    switch( nType )
diff --git a/vcl/win/gdi/salprn.cxx b/vcl/win/gdi/salprn.cxx
index 3302efa..065b060 100644
--- a/vcl/win/gdi/salprn.cxx
+++ b/vcl/win/gdi/salprn.cxx
@@ -1196,6 +1196,25 @@ OUString WinSalInfoPrinter::GetPaperBinName( const ImplJobSetup* pSetupData, sal
    return aPaperBinName;
}

sal_uInt16 WinSalInfoPrinter::GetPaperBinBySourceIndex( const ImplJobSetup* pSetupData, sal_uInt16 nPaperSource )
{
    DWORD nBins = ImplDeviceCaps( this, DC_BINNAMES, nullptr, pSetupData );
    if (nBins != GDI_ERROR)
    {
        auto pBuffer = std::make_unique<sal_uInt16[]>(nBins);
        DWORD nBins = ImplDeviceCaps( this, DC_BINS, reinterpret_cast<BYTE*>(pBuffer.get()), pSetupData );
        if (nBins != GDI_ERROR)
        {
            for (DWORD nBin = 0; nBin < nBins; ++nBin)
            {
                if (nPaperSource == *(pBuffer.get() + nBin))
                    return nBin;
            }
        }
    }
    return 0xffff;
}

sal_uInt32 WinSalInfoPrinter::GetCapabilities( const ImplJobSetup* pSetupData, PrinterCapType nType )
{
    DWORD nRet;
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index d6717cc..30c2203 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -703,6 +703,12 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
        case NS_ooxml::LN_CT_PageMar_gutter:
            m_pImpl->SetPageMarginTwip( PAGE_MAR_GUTTER, nIntValue );
        break;
        case NS_ooxml::LN_CT_PaperSource_first:
            m_pImpl->SetPaperSource(PAPER_SOURCE_FIRST, nIntValue);
        break;
        case NS_ooxml::LN_CT_PaperSource_other:
            m_pImpl->SetPaperSource(PAPER_SOURCE_OTHER, nIntValue);
        break;
        case NS_ooxml::LN_CT_Language_val: //90314
        case NS_ooxml::LN_CT_Language_eastAsia: //90315
        case NS_ooxml::LN_CT_Language_bidi: //90316
@@ -2493,7 +2499,16 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
            pSectionContext->SetGutterMargin(rPageMar.gutter);
        }
        break;

    case NS_ooxml::LN_EG_SectPrContents_paperSrc:
        m_pImpl->InitPaperSource();
        resolveSprmProps(*this, rSprm);
        OSL_ENSURE(pSectionContext, "SectionContext unavailable!");
        if(pSectionContext)
        {
            const PaperSource& rPaperSource = m_pImpl->GetPaperSource();
            pSectionContext->SetPaperSource( rPaperSource.first, rPaperSource.other );
        }
    break;
    case NS_ooxml::LN_EG_SectPrContents_cols:
    {
        writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 96043cb..8606506 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -9329,6 +9329,14 @@ void DomainMapper_Impl::SetPageMarginTwip( PageMarElement eElement, sal_Int32 nV
    }
}

void DomainMapper_Impl::SetPaperSource(PaperSourceElement eElement, sal_Int32 nValue)
{
    if(eElement == PAPER_SOURCE_FIRST)
        m_aPaperSource.first = nValue;
    else
        m_aPaperSource.other = nValue;
}


PageMar::PageMar()
    : top(ConversionHelper::convertTwipToMM100( sal_Int32(1440)))
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index dc8dbce..18bec93 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -103,6 +103,23 @@ enum PageMarElement
    PAGE_MAR_GUTTER
};

struct PaperSource
{
    sal_Int32 first;
    sal_Int32 other;
    public:
        PaperSource() :
            first(0),
            other(0)
            {}
};

enum PaperSourceElement
{
    PAPER_SOURCE_FIRST,
    PAPER_SOURCE_OTHER,
};

/// property stack element
enum ContextType
{
@@ -504,6 +521,7 @@ private:
    OUString                                                                        m_sCurrentPermEdGrp;

    PageMar                                                                        m_aPageMargins;
    PaperSource                                                                     m_aPaperSource;
    SymbolData                                                                      m_aSymbolData;

    // TableManagers are stacked: one for each stream to avoid any confusion
@@ -1014,6 +1032,10 @@ public:
    void SetPageMarginTwip( PageMarElement eElement, sal_Int32 nValue );
    const PageMar& GetPageMargins() const {return m_aPageMargins;}

    void InitPaperSource() { m_aPaperSource = PaperSource(); }
    void SetPaperSource( PaperSourceElement eElement, sal_Int32 nValue );
    const PaperSource& GetPaperSource() {return m_aPaperSource;}

    const LineNumberSettings& GetLineNumberSettings() const { return m_aLineNumberSettings;}
    void SetLineNumberSettings(const LineNumberSettings& rSet) { m_aLineNumberSettings = rSet;}

diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index 01cf120..b8b4efc0 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -383,6 +383,7 @@ namespace
        { PROP_CURSOR_NOT_IGNORE_TABLES_IN_HF, u"CursorNotIgnoreTables"},
        { PROP_PARA_CONNECT_BORDERS, u"ParaIsConnectBorder"},
        { PROP_DECORATIVE, u"Decorative"},
        { PROP_PAPER_TRAY, u"PrinterPaperTray"},
    });
} // end anonymous ns

diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index 83d05d8..b39fcd2 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -262,6 +262,7 @@ enum PropertyIds
        ,PROP_PARA_TOP_MARGIN
        ,PROP_PARA_VERT_ALIGNMENT
        ,PROP_PARA_WIDOWS
        ,PROP_PAPER_TRAY
        ,PROP_PARENT_NUMBERING
        ,PROP_POSITION_AND_SPACE_MODE
        ,PROP_POSITION_PROTECTED
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index 9f9269b..29444d8 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -429,6 +429,8 @@ SectionPropertyMap::SectionPropertyMap( bool bIsFirstSection )
    , m_nLnc(NS_ooxml::LN_Value_ST_LineNumberRestart_newPage)
    , m_ndxaLnn( 0 )
    , m_nLnnMin( 0 )
    , m_nPaperSourceFirst( 0 )
    , m_nPaperSourceOther( 0 )
    , m_bDynamicHeightTop( true )
    , m_bDynamicHeightBottom( true )
{
@@ -575,6 +577,27 @@ void SectionPropertyMap::SetBorder( BorderPosition ePos, sal_Int32 nLineDistance
    m_bBorderShadows[ePos]   = bShadow;
}

void SectionPropertyMap::ApplyPaperSource(DomainMapper_Impl& rDM_Impl)
{
    uno::Reference<beans::XPropertySet> xFirst;
    // todo: negative spacing (from ww8par6.cxx)
    if (!m_sPageStyleName.isEmpty())
    {
        xFirst = GetPageStyle(rDM_Impl);
        if ( xFirst.is() )
            try
            {
                //TODO: which of the two tray values needs to be set? first/other - the interfaces requires the name of the tray!
                xFirst->setPropertyValue(getPropertyName(PROP_PAPER_TRAY),
                                         uno::Any(m_nPaperSourceFirst));
            }
            catch (const uno::Exception&)
            {
                TOOLS_WARN_EXCEPTION("writerfilter", "Paper source not found");
            }
    }
}

void SectionPropertyMap::ApplyBorderToPageStyles( DomainMapper_Impl& rDM_Impl,
                                                  BorderApply /*eBorderApply*/, BorderOffsetFrom eOffsetFrom )
{
@@ -1751,6 +1774,7 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl )
            ApplyProperties_(xPageStyle);

        ApplyBorderToPageStyles( rDM_Impl, m_eBorderApply, m_eBorderOffsetFrom );
        ApplyPaperSource(rDM_Impl);

        try
        {
diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx
index d6ecfb2..3b1b55d 100644
--- a/writerfilter/source/dmapper/PropertyMap.hxx
+++ b/writerfilter/source/dmapper/PropertyMap.hxx
@@ -295,6 +295,9 @@ private:
    sal_Int32                                       m_ndxaLnn;
    sal_Int32                                       m_nLnnMin;

    sal_Int32                                       m_nPaperSourceFirst;
    sal_Int32                                       m_nPaperSourceOther;

    bool                                            m_bDynamicHeightTop;
    bool                                            m_bDynamicHeightBottom;

@@ -409,12 +412,14 @@ public:
    void SetdxaLnn( sal_Int32 nValue ) { m_ndxaLnn = nValue; }
    void SetLnnMin( sal_Int32 nValue ) { m_nLnnMin = nValue; }

    void SetPaperSource(sal_Int32 first, sal_Int32 other) { m_nPaperSourceFirst = first; m_nPaperSourceOther = other;}

    void addRelativeWidthShape( css::uno::Reference<css::drawing::XShape> xShape ) { m_xRelativeWidthShapes.push_back( xShape ); }

    // determine which style gets the borders
    void ApplyBorderToPageStyles( DomainMapper_Impl &rDM_Impl,
                                  BorderApply eBorderApply, BorderOffsetFrom eOffsetFrom );

    void ApplyPaperSource(DomainMapper_Impl& rDM_Impl);
    void CloseSectionGroup( DomainMapper_Impl& rDM_Impl );
    // Handling of margins, header and footer for any kind of sections breaks.
    void HandleMarginsHeaderFooter(DomainMapper_Impl& rDM_Impl);
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index fd99a74..2c17474 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -17964,6 +17964,10 @@
      <attribute name="footer" tokenid="ooxml:CT_PageMar_footer"/>
      <attribute name="gutter" tokenid="ooxml:CT_PageMar_gutter"/>
    </resource>
    <resource name="CT_PaperSource" resource="Properties">
      <attribute name="first" tokenid="ooxml:CT_PaperSource_first"/>
      <attribute name="other" tokenid="ooxml:CT_PaperSource_other"/>
    </resource>
    <resource name="ST_PageBorderZOrder" resource="List">
      <value tokenid="ooxml:Value_doc_ST_PageBorderZOrder_front">front</value>
      <value tokenid="ooxml:Value_doc_ST_PageBorderZOrder_back">back</value>
diff --git a/writerfilter/source/rtftok/rtfdispatchvalue.cxx b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
index 69157a9..f699b0e 100644
--- a/writerfilter/source/rtftok/rtfdispatchvalue.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchvalue.cxx
@@ -1342,6 +1342,18 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam)
                               NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_w,
                               pIntValue);
            break;
        case RTFKeyword::BINFSXN:
            putNestedAttribute(m_aStates.top().getSectionSprms(),
                               NS_ooxml::LN_EG_SectPrContents_paperSrc,
                               NS_ooxml::LN_CT_PaperSource_first, pIntValue);
            break;
        case RTFKeyword::BINSXN:
        {
            putNestedAttribute(m_aStates.top().getSectionSprms(),
                               NS_ooxml::LN_EG_SectPrContents_paperSrc,
                               NS_ooxml::LN_CT_PaperSource_other, pIntValue);
        }
        break;
        case RTFKeyword::MARGL:
            putNestedAttribute(m_aDefaultState.getSectionSprms(),
                               NS_ooxml::LN_EG_SectPrContents_pgMar, NS_ooxml::LN_CT_PageMar_left,
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index b8d15fb..8a820fa 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -2120,6 +2120,8 @@ RTFError RTFDocumentImpl::pushState()
        case Destination::FIELDRESULT:
        case Destination::SHAPETEXT:
        case Destination::FORMFIELD:
            //TODO: if this is pushed then the font encoding is used which results in a broken command string
            // if it is not pushed to NORMAL then it is not restored in time.
        case Destination::FIELDINSTRUCTION:
        case Destination::PICT:
            m_aStates.top().setDestination(Destination::NORMAL);
@@ -3790,7 +3792,8 @@ void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex)
    if (bHex && !m_aHexBuffer.isEmpty())
    {
        rtl_TextEncoding nEncoding = m_aStates.top().getCurrentEncoding();
        if (m_aStates.top().getDestination() == Destination::FONTENTRY
        if ((m_aStates.top().getDestination() == Destination::FONTENTRY
             || m_aStates.top().getDestination() == Destination::FIELDINSTRUCTION)
            && m_aStates.top().getCurrentEncoding() == RTL_TEXTENCODING_SYMBOL)
            nEncoding = RTL_TEXTENCODING_MS_1252;
        OUString aString = OStringToOUString(m_aHexBuffer, nEncoding);