[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - 7 commits - sw/inc sw/qa sw/source writerfilter/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Wed Jul 3 09:06:36 UTC 2019


 sw/inc/crsrsh.hxx                                        |    3 
 sw/inc/swrect.hxx                                        |    3 
 sw/qa/extras/layout/data/btlr-cell.odt                   |binary
 sw/qa/extras/layout/layout.cxx                           |  105 +++++++++++++++
 sw/qa/extras/ooxmlexport/ooxmlexport8.cxx                |   12 -
 sw/source/core/crsr/crsrsh.cxx                           |    3 
 sw/source/core/docnode/node.cxx                          |    4 
 sw/source/core/layout/newfrm.cxx                         |    4 
 sw/source/core/layout/ssfrm.cxx                          |    9 -
 sw/source/core/layout/trvlfrm.cxx                        |   15 +-
 sw/source/core/text/inftxt.cxx                           |    2 
 sw/source/core/text/txtfrm.cxx                           |   45 +++++-
 sw/source/filter/ww8/docxattributeoutput.cxx             |   25 ---
 sw/source/uibase/docvw/edtwin.cxx                        |   28 +++-
 sw/source/uibase/inc/edtwin.hxx                          |    5 
 writerfilter/source/dmapper/DomainMapperTableManager.cxx |   15 --
 16 files changed, 203 insertions(+), 75 deletions(-)

New commits:
commit e66492a7ee1e178c9ba1e30392cd49048743c581
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Mar 21 21:05:44 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jul 3 10:54:33 2019 +0200

    tdf#123943 sw btlr writing mode render: fix text portion background
    
    The text frame is swapped in this case, so handle BTLR similar to the
    normal vert (TBRL) case and the background will be positioned correctly
    behind the text portion.
    
    Change-Id: I2399131ef74ea8849577a467ad9bb02d980d8609
    Reviewed-on: https://gerrit.libreoffice.org/69539
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    (cherry picked from commit 4c5d0e4822dcd0c6c9397a45e3afb66d53ebaafc)

diff --git a/sw/qa/extras/layout/data/btlr-cell.odt b/sw/qa/extras/layout/data/btlr-cell.odt
index 17a9c19eef25..a4439218b057 100644
Binary files a/sw/qa/extras/layout/data/btlr-cell.odt and b/sw/qa/extras/layout/data/btlr-cell.odt differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 273f13a91e4c..39984fb26031 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -2767,6 +2767,11 @@ void SwLayoutWriter::testBtlrCell()
     assertXPath(pXmlDoc, "//textarray[1]", "x", "1915");
     assertXPath(pXmlDoc, "//textarray[1]", "y", "2707");
 
+    // Without the accompanying fix in place, this test would have failed with 'Expected: 1979;
+    // Actual  : 2129', i.e. the gray background of the "AAA2." text was too close to the right edge
+    // of the text portion. Now it's exactly behind the text portion.
+    assertXPath(pXmlDoc, "//rect[@top='2159']", "left", "1979");
+
     // Without the accompanying fix in place, this test would have failed with 'Expected: 269;
     // Actual  : 0', i.e. the AAA2 frame was not visible due to 0 width.
     pXmlDoc = parseLayoutDump();
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 6714588fed8f..f2c4a3f2bcf4 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -749,7 +749,7 @@ void SwTextPaintInfo::CalcRect( const SwLinePortion& rPor,
     else
     {
         aPoint.setX( X() );
-        if ( GetTextFrame()->IsVertLR() )
+        if (GetTextFrame()->IsVertLR() && !GetTextFrame()->IsVertLRBT())
             aPoint.setY( Y() - rPor.Height() + rPor.GetAscent() );
         else
             aPoint.setY( Y() - rPor.GetAscent() );
commit 8c448e3713e6f6633fa96d94194634aa23f6da1c
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Mar 13 21:35:42 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jul 3 10:42:45 2019 +0200

    sw btlr writing mode shell: fix cursor selection
    
    All changes are about not assuming logical top is a lower y value than
    logical bottom, by going via the SwRectFnSet abstraction, which already
    does the right thing.
    
    Change-Id: I94a9881b018ad14b02e97425f60af01aa3fd9269
    Reviewed-on: https://gerrit.libreoffice.org/69226
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    (cherry picked from commit 2f83055cdbd915d5036a7b4374b4ad10e6efc65f)

diff --git a/sw/inc/swrect.hxx b/sw/inc/swrect.hxx
index c4b1889ae4ae..a09b38e81a8c 100644
--- a/sw/inc/swrect.hxx
+++ b/sw/inc/swrect.hxx
@@ -23,6 +23,7 @@
 
 #include <sal/log.hxx>
 #include <tools/gen.hxx>
+#include "swdllapi.h"
 
 class SvStream;
 
@@ -30,7 +31,7 @@ class SvStream;
 /// This is half-open so m_Point.X() + m_Size.getWidth() is *not* included.
 /// Note the tools Rectangle is (usually? sometimes?) closed so there's a
 /// SVRect() to subtract 1 for the conversion.
-class SAL_WARN_UNUSED SwRect
+class SAL_WARN_UNUSED SW_DLLPUBLIC SwRect
 {
     Point m_Point;
     Size m_Size;
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 1b43ad464444..273f13a91e4c 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -2844,6 +2844,30 @@ void SwLayoutWriter::testBtlrCell()
     // Without the accompanying fix in place, this test would have failed: character position was 5,
     // i.e. cursor was at the end of the paragraph.
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aPosition.nContent.GetIndex());
+
+    // Test that the selection rectangles are inside the cell frame if we select all the cell
+    // content.
+    SwTwips nCellLeft
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/infos/bounds", "left").toInt32();
+    SwTwips nCellWidth
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/infos/bounds", "width").toInt32();
+    SwTwips nCellTop
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/infos/bounds", "top").toInt32();
+    SwTwips nCellHeight
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/infos/bounds", "height").toInt32();
+    SwRect aCellRect(Point(nCellLeft, nCellTop), Size(nCellWidth, nCellHeight));
+    pWrtShell->SelAll();
+    SwShellCursor* pShellCursor = pWrtShell->getShellCursor(/*bBlock=*/false);
+    CPPUNIT_ASSERT(!pShellCursor->empty());
+    // Without the accompanying fix in place, this test would have failed with:
+    // selection rectangle 269x2573@(1970,2172) is not inside cell rectangle 3207x1134@(1593,1701)
+    // i.e. the selection went past the bottom border of the cell frame.
+    for (const auto& rRect : *pShellCursor)
+    {
+        std::stringstream ss;
+        ss << "selection rectangle " << rRect << " is not inside cell rectangle " << aCellRect;
+        CPPUNIT_ASSERT_MESSAGE(ss.str(), aCellRect.IsInside(rRect));
+    }
 #endif
 }
 
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index 46cf019acbc4..e1c8ec770646 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -680,14 +680,15 @@ const SwRect SwFrame::UnionFrame( bool bBorder ) const
     long nWidth = (getFrameArea().*fnRect->fnGetWidth)();
     long nPrtLeft = (getFramePrintArea().*fnRect->fnGetLeft)();
     long nPrtWidth = (getFramePrintArea().*fnRect->fnGetWidth)();
-    if( nPrtLeft + nPrtWidth > nWidth )
+    SwRectFnSet aRectFnSet(this);
+    if (aRectFnSet.XInc(nPrtLeft, nPrtWidth) > nWidth)
         nWidth = nPrtLeft + nPrtWidth;
     if( nPrtLeft < 0 )
     {
         nLeft += nPrtLeft;
         nWidth -= nPrtLeft;
     }
-    SwTwips nRight = nLeft + nWidth;
+    SwTwips nRight = aRectFnSet.XInc(nLeft, nWidth);
     long nAdd = 0;
     if( bBorder )
     {
@@ -715,9 +716,9 @@ const SwRect SwFrame::UnionFrame( bool bBorder ) const
         if( nTmp > nAdd )
             nAdd = nTmp;
     }
-    nWidth = nRight + nAdd - nLeft;
+    nWidth = aRectFnSet.XDiff(aRectFnSet.XInc(nRight, nAdd), nLeft);
     SwRect aRet( getFrameArea() );
-    (aRet.*fnRect->fnSetPosX)( nLeft );
+    (aRet.*fnRect->fnSetLeft)(nLeft);
     (aRet.*fnRect->fnSetWidth)( nWidth );
     return aRet;
 }
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index c511253b6bb1..f564f040552e 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -2139,6 +2139,7 @@ void SwRootFrame::CalcFrameRects(SwShellCursor &rCursor)
     SwRectFnSet aRectFnSet(pStartFrame);
     const bool bR2L = pStartFrame->IsRightToLeft();
     const bool bEndR2L = pEndFrame->IsRightToLeft();
+    const bool bB2T = pStartFrame->IsVertLRBT();
 
     // If there's no doubleline portion involved or start and end are both
     // in the same doubleline portion, all works fine, but otherwise
@@ -2371,7 +2372,7 @@ void SwRootFrame::CalcFrameRects(SwShellCursor &rCursor)
         {
             Point aTmpSt( aStRect.Pos() );
             Point aTmpEnd( aEndRect.Right(), aEndRect.Bottom() );
-            if( bSameRotatedOrBidi || bR2L )
+            if (bSameRotatedOrBidi || bR2L || bB2T)
             {
                 if( aTmpSt.Y() > aTmpEnd.Y() )
                 {
commit 1f5830deb273e3d8e5c554e5f04a07b7c8cfa199
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Mar 7 21:39:14 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jul 3 10:42:19 2019 +0200

    sw btlr writing mode shell: left/right cursor travelling, fix vert pos
    
    By implementing BTLR support in
    SwTextFrame::SwitchVerticalToHorizontal() (Point version).
    
    Cursor traveling now looks good: all of up/down/left/right direction
    have the correct paragraph and character position for all the lrtb, tbrl
    and btlr cases.
    
    As a side effect this also fixes mouse click, where clicking above the
    paragraph positioned the cursor at the bottom of the paragraph.
    
    Explicitly add a test for the mouse case as well, given that I initially
    planned to fix the keyboard part directly in SwCursor::UpDown(), where
    the keyboard test would pass, but not the mouse one.
    
    Change-Id: Iabeded3f03a64416cfcaf58e0438c4a1a793e662
    Reviewed-on: https://gerrit.libreoffice.org/68886
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    (cherry picked from commit 404bfc6f78549d16de193794960a9c9ab7604511)

diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 9ffc60de0b10..1b43ad464444 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -2792,6 +2792,9 @@ void SwLayoutWriter::testBtlrCell()
     CPPUNIT_ASSERT_GREATER(nFirstParaMiddle, rCharRect.Top());
     CPPUNIT_ASSERT_LESS(nFirstParaBottom, rCharRect.Top());
 
+    // Save initial cursor position.
+    SwPosition aCellStart = *pWrtShell->GetCursor()->Start();
+
     // Test that pressing "up" at the start of the cell goes to the next character position.
     sal_uLong nNodeIndex = pWrtShell->GetCursor()->Start()->nNode.GetIndex();
     sal_Int32 nIndex = pWrtShell->GetCursor()->Start()->nContent.GetIndex();
@@ -2804,12 +2807,43 @@ void SwLayoutWriter::testBtlrCell()
     CPPUNIT_ASSERT_EQUAL(nIndex + 1, pWrtShell->GetCursor()->Start()->nContent.GetIndex());
 
     // Test that pressing "right" goes to the next paragraph (logical "down").
+    sal_Int32 nContentIndex = pWrtShell->GetCursor()->Start()->nContent.GetIndex();
     aKeyEvent = KeyEvent(0, KEY_RIGHT);
     rEditWin.KeyInput(aKeyEvent);
     Scheduler::ProcessEventsToIdle();
     // Without the accompanying fix in place, this test would have failed: the cursor went to the
     // paragraph after the table.
     CPPUNIT_ASSERT_EQUAL(nNodeIndex + 1, pWrtShell->GetCursor()->Start()->nNode.GetIndex());
+
+    // Test that we have the correct character index after traveling to the next paragraph.
+    // Without the accompanying fix in place, this test would have failed: char position was 5, i.e.
+    // the cursor jumped to the end of the paragraph for no reason.
+    CPPUNIT_ASSERT_EQUAL(nContentIndex, pWrtShell->GetCursor()->Start()->nContent.GetIndex());
+
+    // Test that clicking "below" the second paragraph positions the cursor at the start of the
+    // second paragraph.
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    SwPosition aPosition(aCellStart);
+    SwTwips nSecondParaLeft
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt[2]/infos/bounds", "left")
+              .toInt32();
+    SwTwips nSecondParaWidth
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt[2]/infos/bounds", "width")
+              .toInt32();
+    SwTwips nSecondParaTop
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt[2]/infos/bounds", "top").toInt32();
+    SwTwips nSecondParaHeight
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt[2]/infos/bounds", "height")
+              .toInt32();
+    Point aPoint;
+    aPoint.setX(nSecondParaLeft + nSecondParaWidth / 2);
+    aPoint.setY(nSecondParaTop + nSecondParaHeight - 100);
+    SwCursorMoveState aState(MV_NONE);
+    pLayout->GetCursorOfst(&aPosition, aPoint, &aState);
+    CPPUNIT_ASSERT_EQUAL(aCellStart.nNode.GetIndex() + 1, aPosition.nNode.GetIndex());
+    // Without the accompanying fix in place, this test would have failed: character position was 5,
+    // i.e. cursor was at the end of the paragraph.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aPosition.nContent.GetIndex());
 #endif
 }
 
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 430a9804877a..847d49a0bc1c 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -617,16 +617,29 @@ void SwTextFrame::SwitchVerticalToHorizontal( Point& rPoint ) const
 
     // calc offset inside frame
     if ( IsVertLR() )
+        // X offset is Y - left.
         nOfstX = rPoint.X() - getFrameArea().Left();
     else
     {
+        // X offset is right - X.
         if ( mbIsSwapped )
             nOfstX = getFrameArea().Left() + getFrameArea().Height() - rPoint.X();
         else
             nOfstX = getFrameArea().Left() + getFrameArea().Width() - rPoint.X();
     }
 
-    const long nOfstY = rPoint.Y() - getFrameArea().Top();
+    long nOfstY;
+    if (IsVertLRBT())
+    {
+        // Y offset is bottom - Y.
+        if (mbIsSwapped)
+            nOfstY = getFrameArea().Top() + getFrameArea().Width() - rPoint.Y();
+        else
+            nOfstY = getFrameArea().Top() + getFrameArea().Height() - rPoint.Y();
+    }
+    else
+        // Y offset is Y - top.
+        nOfstY = rPoint.Y() - getFrameArea().Top();
 
     // calc rotated coords
     rPoint.setX( getFrameArea().Left() + nOfstY );
commit a05baff73b8bbce136cf012cbdf7c7fd9dc9e715
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Wed Feb 27 21:31:06 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jul 3 10:41:02 2019 +0200

    sw btlr writing mode shell: left/right cursor travelling, fix dest para
    
    Fix aVerticalLeftToRightBottomToTop:
    
    - fnXDiff takes "logically larger, logically smaller" arguments, so it's
      first - second for top to bottom text (existing directions) but it's
      second - first for btlr
    
    - fnXInc was effectively unused before, but it probably meant to provide
      logical left + width, so set that to physical left - width for btlr
    
    And then port 3 places in lcl_UpDown() to use aRectFnSet, so we get
    correct behavior for both ttb and btt directions.
    
    With this, pressing the left/right arrow jumps to the previous / next
    paragraph correctly.
    
    Change-Id: I1323e95e2ce0ab2d66a3ea6e02bd50df2cebf232
    Reviewed-on: https://gerrit.libreoffice.org/68462
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    (cherry picked from commit 8ae5a98852c2f3d87d6efff598f0c7d54df835d3)

diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 21fd97a8dfa1..9ffc60de0b10 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -2793,6 +2793,7 @@ void SwLayoutWriter::testBtlrCell()
     CPPUNIT_ASSERT_LESS(nFirstParaBottom, rCharRect.Top());
 
     // Test that pressing "up" at the start of the cell goes to the next character position.
+    sal_uLong nNodeIndex = pWrtShell->GetCursor()->Start()->nNode.GetIndex();
     sal_Int32 nIndex = pWrtShell->GetCursor()->Start()->nContent.GetIndex();
     KeyEvent aKeyEvent(0, KEY_UP);
     SwEditWin& rEditWin = pShell->GetView()->GetEditWin();
@@ -2801,6 +2802,14 @@ void SwLayoutWriter::testBtlrCell()
     // Without the accompanying fix in place, this test would have failed: "up" was interpreted as
     // logical "left", which does nothing if you're at the start of the text anyway.
     CPPUNIT_ASSERT_EQUAL(nIndex + 1, pWrtShell->GetCursor()->Start()->nContent.GetIndex());
+
+    // Test that pressing "right" goes to the next paragraph (logical "down").
+    aKeyEvent = KeyEvent(0, KEY_RIGHT);
+    rEditWin.KeyInput(aKeyEvent);
+    Scheduler::ProcessEventsToIdle();
+    // Without the accompanying fix in place, this test would have failed: the cursor went to the
+    // paragraph after the table.
+    CPPUNIT_ASSERT_EQUAL(nNodeIndex + 1, pWrtShell->GetCursor()->Start()->nNode.GetIndex());
 #endif
 }
 
diff --git a/sw/source/core/layout/newfrm.cxx b/sw/source/core/layout/newfrm.cxx
index 94e016434e47..bfaf62657091 100644
--- a/sw/source/core/layout/newfrm.cxx
+++ b/sw/source/core/layout/newfrm.cxx
@@ -275,9 +275,9 @@ static SwRectFnCollection aVerticalLeftToRightBottomToTop = {
 
     /*.fnSetPos =*/&SwRect::SetLowerLeftCorner,
     /*.fnMakePos =*/&SwFrame::MakeRightPos,
-    /*.fnXDiff =*/&FirstMinusSecond,
+    /*.fnXDiff =*/&SecondMinusFirst,
     /*.fnYDiff =*/&FirstMinusSecond,
-    /*.fnXInc =*/&SwIncrement,
+    /*.fnXInc =*/&SwDecrement,
     /*.fnYInc =*/&SwIncrement,
 
     /*.fnSetLeftAndWidth =*/&SwRect::SetBottomAndHeight,
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 584b74c5f98e..c511253b6bb1 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -757,8 +757,8 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
             while ( pCell && !pCell->IsCellFrame() )
                 pCell = pCell->GetUpper();
             OSL_ENSURE( pCell, "could not find the cell" );
-            nX =  aRectFnSet.GetLeft(pCell->getFrameArea()) +
-                  aRectFnSet.GetWidth(pCell->getFrameArea()) / 2;
+            nX = aRectFnSet.XInc(aRectFnSet.GetLeft(pCell->getFrameArea()),
+                                 aRectFnSet.GetWidth(pCell->getFrameArea()) / 2);
 
             //The flow leads from one table to the next. The X-value needs to be
             //corrected based on the middle of the starting cell by the amount
@@ -778,14 +778,14 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
             const long nPrtLeft = bRTL ?
                                 aRectFnSet.GetPrtRight(*pTable) :
                                 aRectFnSet.GetPrtLeft(*pTable);
-            if ( bRTL != (nX < nPrtLeft) )
+            if (bRTL != (aRectFnSet.XDiff(nPrtLeft, nX) > 0))
                 nX = nPrtLeft;
             else
             {
                    const long nPrtRight = bRTL ?
                                     aRectFnSet.GetPrtLeft(*pTable) :
                                     aRectFnSet.GetPrtRight(*pTable);
-                if ( bRTL != (nX > nPrtRight) )
+                if (bRTL != (aRectFnSet.XDiff(nX, nPrtRight) > 0))
                     nX = nPrtRight;
             }
         }
@@ -884,7 +884,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
                         if ( aRectFnSet.IsVert() )
                         {
                             if ( nTmpTop )
-                                --nTmpTop;
+                                nTmpTop = aRectFnSet.XInc(nTmpTop, -1);
 
                             aInsideCell = Point( nTmpTop, nX );
                         }
@@ -896,7 +896,7 @@ static bool lcl_UpDown( SwPaM *pPam, const SwContentFrame *pStart,
                     if ( aRectFnSet.IsVert() )
                     {
                         if ( nTmpTop )
-                            --nTmpTop;
+                            nTmpTop = aRectFnSet.XInc(nTmpTop, -1);
 
                         aInsideCnt = Point( nTmpTop, nX );
                     }
commit 2b224c441dba93934a9f4f81aa6f8faf378b5bbd
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Feb 21 21:22:15 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jul 3 10:34:27 2019 +0200

    sw btlr writing mode shell: fix up/down cursor travelling
    
    By teaching SwEditWin::KeyInput() about 2 vertical modes: the existing
    tbrl one and the new btlr one. Up now correctly goes to the next
    character and down to the previous one.
    
    Change-Id: I71faebe62e5fa3892b37e8bea6c15d1fb84df5d1
    Reviewed-on: https://gerrit.libreoffice.org/68183
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 31f896bb6ef922cf4250c6b971fb9d24a60592b5)

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index c76be980179d..b258d6d4af14 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -258,8 +258,6 @@ private:
     SAL_DLLPRIVATE bool LRMargin( bool, bool bAPI = false );
     SAL_DLLPRIVATE bool IsAtLRMargin( bool, bool bAPI = false ) const;
 
-    SAL_DLLPRIVATE SvxFrameDirection GetTextDirection( const Point* pPt = nullptr ) const;
-
     SAL_DLLPRIVATE bool isInHiddenTextFrame(SwShellCursor* pShellCursor);
 
     SAL_DLLPRIVATE bool GoStartWordImpl();
@@ -811,6 +809,7 @@ public:
     const SwRangeRedline* SelPrevRedline();
     const SwRangeRedline* GotoRedline( SwRedlineTable::size_type nArrPos, bool bSelect );
 
+    SAL_DLLPRIVATE SvxFrameDirection GetTextDirection( const Point* pPt = nullptr ) const;
     // is cursor or the point in/over a vertical formatted text?
     bool IsInVerticalText( const Point* pPt = nullptr ) const;
     // is cursor or the point in/over a right to left formatted text?
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index f59d867b0c38..21fd97a8dfa1 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -15,10 +15,13 @@
 #include <officecfg/Office/Common.hxx>
 #include <comphelper/scopeguard.hxx>
 #include <unotools/syslocaleoptions.hxx>
+#include <vcl/scheduler.hxx>
 #include <fmtanchr.hxx>
 #include <fmtfsize.hxx>
 #include <fmtcntnt.hxx>
 #include <wrtsh.hxx>
+#include <edtwin.hxx>
+#include <view.hxx>
 
 static char const DATA_DIRECTORY[] = "/sw/qa/extras/layout/data/";
 
@@ -2788,6 +2791,16 @@ void SwLayoutWriter::testBtlrCell()
     // range was 2273 -> 2835, the good vertical position is 2730, the bad one was 1830.
     CPPUNIT_ASSERT_GREATER(nFirstParaMiddle, rCharRect.Top());
     CPPUNIT_ASSERT_LESS(nFirstParaBottom, rCharRect.Top());
+
+    // Test that pressing "up" at the start of the cell goes to the next character position.
+    sal_Int32 nIndex = pWrtShell->GetCursor()->Start()->nContent.GetIndex();
+    KeyEvent aKeyEvent(0, KEY_UP);
+    SwEditWin& rEditWin = pShell->GetView()->GetEditWin();
+    rEditWin.KeyInput(aKeyEvent);
+    Scheduler::ProcessEventsToIdle();
+    // Without the accompanying fix in place, this test would have failed: "up" was interpreted as
+    // logical "left", which does nothing if you're at the start of the text anyway.
+    CPPUNIT_ASSERT_EQUAL(nIndex + 1, pWrtShell->GetCursor()->Start()->nContent.GetIndex());
 #endif
 }
 
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 696eb41c73c8..c655f9e85a34 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -3276,7 +3276,8 @@ SvxFrameDirection SwCursorShell::GetTextDirection( const Point* pPt ) const
 bool SwCursorShell::IsInVerticalText( const Point* pPt ) const
 {
     const SvxFrameDirection nDir = GetTextDirection( pPt );
-    return SvxFrameDirection::Vertical_RL_TB == nDir || SvxFrameDirection::Vertical_LR_TB == nDir;
+    return SvxFrameDirection::Vertical_RL_TB == nDir || SvxFrameDirection::Vertical_LR_TB == nDir
+           || nDir == SvxFrameDirection::Vertical_LR_BT;
 }
 
 bool SwCursorShell::IsInRightToLeftText() const
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index 19cafd55a313..b0027fdd288e 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1993,7 +1993,9 @@ SvxFrameDirection SwContentNode::GetTextDirection( const SwPosition& rPos,
     {
         if ( pFrame->IsVertical() )
         {
-            if ( pFrame->IsRightToLeft() )
+            if (pFrame->IsVertLRBT())
+                nRet = SvxFrameDirection::Vertical_LR_BT;
+            else if (pFrame->IsRightToLeft())
                 nRet = SvxFrameDirection::Vertical_LR_TB;
             else
                 nRet = SvxFrameDirection::Vertical_RL_TB;
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index cb6b59b8736d..f34d310c9242 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -1453,12 +1453,28 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt)
             if( ( bVertText && ( !bTableCursor || bVertTable ) ) ||
                 ( bTableCursor && bVertTable ) )
             {
-                // Attempt to integrate cursor travelling for mongolian layout does not work.
-                // Thus, back to previous mapping of cursor keys to direction keys.
-                if( KEY_UP == nKey ) nKey = KEY_LEFT;
-                else if( KEY_DOWN == nKey ) nKey = KEY_RIGHT;
-                else if( KEY_LEFT == nKey ) nKey = KEY_DOWN;
-                else /* KEY_RIGHT == nKey */ nKey = KEY_UP;
+                SvxFrameDirection eDirection = rSh.GetTextDirection();
+                if (eDirection == SvxFrameDirection::Vertical_LR_BT)
+                {
+                    // Map from physical to logical, so rotate clockwise.
+                    if (KEY_UP == nKey)
+                        nKey = KEY_RIGHT;
+                    else if (KEY_DOWN == nKey)
+                        nKey = KEY_LEFT;
+                    else if (KEY_LEFT == nKey)
+                        nKey = KEY_UP;
+                    else /* KEY_RIGHT == nKey */
+                        nKey = KEY_DOWN;
+                }
+                else
+                {
+                    // Attempt to integrate cursor travelling for mongolian layout does not work.
+                    // Thus, back to previous mapping of cursor keys to direction keys.
+                    if( KEY_UP == nKey ) nKey = KEY_LEFT;
+                    else if( KEY_DOWN == nKey ) nKey = KEY_RIGHT;
+                    else if( KEY_LEFT == nKey ) nKey = KEY_DOWN;
+                    else /* KEY_RIGHT == nKey */ nKey = KEY_UP;
+                }
             }
 
             if ( rSh.IsInRightToLeftText() )
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index 0f63aa229884..abb7f4cd68a4 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -56,12 +56,13 @@ enum class SdrHitKind;
     To translate the pixel positions from the buffer OutputDevice to the real
     pixel positions, use the PixelToLogic methods of this class.
   */
-class SwEditWin final : public vcl::Window,
+class SW_DLLPUBLIC SwEditWin final : public vcl::Window,
                 public DropTargetHelper, public DragSourceHelper
 {
     static  QuickHelpData* m_pQuickHlpData;
 
-    static  long    m_nDDStartPosX, m_nDDStartPosY;
+    static  long    m_nDDStartPosX;
+    static  long    m_nDDStartPosY;
 
     Color m_aWaterCanTextColor;     // text color; for the watering can
     Color m_aWaterCanTextBackColor; // text background; for the watering can
commit 16c6c90b5be29052589df3cc537865795bec04ec
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Feb 15 16:52:20 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jul 3 10:34:00 2019 +0200

    sw btlr writing mode shell: fix cursor position
    
    By implementing the SwRect variant of
    SwTextFrame::SwitchHorizontalToVertical() for the IsVertLRBT() == true
    case.
    
    The blinking cursor position after doc load is now correct.
    
    Change-Id: I4862a6de286d3c0a34235fa0be8be2746b1a4151
    Reviewed-on: https://gerrit.libreoffice.org/67880
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit 61bb90aac5038b5ff051668f7ae86eb61658e4f3)

diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index c70b0d13d9da..f59d867b0c38 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -2768,6 +2768,26 @@ void SwLayoutWriter::testBtlrCell()
     // Actual  : 0', i.e. the AAA2 frame was not visible due to 0 width.
     pXmlDoc = parseLayoutDump();
     assertXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt[2]/infos/bounds", "width", "269");
+
+    // Test the position of the cursor after doc load.
+    // We expect that it's inside the first text frame in the first cell.
+    // More precisely, this is a bottom to top vertical frame, so we expect it's at the start, which
+    // means it's at the lower half of the text frame rectangle (vertically).
+    SwWrtShell* pWrtShell = pShell->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell);
+
+    const SwRect& rCharRect = pWrtShell->GetCharRect();
+    SwTwips nFirstParaTop
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt[1]/infos/bounds", "top").toInt32();
+    SwTwips nFirstParaHeight
+        = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt[1]/infos/bounds", "height")
+              .toInt32();
+    SwTwips nFirstParaMiddle = nFirstParaTop + nFirstParaHeight / 2;
+    SwTwips nFirstParaBottom = nFirstParaTop + nFirstParaHeight;
+    // Without the accompanying fix in place, this test would have failed: the lower half (vertical)
+    // range was 2273 -> 2835, the good vertical position is 2730, the bad one was 1830.
+    CPPUNIT_ASSERT_GREATER(nFirstParaMiddle, rCharRect.Top());
+    CPPUNIT_ASSERT_LESS(nFirstParaBottom, rCharRect.Top());
 #endif
 }
 
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index f02eed653ba5..430a9804877a 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -478,8 +478,18 @@ void SwTextFrame::SwitchHorizontalToVertical( SwRect& rRect ) const
     long nOfstX, nOfstY;
     if ( IsVertLR() )
     {
-        nOfstX = rRect.Left() - getFrameArea().Left();
-        nOfstY = rRect.Top() - getFrameArea().Top();
+        if (IsVertLRBT())
+        {
+            // X and Y offsets here mean the position of the point that will be the top left corner
+            // after the switch.
+            nOfstX = rRect.Left() + rRect.Width() - getFrameArea().Left();
+            nOfstY = rRect.Top() - getFrameArea().Top();
+        }
+        else
+        {
+            nOfstX = rRect.Left() - getFrameArea().Left();
+            nOfstY = rRect.Top() - getFrameArea().Top();
+        }
     }
     else
     {
@@ -491,7 +501,12 @@ void SwTextFrame::SwitchHorizontalToVertical( SwRect& rRect ) const
     const long nHeight = rRect.Height();
 
     if ( IsVertLR() )
-        rRect.Left(getFrameArea().Left() + nOfstY);
+    {
+        if (IsVertLRBT())
+            rRect.Left(getFrameArea().Left() + nOfstY);
+        else
+            rRect.Left(getFrameArea().Left() + nOfstY);
+    }
     else
     {
         if ( mbIsSwapped )
@@ -501,7 +516,14 @@ void SwTextFrame::SwitchHorizontalToVertical( SwRect& rRect ) const
             rRect.Left( getFrameArea().Left() + getFrameArea().Width() - nOfstY );
     }
 
-    rRect.Top( getFrameArea().Top() + nOfstX );
+    if (IsVertLRBT())
+    {
+        SAL_WARN_IF(!mbIsSwapped, "sw.core",
+                    "SwTextFrame::SwitchHorizontalToVertical, IsVertLRBT, not swapped");
+        rRect.Top(getFrameArea().Top() + getFrameArea().Width() - nOfstX);
+    }
+    else
+        rRect.Top(getFrameArea().Top() + nOfstX);
     rRect.Width( nHeight );
     rRect.Height( nWidth );
 }
commit 9e47f03e1241f35972c01e9cad6ec6accb4a6bf2
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Feb 15 14:06:15 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jul 3 10:33:15 2019 +0200

    sw btlr writing mode: implement DOCX filter
    
    Replace the old trick with character-level rotation with the usage of
    the new writing direction.
    
    This means that finally table cells with btlr text direction and
    multiple paragraphs show all content, not only the first paragraph, as
    before (seen as data loss by users).
    
    (cherry picked from commit 8fdbda18b593e7014e44a0fd590bbf98d83258b7)
    
    Conflicts:
            writerfilter/source/dmapper/DomainMapperTableManager.cxx
    
    Change-Id: I094f36fa6ba0701579e487e8e0212707987b1b2f

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
index feb99c340d85..b0bd7bf349c5 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx
@@ -775,9 +775,8 @@ DECLARE_OOXMLEXPORT_TEST(testTbLrHeight, "tblr-height.docx")
     uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
     uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
-    uno::Reference<table::XTableRows> xTableRows(xTable->getRows(), uno::UNO_QUERY);
-    // btLr text direction was imported as MIN, it should be FIX to avoid incorrectly large height in case of too much content.
-    CPPUNIT_ASSERT_EQUAL(text::SizeType::FIX, getProperty<sal_Int16>(xTableRows->getByIndex(0), "SizeType"));
+    uno::Reference<table::XCell> xCell = xTable->getCellByName("B1");
+    CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR, getProperty<sal_Int16>(xCell, "WritingMode"));
 }
 
 DECLARE_OOXMLEXPORT_TEST(testBnc865381, "bnc865381.docx")
@@ -785,11 +784,8 @@ DECLARE_OOXMLEXPORT_TEST(testBnc865381, "bnc865381.docx")
     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
     uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
-    uno::Reference<table::XTableRows> xTableRows(xTextTable->getRows(), uno::UNO_QUERY);
-    // Second row has a vertically merged cell, make sure size type is not FIX in that case (otherwise B2 is not readable).
-    CPPUNIT_ASSERT(text::SizeType::FIX != getProperty<sal_Int16>(xTableRows->getByIndex(1), "SizeType"));
-    // Explicit size of 41 mm100 was set, so the vertical text in A2 was not readable.
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTableRows->getByIndex(1), "Height"));
+    uno::Reference<table::XCell> xCell = xTextTable->getCellByName("A2");
+    CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR, getProperty<sal_Int16>(xCell, "WritingMode"));
 }
 
 DECLARE_OOXMLEXPORT_TEST(testFdo53985, "fdo53985.docx")
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 8fcc14b6d8b9..b20a2a37949b 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -4320,28 +4320,11 @@ void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer
         m_pSerializer->singleElementNS( XML_w, XML_textDirection,
                FSNS( XML_w, XML_val ), "tbRl",
                FSEND );
-    else if ( SvxFrameDirection::Horizontal_LR_TB == m_rExport.TrueFrameDirection( *pFrameFormat ) )
+    else if ( SvxFrameDirection::Vertical_LR_BT == m_rExport.TrueFrameDirection( *pFrameFormat ) )
     {
-        // Undo the text direction mangling done by the btLr handler in writerfilter::dmapper::DomainMapperTableManager::sprm()
-        const SwStartNode* pSttNd = pTabBox->GetSttNd();
-        if (pSttNd)
-        {
-            SwPaM aPam(*pSttNd, 0);
-            ++aPam.GetPoint()->nNode;
-            if (aPam.GetPoint()->nNode.GetNode().IsTextNode())
-            {
-                const SwTextNode& rTextNode = static_cast<const SwTextNode&>(aPam.GetPoint()->nNode.GetNode());
-                if( const SwAttrSet* pAttrSet = rTextNode.GetpSwAttrSet())
-                {
-                    const SvxCharRotateItem& rCharRotate = pAttrSet->GetCharRotate();
-                    if (rCharRotate.GetValue() == 900)
-                    {
-                        m_pSerializer->singleElementNS( XML_w, XML_textDirection, FSNS( XML_w, XML_val ), "btLr", FSEND );
-                        m_bBtLr = true;
-                    }
-                }
-            }
-        }
+        m_pSerializer->singleElementNS( XML_w, XML_textDirection,
+               FSNS( XML_w, XML_val ), "btLr",
+               FSEND );
     }
 
     const SwWriteTableRows& rRows = m_xTableWrt->GetRows( );
diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.cxx b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
index b698fabe0c44..f7538768360f 100644
--- a/writerfilter/source/dmapper/DomainMapperTableManager.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableManager.cxx
@@ -298,20 +298,7 @@ bool DomainMapperTableManager::sprm(Sprm & rSprm)
                         SAL_INFO( "writerfilter", "Have inserted textDirection " << nIntValue );
                         break;
                     case NS_ooxml::LN_Value_ST_TextDirection_btLr:
-                        {
-                        // We have to fake this text direction
-                         pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::LR_TB ));
-                         pPropMap->Insert( PROP_CHAR_ROTATION, uno::makeAny( sal_Int16( 900 ) ));
-                        SAL_INFO( "writerfilter", "Have inserted textDirection " << nIntValue );
-
-                        // We're faking a text direction, so don't allow multiple lines.
-                        if (!getCellProps() || !getCellProps()->isSet(PROP_VERTICAL_MERGE))
-                        {
-                            // Though in case there will be a vertical merge, don't do this, it hides text that is supposed to be visible.
-                            m_bRowSizeTypeInserted = true;
-                        }
-                        m_bHasBtlrCell = true;
-                        }
+                        pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::BT_LR ));
                         break;
                     case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
                         pPropMap->Insert( PROP_FRM_DIRECTION, uno::makeAny( text::WritingMode2::LR_TB ));


More information about the Libreoffice-commits mailing list