cui/source/inc/paragrph.hxx                                       |    2 
 cui/source/tabpages/paragrph.cxx                                  |  100 +++--
 cui/uiconfig/ui/paragalignpage.ui                                 |   49 ++
 editeng/source/editeng/impedit2.cxx                               |   25 +
 editeng/source/items/paraitem.cxx                                 |   10 
 editeng/source/uno/unonrule.cxx                                   |    2 
 include/editeng/adjustitem.hxx                                    |    8 
 include/editeng/editrids.hrc                                      |    2 
 include/editeng/svxenum.hxx                                       |    2 
 include/xmloff/xmlimp.hxx                                         |    3 
 offapi/com/sun/star/style/ParagraphAdjust.idl                     |   13 
 offapi/type_reference/offapi.idl                                  |    4 
 sw/qa/extras/odfexport/data/tdf118350-start-end-preserved.fodt    |  150 
+++++++
 sw/qa/extras/odfexport/odfexport4.cxx                             |   31 +
 sw/qa/extras/uiwriter/data/tdf143176.fodt                         |    2 
 sw/source/core/text/itrcrsr.cxx                                   |   26 +
 sw/source/core/unocore/unosett.cxx                                |    2 
 vcl/qa/cppunit/pdfexport/data/tdf118350-start-end-para-align.fodt |  192 
++++++++++
 vcl/qa/cppunit/pdfexport/pdfexport2.cxx                           |   91 ++++
 xmloff/qa/unit/uxmloff.cxx                                        |    5 
 xmloff/source/core/xmlimp.cxx                                     |   12 
 xmloff/source/style/adjushdl.cxx                                  |    4 
 xmloff/source/style/xmlimppr.cxx                                  |   29 +
 23 files changed, 705 insertions(+), 59 deletions(-)

New commits:
commit 5d1b2baaa96fce2cc283e4d383bcfca70651b2da
Author:     Jonathan Clark <[email protected]>
AuthorDate: Tue Oct 21 02:14:26 2025 -0600
Commit:     Jonathan Clark <[email protected]>
CommitDate: Fri Oct 24 13:07:10 2025 +0200

    tdf#118350 [API CHANGE] Implement start and end paragraph alignment
    
    Implements support for ODF fo:text-align start and end in paragraph
    styles. The new alignment options can be selected in the paragraph
    dialog. Further user interface changes are tracked as separate bugs.
    
    This change also adds START and END to css.style.ParagraphAdjust, which
    is flagged as an incompatible UNO API change.
    
    Change-Id: I2ee57f0029de7b794bc1ecd3eddbbd90af5dfdb9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192932
    Tested-by: Jenkins
    Reviewed-by: Jonathan Clark <[email protected]>

diff --git a/cui/source/inc/paragrph.hxx b/cui/source/inc/paragrph.hxx
index 856daffcf776..ff6482526ed3 100644
--- a/cui/source/inc/paragrph.hxx
+++ b/cui/source/inc/paragrph.hxx
@@ -128,7 +128,9 @@ class SvxParaAlignTabPage : public SfxTabPage
 
     // alignment
     std::unique_ptr<weld::RadioButton> m_xLeft;
+    std::unique_ptr<weld::RadioButton> m_xStart;
     std::unique_ptr<weld::RadioButton> m_xRight;
+    std::unique_ptr<weld::RadioButton> m_xEnd;
     std::unique_ptr<weld::RadioButton> m_xCenter;
     std::unique_ptr<weld::RadioButton> m_xJustify;
     std::unique_ptr<weld::Label> m_xLeftBottom;
diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx
index 3d285f514e84..978c4811b8cf 100644
--- a/cui/source/tabpages/paragrph.cxx
+++ b/cui/source/tabpages/paragrph.cxx
@@ -1265,7 +1265,9 @@ SvxParaAlignTabPage::SvxParaAlignTabPage(weld::Container* 
pPage, weld::DialogCon
     : SfxTabPage(pPage, pController, u"cui/ui/paragalignpage.ui"_ustr, 
u"ParaAlignPage"_ustr, &rSet)
     , m_bSdrVertAlign(false)
     , m_xLeft(m_xBuilder->weld_radio_button(u"radioBTN_LEFTALIGN"_ustr))
+    , m_xStart(m_xBuilder->weld_radio_button(u"radioBTN_STARTALIGN"_ustr))
     , m_xRight(m_xBuilder->weld_radio_button(u"radioBTN_RIGHTALIGN"_ustr))
+    , m_xEnd(m_xBuilder->weld_radio_button(u"radioBTN_ENDALIGN"_ustr))
     , m_xCenter(m_xBuilder->weld_radio_button(u"radioBTN_CENTERALIGN"_ustr))
     , m_xJustify(m_xBuilder->weld_radio_button(u"radioBTN_JUSTIFYALIGN"_ustr))
     , m_xLeftBottom(m_xBuilder->weld_label(u"labelST_LEFTALIGN_ASIAN"_ustr))
@@ -1321,7 +1323,9 @@ SvxParaAlignTabPage::SvxParaAlignTabPage(weld::Container* 
pPage, weld::DialogCon
 
     Link<weld::Toggleable&, void> aLink = LINK( this, SvxParaAlignTabPage, 
AlignHdl_Impl );
     m_xLeft->connect_toggled(aLink);
+    m_xStart->connect_toggled(aLink);
     m_xRight->connect_toggled(aLink);
+    m_xEnd->connect_toggled(aLink);
     m_xCenter->connect_toggled(aLink);
     m_xJustify->connect_toggled(aLink);
     m_xLastLineLB->connect_changed(LINK(this, SvxParaAlignTabPage, 
LastLineHdl_Impl));
@@ -1366,11 +1370,21 @@ bool SvxParaAlignTabPage::FillItemSet( SfxItemSet* 
rOutSet )
         eAdjust = SvxAdjust::Left;
         bAdj = m_xLeft->get_saved_state() == TRISTATE_FALSE;
     }
+    else if (m_xStart->get_active())
+    {
+        eAdjust = SvxAdjust::ParaStart;
+        bAdj = m_xStart->get_saved_state() == TRISTATE_FALSE;
+    }
     else if (m_xRight->get_active())
     {
         eAdjust = SvxAdjust::Right;
         bAdj = m_xRight->get_saved_state() == TRISTATE_FALSE;
     }
+    else if (m_xEnd->get_active())
+    {
+        eAdjust = SvxAdjust::ParaEnd;
+        bAdj = m_xEnd->get_saved_state() == TRISTATE_FALSE;
+    }
     else if (m_xCenter->get_active())
     {
         eAdjust = SvxAdjust::Center;
@@ -1466,8 +1480,12 @@ void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
         {
             case SvxAdjust::Left: m_xLeft->set_active(true); break;
 
+            case SvxAdjust::ParaStart: m_xStart->set_active(true); break;
+
             case SvxAdjust::Right: m_xRight->set_active(true); break;
 
+            case SvxAdjust::ParaEnd: m_xEnd->set_active(true); break;
+
             case SvxAdjust::Center: m_xCenter->set_active(true); break;
 
             case SvxAdjust::Block: m_xJustify->set_active(true); break;
@@ -1533,7 +1551,9 @@ void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
     else
     {
         m_xLeft->set_active(false);
+        m_xStart->set_active(false);
         m_xRight->set_active(false);
+        m_xEnd->set_active(false);
         m_xCenter->set_active(false);
         m_xJustify->set_active(false);
         m_xLabelWordSpacing->set_sensitive(false);
@@ -1601,7 +1621,9 @@ void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
     m_xSnapToGridCB->save_state();
     m_xVertAlignLB->save_value();
     m_xLeft->save_state();
+    m_xStart->save_state();
     m_xRight->save_state();
+    m_xEnd->save_state();
     m_xCenter->save_state();
     m_xJustify->save_state();
     m_xLastLineLB->save_value();
@@ -1623,7 +1645,9 @@ void SvxParaAlignTabPage::ChangesApplied()
     m_xSnapToGridCB->save_state();
     m_xVertAlignLB->save_value();
     m_xLeft->save_state();
+    m_xStart->save_state();
     m_xRight->save_state();
+    m_xEnd->save_state();
     m_xCenter->save_state();
     m_xJustify->save_state();
     m_xLastLineLB->save_value();
@@ -1714,50 +1738,64 @@ IMPL_LINK_NOARG(SvxParaAlignTabPage, 
WordSpacingMaximumHdl_Impl, weld::MetricSpi
 
 void SvxParaAlignTabPage::UpdateExample_Impl()
 {
+    bool bParaIsRtl = [&]
+    {
+        SvxFrameDirection eDir = m_xTextDirectionLB->get_active_id();
+        switch (eDir)
+        {
+            case SvxFrameDirection::Environment:
+                return AllSettings::GetLayoutRTL();
+
+            case SvxFrameDirection::Horizontal_RL_TB:
+                return true;
+
+            default:
+            case SvxFrameDirection::Horizontal_LR_TB:
+                return false;
+        }
+    }();
+
     if (m_xLeft->get_active())
     {
         m_aExampleWin.EnableRTL(false);
         m_aExampleWin.SetAdjust(SvxAdjust::Left);
         m_aExampleWin.SetLastLine(SvxAdjust::Left);
     }
+    else if (m_xStart->get_active())
+    {
+        m_aExampleWin.EnableRTL(bParaIsRtl);
+        m_aExampleWin.SetAdjust(SvxAdjust::Left);
+        m_aExampleWin.SetLastLine(SvxAdjust::Left);
+    }
     else if (m_xRight->get_active())
     {
         m_aExampleWin.EnableRTL(true);
         m_aExampleWin.SetAdjust(SvxAdjust::Left);
         m_aExampleWin.SetLastLine(SvxAdjust::Left);
     }
-    else
+    else if (m_xEnd->get_active())
     {
-        SvxFrameDirection eDir = m_xTextDirectionLB->get_active_id();
-        switch ( eDir )
-        {
-            case SvxFrameDirection::Environment :
-                if ( !m_xRight->get_active() )
-                    m_aExampleWin.EnableRTL( AllSettings::GetLayoutRTL() );
-                break;
-            case SvxFrameDirection::Horizontal_RL_TB :
-                if ( !m_xLeft->get_active() )
-                    m_aExampleWin.EnableRTL( true );
-                break;
-            case SvxFrameDirection::Horizontal_LR_TB :
-                if ( !m_xRight->get_active() )
-                    m_aExampleWin.EnableRTL( false );
-                break;
-            default: ; //prevent warning
-        }
-        if (m_xCenter->get_active())
-            m_aExampleWin.SetAdjust( SvxAdjust::Center );
-        else if (m_xJustify->get_active())
-        {
-            m_aExampleWin.SetAdjust( SvxAdjust::Block );
-            int nLBPos = m_xLastLineLB->get_active();
-            if (nLBPos == 0)
-                m_aExampleWin.SetLastLine(SvxAdjust::Left);
-            else if (nLBPos == 1)
-                m_aExampleWin.SetLastLine(SvxAdjust::Center);
-            else if (nLBPos == 2)
-                m_aExampleWin.SetLastLine(SvxAdjust::Block);
-        }
+        m_aExampleWin.EnableRTL(!bParaIsRtl);
+        m_aExampleWin.SetAdjust(SvxAdjust::Left);
+        m_aExampleWin.SetLastLine(SvxAdjust::Left);
+    }
+    else if (m_xCenter->get_active())
+    {
+        m_aExampleWin.EnableRTL(bParaIsRtl);
+        m_aExampleWin.SetAdjust(SvxAdjust::Center);
+    }
+    else if (m_xJustify->get_active())
+    {
+        m_aExampleWin.EnableRTL(bParaIsRtl);
+        m_aExampleWin.SetAdjust(SvxAdjust::Block);
+
+        int nLBPos = m_xLastLineLB->get_active();
+        if (nLBPos == 0)
+            m_aExampleWin.SetLastLine(SvxAdjust::Left);
+        else if (nLBPos == 1)
+            m_aExampleWin.SetLastLine(SvxAdjust::Center);
+        else if (nLBPos == 2)
+            m_aExampleWin.SetLastLine(SvxAdjust::Block);
     }
 
     m_aExampleWin.Invalidate();
diff --git a/cui/uiconfig/ui/paragalignpage.ui 
b/cui/uiconfig/ui/paragalignpage.ui
index 92824780cf41..58da274533f8 100644
--- a/cui/uiconfig/ui/paragalignpage.ui
+++ b/cui/uiconfig/ui/paragalignpage.ui
@@ -110,7 +110,7 @@
             <property name="label-xalign">0</property>
             <property name="shadow-type">none</property>
             <child>
-              <!-- n-columns=1 n-rows=8 -->
+              <!-- n-columns=1 n-rows=10 -->
               <object class="GtkGrid" id="grid2">
                 <property name="visible">True</property>
                 <property name="can-focus">False</property>
@@ -174,7 +174,7 @@
                   </object>
                   <packing>
                     <property name="left-attach">0</property>
-                    <property name="top-attach">3</property>
+                    <property name="top-attach">5</property>
                   </packing>
                 </child>
                 <child>
@@ -189,7 +189,7 @@
                   </object>
                   <packing>
                     <property name="left-attach">0</property>
-                    <property name="top-attach">5</property>
+                    <property name="top-attach">7</property>
                   </packing>
                 </child>
                 <child>
@@ -204,7 +204,7 @@
                   </object>
                   <packing>
                     <property name="left-attach">0</property>
-                    <property name="top-attach">6</property>
+                    <property name="top-attach">8</property>
                   </packing>
                 </child>
                 <child>
@@ -250,7 +250,7 @@
                   </object>
                   <packing>
                     <property name="left-attach">0</property>
-                    <property name="top-attach">7</property>
+                    <property name="top-attach">9</property>
                   </packing>
                 </child>
                 <child>
@@ -293,11 +293,41 @@
                       </packing>
                     </child>
                   </object>
+                  <packing>
+                    <property name="left-attach">0</property>
+                    <property name="top-attach">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="radioBTN_ENDALIGN">
+                    <property name="label" translatable="yes" 
context="paragalignpage|radioBTN_ENDALIGN">_End</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="receives-default">False</property>
+                    <property name="use-underline">True</property>
+                    <property name="draw-indicator">True</property>
+                    <property name="group">radioBTN_LEFTALIGN</property>
+                  </object>
                   <packing>
                     <property name="left-attach">0</property>
                     <property name="top-attach">4</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkRadioButton" id="radioBTN_STARTALIGN">
+                    <property name="label" translatable="yes" 
context="paragalignpage|radioBTN_STARTALIGN">S_tart</property>
+                    <property name="visible">True</property>
+                    <property name="can-focus">True</property>
+                    <property name="receives-default">False</property>
+                    <property name="use-underline">True</property>
+                    <property name="draw-indicator">True</property>
+                    <property name="group">radioBTN_LEFTALIGN</property>
+                  </object>
+                  <packing>
+                    <property name="left-attach">0</property>
+                    <property name="top-attach">3</property>
+                  </packing>
+                </child>
               </object>
             </child>
             <child type="label">
@@ -445,7 +475,7 @@
             <property name="label-xalign">0</property>
             <property name="shadow-type">none</property>
             <child>
-              <!-- n-columns=4 n-rows=2 -->
+              <!-- n-columns=4 n-rows=4 -->
               <object class="GtkGrid" id="gridJustification">
                 <property name="visible">True</property>
                 <property name="can-focus">False</property>
@@ -657,7 +687,12 @@
                     <property name="top-attach">3</property>
                   </packing>
                 </child>
-
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
                 <child>
                   <placeholder/>
                 </child>
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 5a617b0e6146..c72239dedc11 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -2070,12 +2070,29 @@ SvxAdjust ImpEditEngine::GetJustification( sal_Int32 
nPara ) const
     {
         eJustification = GetParaAttrib( nPara, EE_PARA_JUST ).GetAdjust();
 
-        if ( IsRightToLeft( nPara ) )
+        // Convert paragraph adjustment into an internal start/end value.
+        switch (eJustification)
         {
-            if ( eJustification == SvxAdjust::Left )
-                eJustification = SvxAdjust::Right;
-            else if ( eJustification == SvxAdjust::Right )
+            case SvxAdjust::ParaStart:
+                // Internally, the paragraph start is always the left margin:
                 eJustification = SvxAdjust::Left;
+                break;
+
+            case SvxAdjust::ParaEnd:
+                // Internally, the paragraph end is always the right margin:
+                eJustification = SvxAdjust::Right;
+                break;
+
+            case SvxAdjust::Left:
+                eJustification = IsRightToLeft(nPara) ? SvxAdjust::Right : 
SvxAdjust::Left;
+                break;
+
+            case SvxAdjust::Right:
+                eJustification = IsRightToLeft(nPara) ? SvxAdjust::Left : 
SvxAdjust::Right;
+                break;
+
+            default:
+                break;
         }
     }
     return eJustification;
diff --git a/editeng/source/items/paraitem.cxx 
b/editeng/source/items/paraitem.cxx
index 58fd5be3cc60..9c16c3f78dca 100644
--- a/editeng/source/items/paraitem.cxx
+++ b/editeng/source/items/paraitem.cxx
@@ -409,7 +409,7 @@ bool SvxAdjustItem::PutValue( const uno::Any& rVal, 
sal_uInt8 nMemberId )
         {
             sal_Int32 eVal = - 1;
             ::cppu::enum2int(eVal,rVal);
-            if(eVal >= 0 && eVal <= 4)
+            if(eVal >= 0 && eVal <= 6)
             {
                 SvxAdjust eAdjust = static_cast<SvxAdjust>(eVal);
                 if(MID_LAST_LINE_ADJUST == nMemberId &&
@@ -512,10 +512,12 @@ OUString SvxAdjustItem::GetValueTextByPos( sal_uInt16 
nPos )
         RID_SVXITEMS_ADJUST_RIGHT,
         RID_SVXITEMS_ADJUST_BLOCK,
         RID_SVXITEMS_ADJUST_CENTER,
-        RID_SVXITEMS_ADJUST_BLOCKLINE
+        RID_SVXITEMS_ADJUST_BLOCKLINE,
+        RID_SVXITEMS_ADJUST_PARASTART,
+        RID_SVXITEMS_ADJUST_PARAEND
     };
-    static_assert(std::size(RID_SVXITEMS_ADJUST) - 1 == 
static_cast<size_t>(SvxAdjust::BlockLine), "unexpected size");
-    assert(nPos <= sal_uInt16(SvxAdjust::BlockLine) && "enum overflow!");
+    static_assert(std::size(RID_SVXITEMS_ADJUST) - 1 == 
static_cast<size_t>(SvxAdjust::ParaEnd), "unexpected size");
+    assert(nPos <= sal_uInt16(SvxAdjust::ParaEnd) && "enum overflow!");
     return EditResId(RID_SVXITEMS_ADJUST[nPos]);
 }
 
diff --git a/editeng/source/uno/unonrule.cxx b/editeng/source/uno/unonrule.cxx
index c3ba8276551c..a508d6a7544c 100644
--- a/editeng/source/uno/unonrule.cxx
+++ b/editeng/source/uno/unonrule.cxx
@@ -72,6 +72,8 @@ const o3tl::enumarray<SvxAdjust, sal_Int16> aSvxToUnoAdjust
     text::HoriOrientation::FULL,
     text::HoriOrientation::CENTER,
     text::HoriOrientation::FULL,
+    text::HoriOrientation::LEFT,
+    text::HoriOrientation::RIGHT,
     text::HoriOrientation::LEFT
 };
 
diff --git a/include/editeng/adjustitem.hxx b/include/editeng/adjustitem.hxx
index c1acd36a4113..0a57417bc073 100644
--- a/include/editeng/adjustitem.hxx
+++ b/include/editeng/adjustitem.hxx
@@ -37,6 +37,8 @@ class EDITENG_DLLPUBLIC SvxAdjustItem final : public 
SfxPoolItem
     bool    bRight     : 1;
     bool    bCenter    : 1;
     bool    bBlock     : 1;
+    bool    bStart     : 1;
+    bool    bEnd       : 1;
 
     // only active when bBlock
     bool    bOneBlock : 1;
@@ -103,6 +105,8 @@ public:
         bRight = eType == SvxAdjust::Right;
         bCenter = eType == SvxAdjust::Center;
         bBlock = eType == SvxAdjust::Block;
+        bStart = eType == SvxAdjust::ParaStart;
+        bEnd = eType == SvxAdjust::ParaEnd;
     }
 
     SvxAdjust GetLastBlock() const
@@ -135,6 +139,10 @@ public:
             eRet = SvxAdjust::Center;
         else if ( bBlock )
             eRet = SvxAdjust::Block;
+        else if ( bStart )
+            eRet = SvxAdjust::ParaStart;
+        else if ( bEnd )
+            eRet = SvxAdjust::ParaEnd;
         return eRet;
     }
 
diff --git a/include/editeng/editrids.hrc b/include/editeng/editrids.hrc
index 23c8ec932fd0..fa82e0d90f33 100644
--- a/include/editeng/editrids.hrc
+++ b/include/editeng/editrids.hrc
@@ -151,6 +151,8 @@
 #define RID_SVXITEMS_ADJUST_BLOCK               
NC_("RID_SVXITEMS_ADJUST_BLOCK", "Justify")
 #define RID_SVXITEMS_ADJUST_CENTER              
NC_("RID_SVXITEMS_ADJUST_CENTER", "Centered")
 #define RID_SVXITEMS_ADJUST_BLOCKLINE           
NC_("RID_SVXITEMS_ADJUST_BLOCKLINE", "Justify")
+#define RID_SVXITEMS_ADJUST_PARASTART           
NC_("RID_SVXITEMS_ADJUST_PARASTART", "Start")
+#define RID_SVXITEMS_ADJUST_PARAEND             
NC_("RID_SVXITEMS_ADJUST_PARAEND", "End")
 #define RID_SOLID                               NC_("RID_SOLID", "Single, 
solid")
 #define RID_DOTTED                              NC_("RID_DOTTED", "Single, 
dotted")
 #define RID_DASHED                              NC_("RID_DASHED", "Single, 
dashed")
diff --git a/include/editeng/svxenum.hxx b/include/editeng/svxenum.hxx
index ba77a2a3c65a..84362e18c975 100644
--- a/include/editeng/svxenum.hxx
+++ b/include/editeng/svxenum.hxx
@@ -83,6 +83,8 @@ enum class SvxAdjust
     Block,
     Center,
     BlockLine,
+    ParaStart,
+    ParaEnd,
     End,
     LAST = End
 };
diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx
index 352c61224f74..2a0660272250 100644
--- a/include/xmloff/xmlimp.hxx
+++ b/include/xmloff/xmlimp.hxx
@@ -555,6 +555,9 @@ public:
     static const sal_uInt16 LO_76 = 76 | LO_flag;
     static const sal_uInt16 LO_242 = 80 | LO_flag;
     static const sal_uInt16 LO_248 = 81 | LO_flag;
+    static const sal_uInt16 LO_252 = 82 | LO_flag;
+    static const sal_uInt16 LO_258 = 83 | LO_flag;
+    static const sal_uInt16 LO_262 = 84 | LO_flag;
     static const sal_uInt16 LO_New = 100 | LO_flag;
     static const sal_uInt16 ProductVersionUnknown = SAL_MAX_UINT16;
 
diff --git a/offapi/com/sun/star/style/ParagraphAdjust.idl 
b/offapi/com/sun/star/style/ParagraphAdjust.idl
index 367202bfa87a..248eec51dca3 100644
--- a/offapi/com/sun/star/style/ParagraphAdjust.idl
+++ b/offapi/com/sun/star/style/ParagraphAdjust.idl
@@ -43,8 +43,19 @@ published enum ParagraphAdjust
 
     /** adjusted to both borders / stretched, including last line
      */
-    STRETCH
+    STRETCH,
 
+    /** equivalent to LEFT for LTR paragraphs, RIGHT for RTL paragraphs
+
+        @since LibreOffice 26.2
+     */
+    START,
+
+    /** equivalent to RIGHT for LTR paragraphs, LEFT for RTL paragraphs
+
+        @since LibreOffice 26.2
+     */
+    END
 };
 
 
diff --git a/offapi/type_reference/offapi.idl b/offapi/type_reference/offapi.idl
index 471183f20005..369ca0550221 100644
--- a/offapi/type_reference/offapi.idl
+++ b/offapi/type_reference/offapi.idl
@@ -3585,7 +3585,9 @@ module com {
      RIGHT = 1,
      BLOCK = 2,
      CENTER = 3,
-     STRETCH = 4
+     STRETCH = 4,
+     START = 5,
+     END = 6
     };
     published enum TabAlign {
      LEFT = 0,
diff --git a/sw/qa/extras/odfexport/data/tdf118350-start-end-preserved.fodt 
b/sw/qa/extras/odfexport/data/tdf118350-start-end-preserved.fodt
new file mode 100644
index 000000000000..2859bf0cddae
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/tdf118350-start-end-preserved.fodt
@@ -0,0 +1,150 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/"; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#"; 
xmlns:xhtml="http://www.w3.org/1999/xhtml"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
xmlns:xforms="http://www.w3.org/2002/xforms"; 
xmlns:dom="http://www.w3.org/2001/xml-events"; 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML"; 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office"; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; 
xmlns:drawooo="http://openoffice.org/2010/draw"; 
xmlns:oooc="http://openoffice.org/2004/calc"; 
xmlns:dc="http://purl.org/dc/elements/1.1/"; xmlns:c
 alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:tableooo="http://openoffice.org/2009/table"; 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:rpt="http://openoffice.org/2005/report"; 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:officeooo="http://openoffice.org/2009/office"; 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:
 meta:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
<office:meta><meta:creation-date>2025-10-22T05:31:47.251184918</meta:creation-date><meta:generator>LibreOfficeDev/26.2.0.0.alpha0$Linux_X86_64
 
LibreOffice_project/d7e24df067ba6af0043e70750ad2b97e21201fa9</meta:generator><dc:date>2025-10-22T05:36:27.933616336</dc:date><meta:editing-duration>PT4M39S</meta:editing-duration><meta:editing-cycles>3</meta:editing-cycles><meta:document-statistic
 meta:table-count="0" meta:image-count="0" meta:object-count="0" 
meta:page-count="1" meta:paragraph-count="8" meta:word-count="48" 
meta:character-count="282" 
meta:non-whitespace-character-count="242"/></office:meta>
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation 
Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+  <style:font-face style:name="Noto Sans Devanagari1" svg:font-family="'Noto 
Sans Devanagari'" style:font-family-generic="system" 
style:font-pitch="variable"/>
+  <style:font-face style:name="Noto Serif CJK JP" svg:font-family="'Noto Serif 
CJK JP'" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="graphic">
+   <style:graphic-properties svg:stroke-color="#3465a4" 
draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" 
draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" 
draw:start-line-spacing-vertical="0.283cm" 
draw:end-line-spacing-horizontal="0.283cm" 
draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+   <style:paragraph-properties style:text-autospace="ideograph-alpha" 
style:line-break="strict" loext:tab-stop-distance="0cm" 
style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+    <style:tab-stops/>
+   </style:paragraph-properties>
+   <style:text-properties style:use-window-font-color="true" 
loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" 
fo:language="en" fo:country="CA" style:letter-kerning="true" 
style:font-name-asian="Noto Serif CJK JP" style:font-size-asian="10.5pt" 
style:language-asian="ja" style:country-asian="JP" 
style:font-name-complex="Noto Sans Devanagari1" style:font-size-complex="12pt" 
style:language-complex="hi" style:country-complex="IN"/>
+  </style:default-style>
+  <style:default-style style:family="paragraph">
+   <style:paragraph-properties fo:orphans="2" fo:widows="2" 
fo:hyphenation-ladder-count="no-limit" fo:hyphenation-keep="auto" 
loext:hyphenation-keep-type="column" style:text-autospace="ideograph-alpha" 
style:punctuation-wrap="hanging" style:line-break="strict" 
style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+   <style:text-properties style:use-window-font-color="true" 
loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" 
fo:language="en" fo:country="CA" style:letter-kerning="true" 
style:font-name-asian="Noto Serif CJK JP" style:font-size-asian="10.5pt" 
style:language-asian="ja" style:country-asian="JP" 
style:font-name-complex="Noto Sans Devanagari1" style:font-size-complex="12pt" 
style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" 
fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" 
loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" 
loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/>
+  </style:default-style>
+  <style:default-style style:family="table">
+   <style:table-properties table:border-model="collapsing"/>
+  </style:default-style>
+  <style:default-style style:family="table-row">
+   <style:table-row-properties fo:keep-together="auto"/>
+  </style:default-style>
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text"/>
+  <style:style style:name="LTRLeft" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="left"/>
+  </style:style>
+  <style:style style:name="LTRStart" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="start"/>
+  </style:style>
+  <style:style style:name="LTRRight" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="right"/>
+  </style:style>
+  <style:style style:name="LTREnd" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="end"/>
+  </style:style>
+  <style:style style:name="RTLLeft" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="left" 
style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="RTLStart" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="start" 
style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="RTLRight" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="right" 
style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="RTLEnd" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="end" style:writing-mode="rl-tb"/>
+  </style:style>
+  <text:outline-style style:name="Outline">
+   <text:outline-level-style text:level="1" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="2" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="3" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="4" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="5" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="6" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="7" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="8" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="9" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="10" style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+  </text:outline-style>
+  <text:notes-configuration text:note-class="footnote" style:num-format="1" 
text:start-value="0" text:footnotes-position="page" 
text:start-numbering-at="document"/>
+  <text:notes-configuration text:note-class="endnote" style:num-format="i" 
text:start-value="0"/>
+  <text:linenumbering-configuration text:number-lines="false" 
text:offset="0.499cm" style:num-format="1" text:number-position="left" 
text:increment="5"/>
+  </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties/>
+  </style:style>
+  <style:page-layout style:name="pm1">
+   <style:page-layout-properties fo:page-width="21.59cm" 
fo:page-height="27.94cm" style:num-format="1" 
style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" 
fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" 
style:footnote-max-height="0cm" loext:margin-gutter="0cm">
+    <style:footnote-sep style:width="0.018cm" 
style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" 
style:line-style="solid" style:adjustment="left" style:rel-width="25%" 
style:color="#000000"/>
+   </style:page-layout-properties>
+   <style:header-style/>
+   <style:footer-style/>
+  </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+  <office:text>
+   <text:sequence-decls>
+    <text:sequence-decl text:display-outline-level="0" 
text:name="Illustration"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
+   </text:sequence-decls>
+   <text:p text:style-name="LTRLeft">This paragraph is LTR aligned 
left.</text:p>
+   <text:p text:style-name="P1"/>
+   <text:p text:style-name="LTRStart">This paragraph is LTR aligned 
start.</text:p>
+   <text:p text:style-name="P1"/>
+   <text:p text:style-name="LTRRight">This paragraph is LTR aligned 
right.</text:p>
+   <text:p text:style-name="P1"/>
+   <text:p text:style-name="LTREnd">This paragraph is LTR aligned end.</text:p>
+   <text:p text:style-name="P1"/>
+   <text:p text:style-name="RTLLeft">This paragraph is RTL aligned 
left.</text:p>
+   <text:p text:style-name="P1"/>
+   <text:p text:style-name="RTLStart">This paragraph is RTL aligned 
start.</text:p>
+   <text:p text:style-name="P1"/>
+   <text:p text:style-name="RTLRight">This paragraph is RTL aligned 
right.</text:p>
+   <text:p text:style-name="P1"/>
+   <text:p text:style-name="RTLEnd">This paragraph is RTL aligned end.</text:p>
+   <text:p text:style-name="RTLEnd"/>
+  </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/odfexport/odfexport4.cxx 
b/sw/qa/extras/odfexport/odfexport4.cxx
index d75937da016c..087e19731391 100644
--- a/sw/qa/extras/odfexport/odfexport4.cxx
+++ b/sw/qa/extras/odfexport/odfexport4.cxx
@@ -1645,8 +1645,9 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf168980)
 
 CPPUNIT_TEST_FIXTURE(Test, testTdf37128ConvertStartEndOnResave)
 {
-    // LO doesn't support start/end fo:text-align. These are always loaded as
-    // left/right, respectively. They should be resaved as left/right, too.
+    // Older versions of LO always stored fo:text-align left/right as
+    // start/end, respectively. Make sure documents produced by older
+    // versions of LO convert these values to left/right.
     loadAndReload("tdf37128-start-end-to-left-right.fodt");
     CPPUNIT_ASSERT_EQUAL(1, getPages());
     xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
@@ -1669,6 +1670,32 @@ CPPUNIT_TEST_FIXTURE(Test, 
testTdf37128ConvertStartEndOnResave)
                 "text-align", u"right");
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf118350StartEndPreserved)
+{
+    // Check that fo:text-align start/end round-trip correctly for
+    // documents made by newer versions of LO.
+    loadAndReload("tdf118350-start-end-preserved.fodt");
+    CPPUNIT_ASSERT_EQUAL(1, getPages());
+    xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
+
+    assertXPath(pXmlDoc, 
"//style:style[@style:name='LTRLeft']/style:paragraph-properties",
+                "text-align", u"left");
+    assertXPath(pXmlDoc, 
"//style:style[@style:name='LTRStart']/style:paragraph-properties",
+                "text-align", u"start");
+    assertXPath(pXmlDoc, 
"//style:style[@style:name='LTRRight']/style:paragraph-properties",
+                "text-align", u"right");
+    assertXPath(pXmlDoc, 
"//style:style[@style:name='LTREnd']/style:paragraph-properties",
+                "text-align", u"end");
+    assertXPath(pXmlDoc, 
"//style:style[@style:name='RTLLeft']/style:paragraph-properties",
+                "text-align", u"left");
+    assertXPath(pXmlDoc, 
"//style:style[@style:name='RTLStart']/style:paragraph-properties",
+                "text-align", u"start");
+    assertXPath(pXmlDoc, 
"//style:style[@style:name='RTLRight']/style:paragraph-properties",
+                "text-align", u"right");
+    assertXPath(pXmlDoc, 
"//style:style[@style:name='RTLEnd']/style:paragraph-properties",
+                "text-align", u"end");
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/qa/extras/uiwriter/data/tdf143176.fodt 
b/sw/qa/extras/uiwriter/data/tdf143176.fodt
index fdd89c38da3c..994f133447d4 100644
--- a/sw/qa/extras/uiwriter/data/tdf143176.fodt
+++ b/sw/qa/extras/uiwriter/data/tdf143176.fodt
@@ -8,7 +8,7 @@
  </office:styles>
  <office:automatic-styles>
   <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard">
-   <style:paragraph-properties fo:text-align="end" 
style:justify-single-word="false" style:writing-mode="rl-tb"/>
+   <style:paragraph-properties fo:text-align="start" 
style:justify-single-word="false" style:writing-mode="rl-tb"/>
   </style:style>
  </office:automatic-styles>
  <office:body>
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index 1a8c500ef92f..bff160bffba8 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -348,13 +348,29 @@ void SwTextMargin::CtorInitTextMargin( SwTextFrame 
*pNewFrame, SwTextSizeInfo *p
     const SvxAdjustItem& rAdjust = 
m_pFrame->GetTextNodeForParaProps()->GetSwAttrSet().GetAdjust();
     mnAdjust = rAdjust.GetAdjust();
 
-    // left is left and right is right
-    if ( m_pFrame->IsRightToLeft() )
+    // Convert paragraph adjustment into an internal start/end value.
+    switch (mnAdjust)
     {
-        if ( SvxAdjust::Left == mnAdjust )
-            mnAdjust = SvxAdjust::Right;
-        else if ( SvxAdjust::Right == mnAdjust )
+        case SvxAdjust::ParaStart:
+            // Internally, the paragraph start is always the left margin:
             mnAdjust = SvxAdjust::Left;
+            break;
+
+        case SvxAdjust::ParaEnd:
+            // Internally, the paragraph end is always the right margin:
+            mnAdjust = SvxAdjust::Right;
+            break;
+
+        case SvxAdjust::Left:
+            mnAdjust = m_pFrame->IsRightToLeft() ? SvxAdjust::Right : 
SvxAdjust::Left;
+            break;
+
+        case SvxAdjust::Right:
+            mnAdjust = m_pFrame->IsRightToLeft() ? SvxAdjust::Left : 
SvxAdjust::Right;
+            break;
+
+        default:
+            break;
     }
 
     m_bOneBlock = rAdjust.GetOneWord() == SvxAdjust::Block;
diff --git a/sw/source/core/unocore/unosett.cxx 
b/sw/source/core/unocore/unosett.cxx
index cce13036c8d5..cd4d5020f13f 100644
--- a/sw/source/core/unocore/unosett.cxx
+++ b/sw/source/core/unocore/unosett.cxx
@@ -244,6 +244,8 @@ const o3tl::enumarray<SvxAdjust, sal_Int16> aSvxToUnoAdjust
     sal_Int16(-1),
     text::HoriOrientation::CENTER, //2
     sal_Int16(-1),
+    sal_Int16(-1),
+    sal_Int16(-1),
     sal_Int16(-1)
 };
 
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf118350-start-end-para-align.fodt 
b/vcl/qa/cppunit/pdfexport/data/tdf118350-start-end-para-align.fodt
new file mode 100644
index 000000000000..ad0b5e132659
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/tdf118350-start-end-para-align.fodt
@@ -0,0 +1,192 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/"; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#"; 
xmlns:xhtml="http://www.w3.org/1999/xhtml"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
xmlns:xforms="http://www.w3.org/2002/xforms"; 
xmlns:dom="http://www.w3.org/2001/xml-events"; 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML"; 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office"; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; 
xmlns:drawooo="http://openoffice.org/2010/draw"; 
xmlns:oooc="http://openoffice.org/2004/calc"; 
xmlns:dc="http://purl.org/dc/elements/1.1/"; xmlns:c
 alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:tableooo="http://openoffice.org/2009/table"; 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:rpt="http://openoffice.org/2005/report"; 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:officeooo="http://openoffice.org/2009/office"; 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:
 meta:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ 
<office:meta><meta:creation-date>2025-10-23T06:15:16.537082542</meta:creation-date><dc:date>2025-10-23T06:21:45.657634279</dc:date><meta:editing-duration>PT4M33S</meta:editing-duration><meta:editing-cycles>5</meta:editing-cycles><meta:generator>LibreOfficeDev/26.2.0.0.alpha0$Linux_X86_64
 
LibreOffice_project/faccef0e7b37c40cb2efc276ea5d914f9496665e</meta:generator><meta:document-statistic
 meta:table-count="0" meta:image-count="0" meta:object-count="0" 
meta:page-count="1" meta:paragraph-count="8" meta:word-count="48" 
meta:character-count="282" 
meta:non-whitespace-character-count="242"/></office:meta>
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation 
Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+  <style:font-face style:name="Noto Sans1" svg:font-family="'Noto Sans'" 
style:font-family-generic="system" style:font-pitch="variable"/>
+  <style:font-face style:name="Noto Serif CJK SC" svg:font-family="'Noto Serif 
CJK SC'" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="graphic">
+   <style:graphic-properties svg:stroke-color="#3465a4" 
draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" 
draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" 
draw:start-line-spacing-vertical="0.283cm" 
draw:end-line-spacing-horizontal="0.283cm" 
draw:end-line-spacing-vertical="0.283cm" style:writing-mode="lr-tb" 
style:flow-with-text="false"/>
+   <style:paragraph-properties style:text-autospace="ideograph-alpha" 
style:line-break="strict" loext:tab-stop-distance="0cm" 
style:font-independent-line-spacing="false">
+    <style:tab-stops/>
+   </style:paragraph-properties>
+   <style:text-properties style:use-window-font-color="true" 
loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" 
fo:language="en" fo:country="CA" style:letter-kerning="true" 
style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" 
style:language-asian="zh" style:country-asian="CN" 
style:font-name-complex="Noto Sans1" style:font-size-complex="12pt" 
style:language-complex="hi" style:country-complex="IN"/>
+  </style:default-style>
+  <style:default-style style:family="paragraph">
+   <style:paragraph-properties fo:orphans="2" fo:widows="2" 
fo:hyphenation-ladder-count="no-limit" fo:hyphenation-keep="auto" 
loext:hyphenation-keep-type="column" loext:hyphenation-keep-line="false" 
style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" 
style:line-break="strict" style:tab-stop-distance="1.251cm" 
style:writing-mode="page"/>
+   <style:text-properties style:use-window-font-color="true" 
loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" 
fo:language="en" fo:country="CA" style:letter-kerning="true" 
style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" 
style:language-asian="zh" style:country-asian="CN" 
style:font-name-complex="Noto Sans1" style:font-size-complex="12pt" 
style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" 
fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" 
loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" 
loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/>
+  </style:default-style>
+  <style:default-style style:family="table">
+   <style:table-properties table:border-model="collapsing"/>
+  </style:default-style>
+  <style:default-style style:family="table-row">
+   <style:table-row-properties fo:keep-together="auto"/>
+  </style:default-style>
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text"/>
+  <text:outline-style style:name="Outline">
+   <text:outline-level-style text:level="1" loext:num-list-format="%1%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="2" loext:num-list-format="%2%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="3" loext:num-list-format="%3%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="4" loext:num-list-format="%4%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="5" loext:num-list-format="%5%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="6" loext:num-list-format="%6%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="7" loext:num-list-format="%7%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="8" loext:num-list-format="%8%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="9" loext:num-list-format="%9%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+   <text:outline-level-style text:level="10" loext:num-list-format="%10%" 
style:num-format="">
+    <style:list-level-properties 
text:list-level-position-and-space-mode="label-alignment">
+     <style:list-level-label-alignment text:label-followed-by="listtab"/>
+    </style:list-level-properties>
+   </text:outline-level-style>
+  </text:outline-style>
+  <text:notes-configuration text:note-class="footnote" style:num-format="1" 
text:start-value="0" text:footnotes-position="page" 
text:start-numbering-at="document"/>
+  <text:notes-configuration text:note-class="endnote" style:num-format="i" 
text:start-value="0"/>
+  <text:linenumbering-configuration text:number-lines="false" 
text:offset="0.499cm" style:num-format="1" text:number-position="left" 
text:increment="5"/>
+  </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="start" 
style:justify-single-word="false"/>
+  </style:style>
+  <style:style style:name="P2" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="right" 
style:justify-single-word="false"/>
+  </style:style>
+  <style:style style:name="P3" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="end" 
style:justify-single-word="false"/>
+  </style:style>
+  <style:style style:name="P4" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="P5" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="start" 
style:justify-single-word="false" style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="P6" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="right" 
style:justify-single-word="false" style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="P7" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:paragraph-properties fo:text-align="end" 
style:justify-single-word="false" style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="P8" style:family="paragraph">
+   <style:paragraph-properties fo:text-align="start"/>
+  </style:style>
+  <style:style style:name="P9" style:family="paragraph">
+   <style:paragraph-properties fo:text-align="right"/>
+  </style:style>
+  <style:style style:name="P10" style:family="paragraph">
+   <style:paragraph-properties fo:text-align="end"/>
+  </style:style>
+  <style:style style:name="P11" style:family="paragraph">
+   <style:paragraph-properties fo:text-align="end" style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="P12" style:family="paragraph">
+   <style:paragraph-properties fo:text-align="start" 
style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="P13" style:family="paragraph">
+   <style:paragraph-properties fo:text-align="right" 
style:writing-mode="rl-tb"/>
+  </style:style>
+  <style:style style:name="P14" style:family="paragraph">
+   <loext:graphic-properties draw:fill="none" draw:fill-color="#ffffff"/>
+  </style:style>
+  <style:style style:name="gr1" style:family="graphic">
+   <style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" 
draw:fill="none" draw:fill-color="#ffffff" fo:min-height="11.748cm" 
loext:decorative="false" style:run-through="foreground" 
style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" 
style:vertical-pos="from-top" style:vertical-rel="paragraph" 
style:horizontal-pos="from-left" style:horizontal-rel="paragraph" 
draw:wrap-influence-on-position="once-concurrent" loext:allow-overlap="true" 
style:flow-with-text="false"/>
+   <style:paragraph-properties style:writing-mode="lr-tb"/>
+  </style:style>
+  <style:page-layout style:name="pm1">
+   <style:page-layout-properties fo:page-width="21.59cm" 
fo:page-height="27.94cm" style:num-format="1" 
style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" 
fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" 
style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" 
style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" 
style:layout-grid-mode="none" style:layout-grid-ruby-below="false" 
style:layout-grid-print="false" style:layout-grid-display="false" 
style:footnote-max-height="0cm" loext:margin-gutter="0cm">
+    <style:footnote-sep style:width="0.018cm" 
style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" 
style:line-style="solid" style:adjustment="left" style:rel-width="25%" 
style:color="#000000"/>
+   </style:page-layout-properties>
+   <style:header-style/>
+   <style:footer-style/>
+  </style:page-layout>
+  <style:style style:name="dp1" style:family="drawing-page">
+   <style:drawing-page-properties draw:background-size="full"/>
+  </style:style>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1" 
draw:style-name="dp1"/>
+ </office:master-styles>
+ <office:body>
+  <office:text>
+   <text:sequence-decls>
+    <text:sequence-decl text:display-outline-level="0" 
text:name="Illustration"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+    <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
+   </text:sequence-decls>
+   <text:p text:style-name="Standard">This paragraph is LTR aligned 
left.</text:p>
+   <text:p text:style-name="Standard"/>
+   <text:p text:style-name="P1">This paragraph is LTR aligned start.</text:p>
+   <text:p text:style-name="Standard"/>
+   <text:p text:style-name="P2">This paragraph is LTR aligned right.</text:p>
+   <text:p text:style-name="Standard"/>
+   <text:p text:style-name="P3">This paragraph is LTR aligned end.</text:p>
+   <text:p text:style-name="Standard"/>
+   <text:p text:style-name="P4">This paragraph is RTL aligned left.</text:p>
+   <text:p text:style-name="Standard"/>
+   <text:p text:style-name="P5">This paragraph is RTL aligned start.</text:p>
+   <text:p text:style-name="Standard"/>
+   <text:p text:style-name="P6">This paragraph is RTL aligned right.</text:p>
+   <text:p text:style-name="Standard"/>
+   <text:p text:style-name="P7">This paragraph is RTL aligned end.</text:p>
+   <text:p text:style-name="Standard"/>
+   <text:p text:style-name="Standard"><draw:frame text:anchor-type="paragraph" 
draw:z-index="0" draw:name="Text Frame 1" draw:style-name="gr1" 
draw:text-style-name="P14" svg:width="15.505cm" svg:height="11.748cm" 
svg:x="1.478cm" svg:y="1.986cm">
+     <draw:text-box>
+      <text:p>This paragraph is LTR aligned left.</text:p>
+      <text:p/>
+      <text:p text:style-name="P8">This paragraph is LTR aligned 
start.</text:p>
+      <text:p/>
+      <text:p text:style-name="P9">This paragraph is LTR aligned 
right.</text:p>
+      <text:p/>
+      <text:p text:style-name="P10">This paragraph is LTR aligned end.</text:p>
+      <text:p/>
+      <text:p text:style-name="P11">This paragraph is RTL aligned 
left.</text:p>
+      <text:p/>
+      <text:p text:style-name="P12">This paragraph is RTL aligned 
start.</text:p>
+      <text:p/>
+      <text:p text:style-name="P13">This paragraph is RTL aligned 
right.</text:p>
+      <text:p/>
+      <text:p text:style-name="P11">This paragraph is RTL aligned end.</text:p>
+      <text:p/>
+     </draw:text-box>
+    </draw:frame></text:p>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx 
b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
index b160e67b0ab0..61075c4d3bf9 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport2.cxx
@@ -6348,6 +6348,97 @@ CPPUNIT_TEST_FIXTURE(PdfExportTest2, 
testTdf166044ContFootnoteOnlyOnePgNum)
     CPPUNIT_ASSERT_EQUAL(u"2"_ustr, pPgNumObject->getText(pTextPage));
 }
 
+CPPUNIT_TEST_FIXTURE(PdfExportTest2, testTdf118350StartEndParaAlign)
+{
+    saveAsPDF(u"tdf118350-start-end-para-align.fodt");
+
+    auto pPdfDocument = parsePDFExport();
+    CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount());
+
+    auto pPdfPage = pPdfDocument->openPage(/*nIndex*/ 0);
+    CPPUNIT_ASSERT(pPdfPage);
+    auto pTextPage = pPdfPage->getTextPage();
+    CPPUNIT_ASSERT(pTextPage);
+
+    int nPageObjectCount = pPdfPage->getObjectCount();
+
+    CPPUNIT_ASSERT_EQUAL(24, nPageObjectCount);
+
+    std::vector<OUString> aText;
+    std::vector<basegfx::B2DRectangle> aRect;
+
+    for (int i = 0; i < nPageObjectCount; ++i)
+    {
+        auto pPageObject = pPdfPage->getObject(i);
+        CPPUNIT_ASSERT_MESSAGE("no object", pPageObject != nullptr);
+        if (pPageObject->getType() == vcl::pdf::PDFPageObjectType::Text)
+        {
+            aText.push_back(pPageObject->getText(pTextPage));
+            aRect.push_back(pPageObject->getBounds());
+        }
+    }
+
+    CPPUNIT_ASSERT_EQUAL(size_t(24), aText.size());
+
+    // Lines from the Writer portion
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is LTR aligned left."_ustr, 
aText.at(0).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(57.0, aRect.at(0).getMinX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is LTR aligned start."_ustr, 
aText.at(1).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(57.0, aRect.at(1).getMinX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is LTR aligned right."_ustr, 
aText.at(2).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(550.0, aRect.at(2).getMaxX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is LTR aligned end."_ustr, 
aText.at(3).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(550.0, aRect.at(3).getMaxX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is RTL aligned left"_ustr, 
aText.at(4).trim());
+    CPPUNIT_ASSERT_EQUAL(u"."_ustr, aText.at(5).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(57.0, aRect.at(5).getMinX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is RTL aligned start"_ustr, 
aText.at(6).trim());
+    CPPUNIT_ASSERT_EQUAL(u"."_ustr, aText.at(7).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(550.0, aRect.at(6).getMaxX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is RTL aligned right"_ustr, 
aText.at(8).trim());
+    CPPUNIT_ASSERT_EQUAL(u"."_ustr, aText.at(9).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(550.0, aRect.at(8).getMaxX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is RTL aligned end"_ustr, 
aText.at(10).trim());
+    CPPUNIT_ASSERT_EQUAL(u"."_ustr, aText.at(11).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(57.0, aRect.at(11).getMinX(), /*delta*/ 10.0);
+
+    // Lines from the Edit Engine portion
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is LTR aligned left."_ustr, 
aText.at(12).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(99.0, aRect.at(12).getMinX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is LTR aligned start."_ustr, 
aText.at(13).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(99.0, aRect.at(13).getMinX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is LTR aligned right."_ustr, 
aText.at(14).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(537.0, aRect.at(14).getMaxX(), /*delta*/ 
10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is LTR aligned end."_ustr, 
aText.at(15).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(537.0, aRect.at(15).getMaxX(), /*delta*/ 
10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is RTL aligned left"_ustr, 
aText.at(16).trim());
+    CPPUNIT_ASSERT_EQUAL(u"."_ustr, aText.at(17).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(99.0, aRect.at(17).getMinX(), /*delta*/ 10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is RTL aligned start"_ustr, 
aText.at(18).trim());
+    CPPUNIT_ASSERT_EQUAL(u"."_ustr, aText.at(19).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(537.0, aRect.at(18).getMaxX(), /*delta*/ 
10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is RTL aligned right"_ustr, 
aText.at(20).trim());
+    CPPUNIT_ASSERT_EQUAL(u"."_ustr, aText.at(21).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(537.0, aRect.at(20).getMaxX(), /*delta*/ 
10.0);
+
+    CPPUNIT_ASSERT_EQUAL(u"This paragraph is RTL aligned end"_ustr, 
aText.at(22).trim());
+    CPPUNIT_ASSERT_EQUAL(u"."_ustr, aText.at(23).trim());
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(99.0, aRect.at(23).getMinX(), /*delta*/ 10.0);
+}
+
 } // end anonymous namespace
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/xmloff/qa/unit/uxmloff.cxx b/xmloff/qa/unit/uxmloff.cxx
index cf888baa93fd..7f51e193f284 100644
--- a/xmloff/qa/unit/uxmloff.cxx
+++ b/xmloff/qa/unit/uxmloff.cxx
@@ -201,7 +201,10 @@ void Test::testMetaGenerator()
         { "CIB_OfficeDev/6.4.0.19$Linux_X86_64 
LibreOffice_project/2e04f804b5f82770435f250873f07b3384d95504", ";6.4.0.19", 
SvXMLImport::LO_63x },
         { "LibreOfficeDev/24.2.0.0.alpha0$Linux_X86_64 
LibreOffice_project/b81e7b6f3c71fb3ade1cb665444ac730dac0a9a9", ";24.2.0.0.", 
SvXMLImport::LO_242 },
         { "LibreOfficeDev/24.8.6.2$Linux_X86_64 
LibreOffice_project/dc6216c3d2b4ec3bcdba950f1e6ee1d013adb2d6", ";24.8.6.2", 
SvXMLImport::LO_248 },
-        { "LibreOfficeDev/25.8.0.0.alpha0$Linux_X86_64 
LibreOffice_project/308705574842e0c36f7385f73fc47da9a4542367", ";25.8.0.0.", 
SvXMLImport::LO_New }
+        { "LibreOffice/25.2.6.2$Linux_X86_64 LibreOffice_project/520$Build-2", 
";25.2.6.2", SvXMLImport::LO_252 },
+        { "LibreOfficeDev/25.8.0.0.alpha0$Linux_X86_64 
LibreOffice_project/308705574842e0c36f7385f73fc47da9a4542367", ";25.8.0.0.", 
SvXMLImport::LO_258 },
+        { "LibreOfficeDev/26.2.0.0.alpha0$Linux_X86_64 
LibreOffice_project/d7e24df067ba6af0043e70750ad2b97e21201fa9", ";26.2.0.0.", 
SvXMLImport::LO_262 },
+        { "LibreOfficeDev/26.8.0.0.alpha0$Linux_X86_64 
LibreOffice_project/d7e24df067ba6af0043e70750ad2b97e21201fa9", ";26.8.0.0.", 
SvXMLImport::LO_New }
     };
 
     for (auto const[pGenerator, pBuildId, nResult] : tests)
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index 3e1c26fced76..36aae86dc200 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -243,6 +243,18 @@ public:
                         {
                             mnGeneratorVersion = SvXMLImport::LO_248;
                         }
+                        else if (25 == year && month == 2)
+                        {
+                            mnGeneratorVersion = SvXMLImport::LO_252;
+                        }
+                        else if (25 == year && month == 8)
+                        {
+                            mnGeneratorVersion = SvXMLImport::LO_258;
+                        }
+                        else if (26 == year && month == 2)
+                        {
+                            mnGeneratorVersion = SvXMLImport::LO_262;
+                        }
                         else if (0 < year)
                         {
                             mnGeneratorVersion = SvXMLImport::LO_New;
diff --git a/xmloff/source/style/adjushdl.cxx b/xmloff/source/style/adjushdl.cxx
index 61878c720504..a37243c5e052 100644
--- a/xmloff/source/style/adjushdl.cxx
+++ b/xmloff/source/style/adjushdl.cxx
@@ -33,8 +33,8 @@ SvXMLEnumMapEntry<style::ParagraphAdjust> const 
pXML_Para_Adjust_Enum[] =
 {
     { XML_LEFT,         style::ParagraphAdjust_LEFT },
     { XML_RIGHT,        style::ParagraphAdjust_RIGHT },
-    { XML_START,        style::ParagraphAdjust_LEFT },
-    { XML_END,          style::ParagraphAdjust_RIGHT },
+    { XML_START,        style::ParagraphAdjust_START },
+    { XML_END,          style::ParagraphAdjust_END },
     { XML_CENTER,       style::ParagraphAdjust_CENTER },
     { XML_JUSTIFY,      style::ParagraphAdjust_BLOCK },
     { XML_JUSTIFIED,    style::ParagraphAdjust_BLOCK }, // obsolete
diff --git a/xmloff/source/style/xmlimppr.cxx b/xmloff/source/style/xmlimppr.cxx
index ef4b2bb24513..5626da2e3c99 100644
--- a/xmloff/source/style/xmlimppr.cxx
+++ b/xmloff/source/style/xmlimppr.cxx
@@ -26,6 +26,7 @@
 #include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
 #include <com/sun/star/beans/XTolerantMultiPropertySet.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
 #include <sal/log.hxx>
 #include <osl/diagnose.h>
 #include <utility>
@@ -231,6 +232,34 @@ void SvXMLImportPropertyMapper::importXMLAttribute(
                     // let the XMLPropertySetMapper decide how to import the 
value
                     bSet = maPropMapper->importXML( sValue, aNewProperty,
                                              rUnitConverter );
+
+                    // tdf#37128: Older versions of LO stored fo:text-align 
incorrectly.
+                    // Remap the buggy values during parsing.
+                    if (bSet
+                        && 
GetImport().isGeneratorVersionOlderThan(SvXMLImport::AOO_4x,
+                                                                   
SvXMLImport::LO_262)
+                        && rAttrName == u"fo:text-align"_ustr)
+                    {
+                        if (sal_Int16 nTmp; aNewProperty.maValue >>= nTmp)
+                        {
+                            css::style::ParagraphAdjust eAdjust{ nTmp };
+                            switch (eAdjust)
+                            {
+                                case css::style::ParagraphAdjust_START:
+                                    eAdjust = css::style::ParagraphAdjust_LEFT;
+                                    break;
+
+                                case css::style::ParagraphAdjust_END:
+                                    eAdjust = 
css::style::ParagraphAdjust_RIGHT;
+                                    break;
+
+                                default:
+                                    break;
+                            }
+
+                            aNewProperty.maValue <<= 
static_cast<sal_Int16>(eAdjust);
+                        }
+                    }
                 }
                 else
                 {

Reply via email to