[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - 7 commits - cui/source include/svx include/xmloff offapi/com schema/libreoffice svx/inc sw/inc sw/qa sw/source writerfilter/source xmloff/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Wed May 6 09:36:19 UTC 2020


 cui/source/tabpages/swpossizetabpage.cxx                           |   11 +-
 include/svx/swframeposstrings.hxx                                  |    1 
 include/xmloff/xmltoken.hxx                                        |    2 
 offapi/com/sun/star/text/RelOrientation.idl                        |    6 +
 schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng        |   11 ++
 svx/inc/swframeposstrings.hrc                                      |    1 
 sw/inc/swrect.hxx                                                  |    3 
 sw/qa/core/frmedt/frmedt.cxx                                       |   54 ++++++++++
 sw/qa/core/objectpositioning/objectpositioning.cxx                 |   33 ++++++
 sw/qa/extras/odfexport/data/page-content-bottom.odt                |binary
 sw/qa/extras/odfexport/odfexport.cxx                               |    7 +
 sw/qa/extras/ooxmlexport/data/page-content-bottom.docx             |binary
 sw/qa/extras/ooxmlexport/ooxmlexport14.cxx                         |   11 ++
 sw/source/core/bastyp/swrect.cxx                                   |   12 ++
 sw/source/core/frmedt/fews.cxx                                     |   16 ++
 sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx |   12 ++
 sw/source/core/text/xmldump.cxx                                    |   23 +---
 sw/source/filter/ww8/docxsdrexport.cxx                             |    3 
 sw/source/uibase/shells/drwbassh.cxx                               |    3 
 writerfilter/source/dmapper/GraphicHelpers.cxx                     |    4 
 xmloff/source/core/xmltoken.cxx                                    |    2 
 xmloff/source/style/xmlexppr.cxx                                   |   13 ++
 xmloff/source/text/txtprhdl.cxx                                    |    2 
 xmloff/source/text/txtprmap.cxx                                    |    6 +
 xmloff/source/token/tokens.txt                                     |    1 
 25 files changed, 215 insertions(+), 22 deletions(-)

New commits:
commit b6969472df1564351f10af94ea373af6e7435aab
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue May 5 18:03:51 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed May 6 11:26:08 2020 +0200

    sw from-bottom relative orientation: fix calculation of position limits
    
    Create a new Writer doc, insert a rectangle with height = 10cm, try to
    position it 2cm above the bottom of the page, so that would be -12cm,
    but we limited the metric field to -2cm because 2cm was the page margin.
    
    Teach SwFEShell::CalcBoundRect() about
    text::RelOrientation::PAGE_PRINT_AREA_BOTTOM, then this will work
    without problems.
    
    (cherry picked from commit e21bc1b3e587c2bd90168b24f3774d98a3837f8e)
    
    Conflicts:
            sw/qa/core/frmedt/frmedt.cxx
    
    Change-Id: Ib6ddccc1512d39fff5bff2e989973b156a6c2bf7

diff --git a/sw/qa/core/frmedt/frmedt.cxx b/sw/qa/core/frmedt/frmedt.cxx
index cf3d1945e049..6c29e647d391 100644
--- a/sw/qa/core/frmedt/frmedt.cxx
+++ b/sw/qa/core/frmedt/frmedt.cxx
@@ -13,6 +13,9 @@
 #include <comphelper/classids.hxx>
 #include <tools/globname.hxx>
 #include <svtools/embedhlp.hxx>
+
+#include <com/sun/star/text/VertOrientation.hpp>
+
 #include <svx/svdpage.hxx>
 
 #include <wrtsh.hxx>
@@ -20,6 +23,8 @@
 #include <IDocumentDrawModelAccess.hxx>
 #include <drawdoc.hxx>
 #include <dcontact.hxx>
+#include <docary.hxx>
+#include <pagefrm.hxx>
 
 static char const DATA_DIRECTORY[] = "/sw/qa/core/frmedt/data/";
 
@@ -58,6 +63,55 @@ CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testTextboxReanchor)
     CPPUNIT_ASSERT_EQUAL(nOldAnchor, nNewAnchor);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testVertPosFromBottomBoundingBox)
+{
+    // Insert a shape and anchor it vertically in a way, so its position is from the top of the page
+    // bottom margin area.
+    mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
+    uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+    uno::Reference<drawing::XShape> xShape(
+        xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
+    xShape->setSize(awt::Size(10000, 10000));
+    uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+    xShapeProps->setPropertyValue("AnchorType",
+                                  uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
+    xShapeProps->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::NONE));
+    xShapeProps->setPropertyValue("VertOrientRelation",
+                                  uno::makeAny(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM));
+    xShapeProps->setPropertyValue("VertOrientPosition",
+                                  uno::makeAny(static_cast<sal_Int32>(-11000)));
+    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+    xDrawPageSupplier->getDrawPage()->add(xShape);
+
+    // Get the absolute position of the top of the page bottom margin area.
+    xmlDocPtr pXmlDoc = parseLayoutDump();
+    SwTwips nPagePrintAreaBottom = getXPath(pXmlDoc, "//page/infos/prtBounds", "bottom").toInt32();
+
+    // Calculate the allowed bounding box of the shape, e.g. the shape's position & size dialog uses
+    // this to limit the vertical position to sensible values.
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
+    SwRect aBoundRect;
+    RndStdIds eAnchorType = RndStdIds::FLY_AT_CHAR;
+    SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+    const auto& rFrameFormats = *pDoc->GetFrameFormats();
+    const SwPosition* pContentPos = rFrameFormats[0]->GetAnchor().GetContentAnchor();
+    sal_Int16 eHoriRelOrient = text::RelOrientation::PAGE_FRAME;
+    sal_Int16 eVertRelOrient = text::RelOrientation::PAGE_PRINT_AREA_BOTTOM;
+    bool bFollowTextFlow = false;
+    bool bMirror = false;
+    Size aPercentSize;
+    pWrtShell->CalcBoundRect(aBoundRect, eAnchorType, eHoriRelOrient, eVertRelOrient, pContentPos,
+                             bFollowTextFlow, bMirror, nullptr, &aPercentSize);
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: -14705
+    // - Actual  : -1134
+    // i.e. UI did not allow anchoring a shape 10cm above the bottom of the page due to wrong
+    // bounding box.
+    CPPUNIT_ASSERT_EQUAL(-1 * nPagePrintAreaBottom, aBoundRect.Pos().getY());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx
index 2f874fd34e24..b20c37d28674 100644
--- a/sw/source/core/frmedt/fews.cxx
+++ b/sw/source/core/frmedt/fews.cxx
@@ -967,7 +967,9 @@ void SwFEShell::CalcBoundRect( SwRect& _orRect,
                 // #i18732# - adjustment vertical 'virtual' anchor position
                 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
                 // to page areas.
-                if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
+                if (_eVertRelOrient == text::RelOrientation::PAGE_FRAME
+                    || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA
+                    || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
                 {
                     if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
                     {
@@ -998,6 +1000,18 @@ void SwFEShell::CalcBoundRect( SwRect& _orRect,
                                 aPos.setY(aPos.getY() + pTmpFrame->getFrameArea().Height());
                             }
                         }
+                        else if (_eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
+                        {
+                            if (rVertEnvironLayFrame.IsPageFrame())
+                            {
+                                auto& rPageFrame = static_cast<const SwPageFrame&>(rVertEnvironLayFrame);
+                                aPos.setY(rPageFrame.PrtWithoutHeaderAndFooter().Bottom());
+                            }
+                            else
+                            {
+                                aPos.AdjustY(rVertEnvironLayFrame.getFramePrintArea().Bottom());
+                            }
+                        }
                     }
                 }
             }
diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx
index 12d87bab691b..d0d4cba2cba8 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -932,7 +932,8 @@ IMPL_LINK(SwDrawBaseShell, ValidatePosition, SvxSwFrameValidation&, rValidation,
         // and alignment at page areas.
         const bool bMaxVPosAtBottom = !rValidation.bFollowTextFlow ||
                                       rValidation.nVRelOrient == text::RelOrientation::PAGE_FRAME ||
-                                      rValidation.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA;
+                                      rValidation.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA ||
+                                      rValidation.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM;
         {
             SwTwips nTmpMaxVPos = ( bMaxVPosAtBottom
                                     ? aBoundRect.Bottom()
commit 1b9c1803f6f42adc23f65ff4182c15192c4b7b92
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue May 5 13:59:16 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed May 6 11:26:02 2020 +0200

    sw from-bottom relative orientation: add UI
    
    And fix the value of LAST: it seems this went wrong in commit
    c2fc91664f71c447209d2cd29c0df1d7faba4927 (Convert LB flags to scoped
    enum, 2016-05-14), where the upper limit went from 0x80000000 to
    0x080000, which means it started to matter if we allow equality or not.
    Other places compare LAST without allowing equality, so leave that
    unchanged and instead give LAST its own value.
    
    Change-Id: I0ceac18475f5f50b792c7a8442648c9ba2a25236
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93477
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 8af2c4e3a517e3b75f2ace9719c1ca03153baddf)

diff --git a/cui/source/tabpages/swpossizetabpage.cxx b/cui/source/tabpages/swpossizetabpage.cxx
index 46a210559892..d4ade3ea4dfc 100644
--- a/cui/source/tabpages/swpossizetabpage.cxx
+++ b/cui/source/tabpages/swpossizetabpage.cxx
@@ -94,10 +94,12 @@ enum class LB {
 // #i22341#
     VertLine            = 0x080000, // vertical text line
 
-    LAST = VertLine
+    RelPagePrintAreaBottom = 0x100000, // bottom of text area of page
+
+    LAST = 0x200000
 };
 namespace o3tl {
-    template<> struct typed_flags<LB> : is_typed_flags<LB, 0x0fffff> {};
+    template<> struct typed_flags<LB> : is_typed_flags<LB, 0x3fffff> {};
 }
 
 static RelationMap const aRelationMap[] =
@@ -110,6 +112,7 @@ static RelationMap const aRelationMap[] =
     {SwFPos::REL_FRM_RIGHT, SwFPos::MIR_REL_FRM_RIGHT, LB::RelFrameRight,   RelOrientation::FRAME_RIGHT},
     {SwFPos::REL_PG_FRAME,  SwFPos::REL_PG_FRAME,      LB::RelPageFrame,    RelOrientation::PAGE_FRAME},
     {SwFPos::REL_PG_PRTAREA,SwFPos::REL_PG_PRTAREA,    LB::RelPagePrintArea,  RelOrientation::PAGE_PRINT_AREA},
+    {SwFPos::REL_PG_PRTAREA_BOTTOM,SwFPos::REL_PG_PRTAREA_BOTTOM,    LB::RelPagePrintAreaBottom,  RelOrientation::PAGE_PRINT_AREA_BOTTOM},
     {SwFPos::REL_CHAR,      SwFPos::REL_CHAR,          LB::RelChar,        RelOrientation::CHAR},
 
     {SwFPos::FLY_REL_PG_LEFT,       SwFPos::FLY_MIR_REL_PG_LEFT,    LB::FlyRelPageLeft,     RelOrientation::PAGE_LEFT},
@@ -257,7 +260,7 @@ static FrmMap const aVParaMap[] =
     {SwFPos::TOP,           SwFPos::TOP,            VertOrientation::TOP,       VERT_PARA_REL},
     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         VertOrientation::BOTTOM,    VERT_PARA_REL},
     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    VertOrientation::CENTER,    VERT_PARA_REL},
-    {SwFPos::FROMTOP,       SwFPos::FROMTOP,        VertOrientation::NONE,      VERT_PARA_REL}
+    {SwFPos::FROMTOP,       SwFPos::FROMTOP,        VertOrientation::NONE,      VERT_PARA_REL|LB::RelPagePrintAreaBottom}
 };
 
 static FrmMap const aVParaHtmlMap[] =
@@ -314,7 +317,7 @@ static FrmMap aVCharMap[] =
     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         VertOrientation::BOTTOM,        VERT_CHAR_REL|LB::RelChar},
     {SwFPos::BELOW,         SwFPos::BELOW,          VertOrientation::CHAR_BOTTOM,   LB::RelChar},
     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    VertOrientation::CENTER,        VERT_CHAR_REL|LB::RelChar},
-    {SwFPos::FROMTOP,       SwFPos::FROMTOP,        VertOrientation::NONE,          VERT_CHAR_REL},
+    {SwFPos::FROMTOP,       SwFPos::FROMTOP,        VertOrientation::NONE,          VERT_CHAR_REL|LB::RelPagePrintAreaBottom},
     {SwFPos::FROMBOTTOM,    SwFPos::FROMBOTTOM,     VertOrientation::NONE,          LB::RelChar|LB::VertLine},
     {SwFPos::TOP,           SwFPos::TOP,            VertOrientation::LINE_TOP,      LB::VertLine},
     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         VertOrientation::LINE_BOTTOM,   LB::VertLine},
diff --git a/include/svx/swframeposstrings.hxx b/include/svx/swframeposstrings.hxx
index c0ef3a3520d0..61d06d459cdf 100644
--- a/include/svx/swframeposstrings.hxx
+++ b/include/svx/swframeposstrings.hxx
@@ -49,6 +49,7 @@ public:
         MIR_REL_FRM_RIGHT          ,
         REL_PG_FRAME               ,
         REL_PG_PRTAREA             ,
+        REL_PG_PRTAREA_BOTTOM      ,
         REL_BASE                   ,
         REL_CHAR                   ,
         REL_ROW                    ,
diff --git a/svx/inc/swframeposstrings.hrc b/svx/inc/swframeposstrings.hrc
index df4d92a976fb..b08a9a3b525b 100644
--- a/svx/inc/swframeposstrings.hrc
+++ b/svx/inc/swframeposstrings.hrc
@@ -43,6 +43,7 @@ const char* RID_SVXSW_FRAMEPOSITIONS[] =
     NC_("RID_SVXSW_FRAMEPOSITIONS", "Outer paragraph border"),
     NC_("RID_SVXSW_FRAMEPOSITIONS", "Entire page"),
     NC_("RID_SVXSW_FRAMEPOSITIONS", "Page text area"),
+    NC_("RID_SVXSW_FRAMEPOSITIONS", "Page text area bottom"),
     NC_("RID_SVXSW_FRAMEPOSITIONS", "Base line"),
     NC_("RID_SVXSW_FRAMEPOSITIONS", "Character"),
     NC_("RID_SVXSW_FRAMEPOSITIONS", "Row"),
commit d29f4857da385db17fe9efd4157c0a021531d0c4
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Apr 29 19:19:37 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed May 6 11:25:55 2020 +0200

    sw from-bottom relative orientation: add DOCX filter
    
    The OOXML equivalent is <wp:positionV relativeFrom="bottomMargin">, and
    the position is typically a negative number (i.e. the position is the
    offset between the top of the shape and the top of the top or bottom
    margin; not the distance and it's always the top of some margin).
    
    (cherry picked from commit fc620901ddd134f644a56ed4ea4a9b5446cc5675)
    
    Conflicts:
            sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
    
    Change-Id: Ia979bc8bfaa37d29b0947c4408335e0a80c05880

diff --git a/sw/qa/extras/ooxmlexport/data/page-content-bottom.docx b/sw/qa/extras/ooxmlexport/data/page-content-bottom.docx
new file mode 100644
index 000000000000..f955586f3916
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/page-content-bottom.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index f96451dda24d..36eb90e7e1c1 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -169,6 +169,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf108350_noFontdefaults, "tdf108350_noFontdefaults
     //CPPUNIT_ASSERT_EQUAL_MESSAGE("Font size", 10.f, getProperty<float>(xStyleProps, "CharHeight"));
 }
 
+DECLARE_OOXMLEXPORT_TEST(testPageContentBottom, "page-content-bottom.docx")
+{
+    uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
+    sal_Int16 nExpected = text::RelOrientation::PAGE_PRINT_AREA_BOTTOM;
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 10 (PAGE_PRINT_AREA_BOTTOM)
+    // - Actual  : 0 (FRAME)
+    // i.e. the bottom-of-body relation was lost.
+    CPPUNIT_ASSERT_EQUAL(nExpected, getProperty<sal_Int16>(xShape, "VertOrientRelation"));
+}
+
 DECLARE_OOXMLIMPORT_TEST(testTdf125038, "tdf125038.docx")
 {
     OUString aActual = getParagraph(1)->getString();
diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx
index 7cacc4eb3173..e9381ca77d0d 100644
--- a/sw/source/filter/ww8/docxsdrexport.cxx
+++ b/sw/source/filter/ww8/docxsdrexport.cxx
@@ -498,6 +498,9 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons
             case text::RelOrientation::PAGE_PRINT_AREA:
                 relativeFromV = "margin";
                 break;
+            case text::RelOrientation::PAGE_PRINT_AREA_BOTTOM:
+                relativeFromV = "bottomMargin";
+                break;
             case text::RelOrientation::PAGE_FRAME:
                 relativeFromV = "page";
                 break;
diff --git a/writerfilter/source/dmapper/GraphicHelpers.cxx b/writerfilter/source/dmapper/GraphicHelpers.cxx
index 9168ad51eebd..7e8564826758 100644
--- a/writerfilter/source/dmapper/GraphicHelpers.cxx
+++ b/writerfilter/source/dmapper/GraphicHelpers.cxx
@@ -75,6 +75,10 @@ void PositionHandler::lcl_attribute( Id aName, Value& rVal )
                         m_nRelation =  text::RelOrientation::PAGE_FRAME;
                         break;
 
+                    case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_bottomMargin:
+                        m_nRelation = text::RelOrientation::PAGE_PRINT_AREA_BOTTOM;
+                        break;
+
                     case NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_paragraph:
                         m_nRelation = text::RelOrientation::FRAME;
                         break;
commit 49f0501f8ba4acd36067a84590469944e9d3234c
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Apr 29 12:31:25 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed May 6 11:25:46 2020 +0200

    sw from-bottom relative orientation: add ODF filter
    
    Map between RelOrientation::PAGE_PRINT_AREA_BOTTOM and
    loext:vertical-rel="page-content-bottom".
    
    Conflicts:
            sw/qa/extras/odfexport/odfexport.cxx
    
    Change-Id: I1d614bf7c82a76285f4268b8008e08c25ef9b7f0

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 1175958548ff..dfc9ad5ced3d 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -3367,6 +3367,8 @@ namespace xmloff { namespace token {
 
         XML_RESOLVED,
 
+        XML_PAGE_CONTENT_BOTTOM,
+
         XML_TOKEN_END
     };
 
diff --git a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
index 69d43e510d44..7b2b04c68a72 100644
--- a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
+++ b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng
@@ -2385,6 +2385,17 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:optional>
   </rng:define>
 
+  <!-- TODO no proposal -->
+  <rng:define name="common-vertical-rel-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:vertical-rel">
+        <rng:choice>
+          <rng:value>page-content-bottom</rng:value>
+        </rng:choice>
+      </rng:attribute>
+    </rng:optional>
+  </rng:define>
+
   <!-- just a test-case for user-defined attributes, move along, nothing to see here... -->
   <rng:define name="style-table-cell-properties-attlist" combine="interleave">
     <rng:optional>
diff --git a/sw/qa/extras/odfexport/data/page-content-bottom.odt b/sw/qa/extras/odfexport/data/page-content-bottom.odt
new file mode 100644
index 000000000000..263ca7df40a1
Binary files /dev/null and b/sw/qa/extras/odfexport/data/page-content-bottom.odt differ
diff --git a/sw/qa/extras/odfexport/odfexport.cxx b/sw/qa/extras/odfexport/odfexport.cxx
index 71631603be81..cd7ec96315f4 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -2328,5 +2328,12 @@ DECLARE_ODFEXPORT_TEST(tdf121658, "tdf121658.odt")
     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xStyle1, "ParaHyphenationNoCaps"));
 }
 
+DECLARE_ODFEXPORT_TEST(testPageContentBottom, "page-content-bottom.odt")
+{
+    uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
+    sal_Int16 nExpected = text::RelOrientation::PAGE_PRINT_AREA_BOTTOM;
+    CPPUNIT_ASSERT_EQUAL(nExpected, getProperty<sal_Int16>(xShape, "VertOrientRelation"));
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index e0f6e4d7a216..b37e90f0b568 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3360,6 +3360,8 @@ namespace xmloff { namespace token {
         // For recording whether comments/annotations are resolved
         TOKEN( "resolved",                        XML_RESOLVED ),
 
+        TOKEN( "page-content-bottom",             XML_PAGE_CONTENT_BOTTOM ),
+
 #if OSL_DEBUG_LEVEL > 0
         { 0, nullptr, nullptr,                       XML_TOKEN_END }
 #else
diff --git a/xmloff/source/style/xmlexppr.cxx b/xmloff/source/style/xmlexppr.cxx
index 76fd72c71deb..cd94fccae8dd 100644
--- a/xmloff/source/style/xmlexppr.cxx
+++ b/xmloff/source/style/xmlexppr.cxx
@@ -1030,10 +1030,10 @@ void SvXMLExportPropertyMapper::_exportXML(
             if( bRemove )
                 rAttrList.RemoveAttribute( sName );
 
+            // We don't seem to have a generic mechanism to write an attribute in the extension
+            // namespace in case of certain attribute values only, so do this manually.
             if (IsXMLToken(mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex), XML_WRITING_MODE))
             {
-                // We don't seem to have a generic mechanism to write an attribute in the extension
-                // namespace in case of certain attribute values only, so do this manually.
                 if (IsXMLToken(aValue, XML_BT_LR))
                 {
                     sName = rNamespaceMap.GetQNameByKey(
@@ -1041,6 +1041,15 @@ void SvXMLExportPropertyMapper::_exportXML(
                             mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex));
                 }
             }
+            else if (IsXMLToken(mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex), XML_VERTICAL_REL))
+            {
+                if (IsXMLToken(aValue, XML_PAGE_CONTENT_BOTTOM))
+                {
+                    sName = rNamespaceMap.GetQNameByKey(
+                            XML_NAMESPACE_LO_EXT,
+                            mpImpl->mxPropMapper->GetEntryXMLName(rProperty.mnIndex));
+                }
+            }
 
             rAttrList.AddAttribute( sName, aValue );
         }
diff --git a/xmloff/source/text/txtprhdl.cxx b/xmloff/source/text/txtprhdl.cxx
index 32644e5f7f1c..13770a7de558 100644
--- a/xmloff/source/text/txtprhdl.cxx
+++ b/xmloff/source/text/txtprhdl.cxx
@@ -153,6 +153,7 @@ static SvXMLEnumMapEntry<sal_uInt16> const pXML_VertRel_Enum[] =
     // DVO, OD 17.09.2003 #i18732# - allow vertical alignment at page
     { XML_PAGE,                 RelOrientation::PAGE_FRAME  },
     { XML_PAGE_CONTENT,         RelOrientation::PAGE_PRINT_AREA },
+    { XML_PAGE_CONTENT_BOTTOM,  RelOrientation::PAGE_PRINT_AREA_BOTTOM },
     { XML_FRAME,                RelOrientation::FRAME   },      // import only
     { XML_FRAME_CONTENT,        RelOrientation::PRINT_AREA  },  // import only
     // OD 13.11.2003 #i22341# - new vertical alignment at top of line
@@ -166,6 +167,7 @@ static SvXMLEnumMapEntry<sal_uInt16> const pXML_VertRelPage_Enum[] =
     { XML_PAGE_CONTENT, RelOrientation::PRINT_AREA  },
     { XML_PAGE,         RelOrientation::PAGE_FRAME  },
     { XML_PAGE_CONTENT, RelOrientation::PAGE_PRINT_AREA },
+    { XML_PAGE_CONTENT_BOTTOM, RelOrientation::PAGE_PRINT_AREA_BOTTOM },
     { XML_TOKEN_INVALID, 0 }
 };
 
diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx
index ebd91ebc3062..e3597b7c6f50 100644
--- a/xmloff/source/text/txtprmap.cxx
+++ b/xmloff/source/text/txtprmap.cxx
@@ -736,6 +736,9 @@ XMLPropertyMapEntry const aXMLFramePropMap[] =
     MG_ED( "VertOrientRelation",        STYLE,  VERTICAL_REL,         XML_TYPE_TEXT_VERTICAL_REL, CTF_VERTICALREL ),
     MG_ED( "VertOrientRelation",        STYLE,  VERTICAL_REL,         XML_TYPE_TEXT_VERTICAL_REL_PAGE|MID_FLAG_SPECIAL_ITEM_IMPORT, CTF_VERTICALREL_PAGE ),
     MG_ED( "VertOrientRelation",        STYLE,  VERTICAL_REL,         XML_TYPE_TEXT_VERTICAL_REL_FRAME|MID_FLAG_SPECIAL_ITEM_IMPORT, CTF_VERTICALREL_FRAME ),
+    MAP_EXT_I( "VertOrientRelation",    XML_NAMESPACE_LO_EXT, XML_VERTICAL_REL, XML_TYPE_TEXT_VERTICAL_REL|XML_TYPE_PROP_GRAPHIC|MID_FLAG_DEFAULT_ITEM_EXPORT, CTF_VERTICALREL ),
+    MAP_EXT_I( "VertOrientRelation",    XML_NAMESPACE_LO_EXT, XML_VERTICAL_REL, XML_TYPE_TEXT_VERTICAL_REL_PAGE|MID_FLAG_SPECIAL_ITEM_IMPORT|XML_TYPE_PROP_GRAPHIC|MID_FLAG_DEFAULT_ITEM_EXPORT, CTF_VERTICALREL_PAGE ),
+    MAP_EXT_I( "VertOrientRelation",    XML_NAMESPACE_LO_EXT, XML_VERTICAL_REL, XML_TYPE_TEXT_VERTICAL_REL_FRAME|MID_FLAG_SPECIAL_ITEM_IMPORT|XML_TYPE_PROP_GRAPHIC|MID_FLAG_DEFAULT_ITEM_EXPORT, CTF_VERTICALREL_FRAME ),
     // RES_HORI_ORIENT
     MG_ED( "HoriOrient",                STYLE,  HORIZONTAL_POS,       XML_TYPE_TEXT_HORIZONTAL_POS|MID_FLAG_MULTI_PROPERTY, CTF_HORIZONTALPOS ),
     MG_ED( "PageToggle",        STYLE,  HORIZONTAL_POS,       XML_TYPE_TEXT_HORIZONTAL_MIRROR, CTF_HORIZONTALMIRROR ),
@@ -901,6 +904,9 @@ XMLPropertyMapEntry const aXMLShapePropMap[] =
     MG_E( "VertOrientRelation", STYLE,  VERTICAL_REL,   XML_TYPE_TEXT_VERTICAL_REL, CTF_SHAPE_VERTICALREL ),
     MG_E( "VertOrientRelation", STYLE,  VERTICAL_REL,   XML_TYPE_TEXT_VERTICAL_REL_PAGE|MID_FLAG_SPECIAL_ITEM_IMPORT, CTF_SHAPE_VERTICALREL_PAGE ),
     MG_E( "VertOrientRelation", STYLE,  VERTICAL_REL,   XML_TYPE_TEXT_VERTICAL_REL_FRAME|MID_FLAG_SPECIAL_ITEM_IMPORT, CTF_SHAPE_VERTICALREL_FRAME ),
+    MAP_EXT_I( "VertOrientRelation",    XML_NAMESPACE_LO_EXT, XML_VERTICAL_REL, XML_TYPE_TEXT_VERTICAL_REL|XML_TYPE_PROP_GRAPHIC, CTF_VERTICALREL ),
+    MAP_EXT_I( "VertOrientRelation",    XML_NAMESPACE_LO_EXT, XML_VERTICAL_REL, XML_TYPE_TEXT_VERTICAL_REL_PAGE|MID_FLAG_SPECIAL_ITEM_IMPORT|XML_TYPE_PROP_GRAPHIC, CTF_VERTICALREL_PAGE ),
+    MAP_EXT_I( "VertOrientRelation",    XML_NAMESPACE_LO_EXT, XML_VERTICAL_REL, XML_TYPE_TEXT_VERTICAL_REL_FRAME|MID_FLAG_SPECIAL_ITEM_IMPORT|XML_TYPE_PROP_GRAPHIC, CTF_VERTICALREL_FRAME ),
     // RES_HORI_ORIENT
     MG_E( "HoriOrient",         STYLE,  HORIZONTAL_POS, XML_TYPE_TEXT_HORIZONTAL_POS|MID_FLAG_MULTI_PROPERTY, CTF_SHAPE_HORIZONTALPOS ),
     MG_E( "PageToggle",         STYLE,  HORIZONTAL_POS, XML_TYPE_TEXT_HORIZONTAL_MIRROR, CTF_SHAPE_HORIZONTALMIRROR ),
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index 921ff2b63b5a..ef2aaca8ea77 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -3127,4 +3127,5 @@ newline
 creator-initials
 transliteration-spellout
 resolved
+page-content-bottom
 TOKEN_END_DUMMY
commit c91584ef805866b46b06fe7451b077f9f33419b4
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Apr 28 17:28:16 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed May 6 11:02:50 2020 +0200

    sw from-bottom relative orientation: add layout
    
    The implementation is a combination of what "bottom" and "from-top"
    already provided.
    
    Change-Id: Id7bac8cbcccbadcca377fe9946a21ccb3e368913
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93086
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit dd52fdba87d0cfee039cc236b86241708d4e63b8)

diff --git a/sw/qa/core/objectpositioning/objectpositioning.cxx b/sw/qa/core/objectpositioning/objectpositioning.cxx
index c73e97567f20..e240f7f84926 100644
--- a/sw/qa/core/objectpositioning/objectpositioning.cxx
+++ b/sw/qa/core/objectpositioning/objectpositioning.cxx
@@ -9,6 +9,8 @@
 
 #include <swmodeltestbase.hxx>
 
+#include <com/sun/star/text/VertOrientation.hpp>
+
 #include <comphelper/classids.hxx>
 #include <svtools/embedhlp.hxx>
 #include <svx/svdpage.hxx>
@@ -48,6 +50,37 @@ CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testOverlapCrash)
     pWrtShell->SplitNode();
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertPosFromBottom)
+{
+    // Create a document, insert a shape and position it 1cm above the bottom of the body area.
+    mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
+    uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+    uno::Reference<drawing::XShape> xShape(
+        xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
+    xShape->setSize(awt::Size(10000, 10000));
+    uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+    xShapeProps->setPropertyValue("AnchorType",
+                                  uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
+    xShapeProps->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::NONE));
+    xShapeProps->setPropertyValue("VertOrientRelation",
+                                  uno::makeAny(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM));
+    xShapeProps->setPropertyValue("VertOrientPosition",
+                                  uno::makeAny(static_cast<sal_Int32>(-11000)));
+    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+    xDrawPageSupplier->getDrawPage()->add(xShape);
+
+    // Verify that the distance between the body and anchored object bottom is indeed around 1cm.
+    xmlDocPtr pXmlDoc = parseLayoutDump();
+    sal_Int32 nBodyBottom = getXPath(pXmlDoc, "//body/infos/bounds", "bottom").toInt32();
+    sal_Int32 nAnchoredBottom
+        = getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds", "bottom").toInt32();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 564
+    // - Actual  : 9035
+    // i.e. the vertical position was from-top, not from-bottom.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(564), nBodyBottom - nAnchoredBottom);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx b/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx
index 18c08f8540d9..9bf3c7bfb6cb 100644
--- a/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx
+++ b/sw/source/core/objectpositioning/tocntntanchoredobjectposition.cxx
@@ -548,6 +548,18 @@ void SwToContentAnchoredObjectPosition::CalcPosition()
                                                 aRectFnSet.GetTop(aPgPrtRect),
                                                 nTopOfOrient );
                 }
+                else if (aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
+                {
+                    // The anchored object is relative from the bottom of the page's print area.
+                    SwRect aPgPrtRect(rPageAlignLayFrame.getFrameArea());
+                    if (rPageAlignLayFrame.IsPageFrame())
+                    {
+                        auto& rPageFrame = static_cast<const SwPageFrame&>(rPageAlignLayFrame);
+                        aPgPrtRect = rPageFrame.PrtWithoutHeaderAndFooter();
+                    }
+                    SwTwips nPageBottom = aRectFnSet.GetBottom(aPgPrtRect);
+                    nVertOffsetToFrameAnchorPos += aRectFnSet.YDiff(nPageBottom, nTopOfOrient);
+                }
                 nRelPosY = nVertOffsetToFrameAnchorPos + aVert.GetPos();
             }
 
commit 9e170a5def6ce48c8273843d13bd5bbb43b802da
Author:     Jan-Marek Glogowski <jan-marek.glogowski at extern.cib.de>
AuthorDate: Thu Mar 5 20:49:55 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed May 6 11:02:50 2020 +0200

    Dump some more layout info as Xml
    
    Change-Id: Ia82d545e4c5d4507899d123eba9d4b2efded992d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90125
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    (cherry picked from commit 36f0a04d3caa176b20dccb10ff0bbcfb5cb8d893)

diff --git a/sw/inc/swrect.hxx b/sw/inc/swrect.hxx
index 69b1f2ad781a..6cde3c3f01e7 100644
--- a/sw/inc/swrect.hxx
+++ b/sw/inc/swrect.hxx
@@ -26,6 +26,7 @@
 #include "swdllapi.h"
 
 class SvStream;
+typedef struct _xmlTextWriter* xmlTextWriterPtr;
 
 /// *Of course* Writer needs its own rectangles.
 /// This is half-open so m_Point.X() + m_Size.getWidth() is *not* included.
@@ -104,7 +105,7 @@ public:
 
     // Output operator for debugging.
     friend SvStream& WriteSwRect( SvStream &rStream, const SwRect &rRect );
-
+    void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
 
     void Top_(      const long nTop );
     void Bottom_(   const long nBottom );
diff --git a/sw/source/core/bastyp/swrect.cxx b/sw/source/core/bastyp/swrect.cxx
index 1d53e6e7a71e..884c155003e2 100644
--- a/sw/source/core/bastyp/swrect.cxx
+++ b/sw/source/core/bastyp/swrect.cxx
@@ -19,6 +19,8 @@
 
 #include <swrect.hxx>
 
+#include <libxml/xmlwriter.h>
+
 #ifdef DBG_UTIL
 #include <tools/stream.hxx>
 #endif
@@ -218,6 +220,16 @@ void SwRect::SetUpperRightCorner(  const Point& rNew )
 void SwRect::SetLowerLeftCorner(  const Point& rNew )
     { m_Point = Point(rNew.X(), rNew.Y() - m_Size.getHeight()); }
 
+void SwRect::dumpAsXmlAttributes(xmlTextWriterPtr writer) const
+{
+    xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("left"), "%li", Left());
+    xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("top"), "%li", Top());
+    xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("width"), "%li", Width());
+    xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("height"), "%li", Height());
+    xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("bottom"), "%li", Bottom());
+    xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("right"), "%li", Right());
+}
+
 #ifdef DBG_UTIL
 SvStream& WriteSwRect(SvStream &rStream, const SwRect &rRect)
 {
diff --git a/sw/source/core/text/xmldump.cxx b/sw/source/core/text/xmldump.cxx
index 20f61111126a..4f3d50eba742 100644
--- a/sw/source/core/text/xmldump.cxx
+++ b/sw/source/core/text/xmldump.cxx
@@ -343,6 +343,12 @@ void SwFrame::dumpAsXml( xmlTextWriterPtr writer ) const
             xmlTextWriterWriteAttribute(writer, BAD_CAST("ValidLayout"), BAD_CAST(OString::boolean(!pPageFrame->IsInvalidLayout()).getStr()));
             xmlTextWriterWriteAttribute(writer, BAD_CAST("ValidContent"), BAD_CAST(OString::boolean(!pPageFrame->IsInvalidContent()).getStr()));
             xmlTextWriterEndElement(writer);
+            xmlTextWriterStartElement(writer, BAD_CAST("page_info"));
+            xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("phyNum"), "%d", pPageFrame->GetPhyPageNum());
+            xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("virtNum"), "%d", pPageFrame->GetVirtPageNum());
+            OUString aFormatName = pPageFrame->GetPageDesc()->GetName();
+            xmlTextWriterWriteFormatAttribute( writer, BAD_CAST("pageDesc"), "%s", BAD_CAST(OUStringToOString(aFormatName, RTL_TEXTENCODING_UTF8).getStr()));
+            xmlTextWriterEndElement(writer);
         }
 
         if (IsTextFrame())
@@ -421,22 +427,16 @@ void SwFrame::dumpInfosAsXml( xmlTextWriterPtr writer ) const
 {
     // output the Frame
     xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", getFrameArea().Left() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", getFrameArea().Top() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", getFrameArea().Width() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", getFrameArea().Height() );
+    getFrameArea().dumpAsXmlAttributes(writer);
     xmlTextWriterWriteAttribute(writer, BAD_CAST("mbFixSize"), BAD_CAST(OString::boolean(HasFixSize()).getStr()));
     xmlTextWriterWriteAttribute(writer, BAD_CAST("mbValidPos"), BAD_CAST(OString::boolean(isFrameAreaPositionValid()).getStr()));
     xmlTextWriterWriteAttribute(writer, BAD_CAST("mbValidSize"), BAD_CAST(OString::boolean(isFrameAreaSizeValid()).getStr()));
     xmlTextWriterWriteAttribute(writer, BAD_CAST("mbValidPrtArea"), BAD_CAST(OString::boolean(isFramePrintAreaValid()).getStr()));
     xmlTextWriterEndElement( writer );
 
-    // output the Prt
+    // output the print area
     xmlTextWriterStartElement( writer, BAD_CAST( "prtBounds" ) );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", getFramePrintArea().Left() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", getFramePrintArea().Top() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", getFramePrintArea().Width() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", getFramePrintArea().Height() );
+    getFramePrintArea().dumpAsXmlAttributes(writer);
     xmlTextWriterEndElement( writer );
 }
 
@@ -515,10 +515,7 @@ void SwAnchoredObject::dumpAsXml( xmlTextWriterPtr writer ) const
     xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
 
     xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", GetObjBoundRect().Left() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", GetObjBoundRect().Top() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", GetObjBoundRect().Width() );
-    xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", GetObjBoundRect().Height() );
+    GetObjBoundRect().dumpAsXmlAttributes(writer);
     xmlTextWriterEndElement( writer );
 
     if (const SdrObject* pObject = GetDrawObj())
commit e00329729e1fd18fa452e91820a81964d5527e6d
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Apr 28 15:04:19 2020 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed May 6 10:13:21 2020 +0200

    sw from-bottom relative orientation: add UNO API
    
    When it comes to vertical positioning of anchored sw objects, one can
    say the position should be "1cm from the top of the page". But measuring
    from the bottom of something was not possible.
    
    Add API for this to help working with documents from Word, which
    supports the feature.
    
    There is no duplicated C++ enum in sw/ for vertical relative
    orientation, so no "doc model" changes are needed for this in sw/.
    
    Change-Id: I3199d3e794bda2f21f92ce3bb7c3c6f04d284db2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93065
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 79107d3f8d10aa0f38641775c5eb47dcfd4fd37e)

diff --git a/offapi/com/sun/star/text/RelOrientation.idl b/offapi/com/sun/star/text/RelOrientation.idl
index adfb094fd593..59f39a045740 100644
--- a/offapi/com/sun/star/text/RelOrientation.idl
+++ b/offapi/com/sun/star/text/RelOrientation.idl
@@ -73,6 +73,12 @@ published constants RelOrientation
          */
         const short TEXT_LINE = 9;
 
+    /** Similar to PAGE_PRINT_AREA, but count from bottom, not from top.
+
+        @since LibreOffice 7.0
+     */
+    const short PAGE_PRINT_AREA_BOTTOM = 10;
+
 };
 
 


More information about the Libreoffice-commits mailing list