sw/qa/core/frmedt/frmedt.cxx         |   53 +++++++++++++++++++++++++++++++++++
 sw/source/core/frmedt/fews.cxx       |   16 +++++++++-
 sw/source/uibase/shells/drwbassh.cxx |    3 +
 3 files changed, 70 insertions(+), 2 deletions(-)

New commits:
commit e21bc1b3e587c2bd90168b24f3774d98a3837f8e
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue May 5 18:03:51 2020 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue May 5 21:20:14 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.
    
    Change-Id: Ib6ddccc1512d39fff5bff2e989973b156a6c2bf7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93501
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/frmedt/frmedt.cxx b/sw/qa/core/frmedt/frmedt.cxx
index 807ca494d486..3c6ff01af925 100644
--- a/sw/qa/core/frmedt/frmedt.cxx
+++ b/sw/qa/core/frmedt/frmedt.cxx
@@ -9,6 +9,8 @@
 
 #include <swmodeltestbase.hxx>
 
+#include <com/sun/star/text/VertOrientation.hpp>
+
 #include <svx/svdpage.hxx>
 
 #include <wrtsh.hxx>
@@ -16,6 +18,8 @@
 #include <IDocumentDrawModelAccess.hxx>
 #include <drawdoc.hxx>
 #include <dcontact.hxx>
+#include <frameformats.hxx>
+#include <pagefrm.hxx>
 
 static char const DATA_DIRECTORY[] = "/sw/qa/core/frmedt/data/";
 
@@ -54,6 +58,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 87fb9075644f..4f545ed22649 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 18fce24f2c94..bccbe313bdf9 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -958,7 +958,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()
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to