[Libreoffice-commits] core.git: sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Feb 12 17:19:18 UTC 2019


 sw/source/core/inc/frame.hxx       |   15 +++++++--
 sw/source/core/inc/swfont.hxx      |    3 +
 sw/source/core/layout/calcmove.cxx |    2 -
 sw/source/core/layout/colfrm.cxx   |    2 -
 sw/source/core/layout/findfrm.cxx  |    1 
 sw/source/core/layout/newfrm.cxx   |   61 +++++++++++++++++++++++++++++++++++++
 sw/source/core/layout/paintfrm.cxx |    4 +-
 sw/source/core/layout/ssfrm.cxx    |    4 +-
 sw/source/core/layout/wsfrm.cxx    |   14 ++++++--
 sw/source/core/text/itratr.cxx     |    9 +++--
 sw/source/core/text/itratr.hxx     |    3 +
 sw/source/core/text/redlnitr.cxx   |   16 +++++++--
 sw/source/core/text/txtfrm.cxx     |   15 +++++++++
 sw/source/core/txtnode/swfont.cxx  |   11 ++++--
 14 files changed, 135 insertions(+), 25 deletions(-)

New commits:
commit e8b9572bf89f55463f2c879a401ed62efc165d95
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Feb 12 16:38:47 2019 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Feb 12 18:18:53 2019 +0100

    sw btlr writing mode: implement initial layout
    
    The bulk of this commit is reasonably straightforward, the interesting parts
    are:
    
    - SwFrame::CheckDir() is where the layout reads the doc model, i.e. sets the
      new SwFrame::mbVertLRBT.
    
    - We had 3 text directions previously: horizontal, vertical (implicitly RL) and
      vertical LR (implicitly TB). This adds a 4th text direction for the LRBT case.
    
    - SwTextFrame::SwitchHorizontalToVertical() is responsible for re-locating the
      origo of a string to be painted from the top left to the bottom left corner (in
      addition to the height/width swap that's done for all vertical directions).
    
    - Finally MapDirection() is the place where we map Writer's new btlr mode (with
      no character rotation) to VCL's 900 (90 degrees) rotated direction.
    
    No functional changes intended for existing text directions. Lots of places are
    still not yet adapted, but this is good enough to paint a single word in a
    table cell at the correct position with the correct direction.
    
    Change-Id: I465c62db6562d8a2be140c3d37473e590830139e
    Reviewed-on: https://gerrit.libreoffice.org/67740
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 0a9a1ea823c0..5f9a2cfcf886 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -404,6 +404,7 @@ protected:
     bool mbVertical    : 1;
 
     bool mbVertLR      : 1;
+    bool mbVertLRBT    : 1;
 
     bool mbValidLineNum  : 1;
     bool mbFixSize       : 1;
@@ -602,6 +603,7 @@ public:
 
     inline bool IsVertical() const;
     inline bool IsVertLR() const;
+    inline bool IsVertLRBT() const;
 
     void SetDerivedVert( bool bNew ){ mbDerivedVert = bNew; }
     void SetInvalidVert( bool bNew) { mbInvalidVert = bNew; }
@@ -955,6 +957,10 @@ inline bool SwFrame::IsVertLR() const
 {
     return mbVertLR;
 }
+inline bool SwFrame::IsVertLRBT() const
+{
+    return mbVertLRBT;
+}
 inline bool SwFrame::IsRightToLeft() const
 {
     if( mbInvalidR2L )
@@ -1312,21 +1318,23 @@ struct SwRectFnCollection
 typedef SwRectFnCollection* SwRectFn;
 
 // This class allows to use proper methods regardless of orientation (LTR/RTL, horizontal or vertical)
-extern SwRectFn fnRectHori, fnRectVert, fnRectVertL2R;
+extern SwRectFn fnRectHori, fnRectVert, fnRectVertL2R, fnRectVertL2RB2T;
 class SwRectFnSet {
 public:
     explicit SwRectFnSet(const SwFrame *pFrame)
         : m_bVert(pFrame->IsVertical())
         , m_bVertL2R(pFrame->IsVertLR())
+        , m_bVertL2RB2T(pFrame->IsVertLRBT())
     {
-        m_fnRect = m_bVert ? (m_bVertL2R ? fnRectVertL2R : fnRectVert) : fnRectHori;
+        m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori;
     }
 
     void Refresh(const SwFrame *pFrame)
     {
         m_bVert = pFrame->IsVertical();
         m_bVertL2R = pFrame->IsVertLR();
-        m_fnRect = m_bVert ? (m_bVertL2R ? fnRectVertL2R : fnRectVert) : fnRectHori;
+        m_bVertL2RB2T = pFrame->IsVertLRBT();
+        m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori;
     }
 
     bool IsVert() const    { return m_bVert; }
@@ -1395,6 +1403,7 @@ public:
 private:
     bool m_bVert;
     bool m_bVertL2R;
+    bool m_bVertL2RB2T;
     SwRectFn m_fnRect;
 };
 
diff --git a/sw/source/core/inc/swfont.hxx b/sw/source/core/inc/swfont.hxx
index ff0e5d8a0b9d..cc299a1d3fba 100644
--- a/sw/source/core/inc/swfont.hxx
+++ b/sw/source/core/inc/swfont.hxx
@@ -215,7 +215,8 @@ public:
     void SetOverColor( const Color &rColor ) { m_aOverColor = rColor; }
     inline void SetStrikeout( const FontStrikeout eStrikeout );
     inline void SetOutline( const bool bOutline );
-           void SetVertical( sal_uInt16 nDir, const bool bVertLayout = false );
+    void SetVertical(sal_uInt16 nDir, const bool bVertLayout = false,
+                     const bool bVertLayoutLRBT = false);
     inline void SetShadow( const bool bShadow );
     inline void SetAutoKern( FontKerning nAutoKern );
     inline void SetTransparent( const bool bTrans );
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx
index c8541459aeda..05260abf2dad 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -893,7 +893,7 @@ void SwLayoutFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
     const SwLayNotify aNotify( this );
     bool bVert = IsVertical();
 
-    SwRectFn fnRect = ( IsNeighbourFrame() == bVert )? fnRectHori : ( IsVertLR() ? fnRectVertL2R : fnRectVert );
+    SwRectFn fnRect = ( IsNeighbourFrame() == bVert )? fnRectHori : ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert );
 
     std::unique_ptr<SwBorderAttrAccess> pAccess;
     const SwBorderAttrs*pAttrs = nullptr;
diff --git a/sw/source/core/layout/colfrm.cxx b/sw/source/core/layout/colfrm.cxx
index 3a695b136734..6339d026fafb 100644
--- a/sw/source/core/layout/colfrm.cxx
+++ b/sw/source/core/layout/colfrm.cxx
@@ -300,7 +300,7 @@ void SwLayoutFrame::AdjustColumns( const SwFormatCol *pAttr, bool bAdjustAttribu
 
     const bool bVert = IsVertical();
 
-    SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+    SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
 
     //If we have a pointer or we have to configure an attribute, we set the
     //column widths in any case. Otherwise we check if a configuration is needed.
diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx
index 3ed0dede61f5..a0af09b2ad37 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -1476,6 +1476,7 @@ void SwFrame::SetDirFlags( bool bVert )
             {
                 mbVertical = pAsk->IsVertical();
                 mbVertLR  = pAsk->IsVertLR();
+                mbVertLRBT = pAsk->IsVertLRBT();
 
                 if ( !pAsk->mbInvalidVert )
                     mbInvalidVert = false;
diff --git a/sw/source/core/layout/newfrm.cxx b/sw/source/core/layout/newfrm.cxx
index adc2909c38a5..0971c2d95a8e 100644
--- a/sw/source/core/layout/newfrm.cxx
+++ b/sw/source/core/layout/newfrm.cxx
@@ -224,9 +224,70 @@ static SwRectFnCollection aVerticalLeftToRight = {
     /*.fnSetTopAndHeight =*/&SwRect::SetLeftAndWidth
 };
 
+/**
+ * This is the same as horizontal, but rotated counter-clockwise by 90 degrees.
+ * This means logical top is physical right, bottom is left, left is top,
+ * finally right is bottom.
+ */
+static SwRectFnCollection aVerticalLeftToRightBottomToTop = {
+    /*.fnGetTop =*/&SwRect::Right_,
+    /*.fnGetBottom =*/&SwRect::Left_,
+    /*.fnGetLeft =*/&SwRect::Top_,
+    /*.fnGetRight =*/&SwRect::Bottom_,
+    /*.fnGetWidth =*/&SwRect::Height_,
+    /*.fnGetHeight =*/&SwRect::Width_,
+    /*.fnGetPos =*/&SwRect::TopRight,
+    /*.fnGetSize =*/&SwRect::SwappedSize,
+
+    /*.fnSetTop =*/&SwRect::Right_,
+    /*.fnSetBottom =*/&SwRect::Left_,
+    /*.fnSetLeft =*/&SwRect::Top_,
+    /*.fnSetRight =*/&SwRect::Bottom_,
+    /*.fnSetWidth =*/&SwRect::Height_,
+    /*.fnSetHeight =*/&SwRect::Width_,
+
+    /*.fnSubTop =*/&SwRect::AddRight,
+    /*.fnAddBottom =*/&SwRect::SubLeft,
+    /*.fnSubLeft =*/&SwRect::SubTop,
+    /*.fnAddRight =*/&SwRect::AddBottom,
+    /*.fnAddWidth =*/&SwRect::AddHeight,
+    /*.fnAddHeight =*/&SwRect::AddWidth,
+
+    /*.fnSetPosX =*/&SwRect::SetPosY,
+    /*.fnSetPosY =*/&SwRect::SetPosX,
+
+    /*.fnGetTopMargin =*/&SwFrame::GetRightMargin,
+    /*.fnGetBottomMargin =*/&SwFrame::GetLeftMargin,
+    /*.fnGetLeftMargin =*/&SwFrame::GetTopMargin,
+    /*.fnGetRightMargin =*/&SwFrame::GetBottomMargin,
+    /*.fnSetXMargins =*/&SwFrame::SetTopBottomMargins,
+    /*.fnSetYMargins =*/&SwFrame::SetLeftRightMargins,
+    /*.fnGetPrtTop =*/&SwFrame::GetPrtRight,
+    /*.fnGetPrtBottom =*/&SwFrame::GetPrtLeft,
+    /*.fnGetPrtLeft =*/&SwFrame::GetPrtTop,
+    /*.fnGetPrtRight =*/&SwFrame::GetPrtBottom,
+    /*.fnTopDist =*/&SwRect::GetRightDistance,
+    /*.fnBottomDist =*/&SwRect::GetLeftDistance,
+    /*.fnLeftDist =*/&SwRect::GetTopDistance,
+    /*.fnRightDist =*/&SwRect::GetBottomDistance,
+    /*.fnSetLimit =*/&SwFrame::SetMinLeft,
+    /*.fnOverStep =*/&SwRect::OverStepLeft,
+
+    /*.fnSetPos =*/&SwRect::SetUpperRightCorner,
+    /*.fnMakePos =*/&SwFrame::MakeLeftPos,
+    /*.fnXDiff =*/&FirstMinusSecond,
+    /*.fnYDiff =*/&FirstMinusSecond,
+    /*.fnXInc =*/&SwIncrement,
+    /*.fnYInc =*/&SwIncrement,
+
+    /*.fnSetLeftAndWidth =*/&SwRect::SetTopAndHeight,
+    /*.fnSetTopAndHeight =*/&SwRect::SetRightAndWidth
+};
+
 SwRectFn fnRectHori = &aHorizontal;
 SwRectFn fnRectVert = &aVertical;
 SwRectFn fnRectVertL2R = &aVerticalLeftToRight;
+SwRectFn fnRectVertL2RB2T = &aVerticalLeftToRightBottomToTop;
 
 // #i65250#
 sal_uInt32 SwFrameAreaDefinition::mnLastFrameId=0;
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index b3fc9e8843b3..9db67c8b292d 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -1255,7 +1255,7 @@ static void lcl_CalcBorderRect( SwRect &rRect, const SwFrame *pFrame,
         rRect = pFrame->getFramePrintArea();
         rRect.Pos() += pFrame->getFrameArea().Pos();
 
-        SwRectFn fnRect = pFrame->IsVertical() ? ( pFrame->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+        SwRectFn fnRect = pFrame->IsVertical() ? ( pFrame->IsVertLR() ? (pFrame->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
 
         const SvxBoxItem &rBox = rAttrs.GetBox();
         const bool bTop = 0 != (pFrame->*fnRect->fnGetTopMargin)();
@@ -5218,7 +5218,7 @@ void SwLayoutFrame::PaintColLines( const SwRect &rRect, const SwFormatCol &rForm
     if ( !pCol || !pCol->IsColumnFrame() )
         return;
 
-    SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+    SwRectFn fnRect = pCol->IsVertical() ? ( pCol->IsVertLR() ? (pCol->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
 
     SwRect aLineRect = getFramePrintArea();
     aLineRect += getFrameArea().Pos();
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index f309693befc2..46cf019acbc4 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -584,7 +584,7 @@ const SwRect SwFrame::GetPaintArea() const
     // Cell frames may not leave their upper:
     SwRect aRect = IsRowFrame() ? GetUpper()->getFrameArea() : getFrameArea();
     const bool bVert = IsVertical();
-    SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+    SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
     long nRight = (aRect.*fnRect->fnGetRight)();
     long nLeft  = (aRect.*fnRect->fnGetLeft)();
     const SwFrame* pTmp = this;
@@ -675,7 +675,7 @@ const SwRect SwFrame::GetPaintArea() const
 const SwRect SwFrame::UnionFrame( bool bBorder ) const
 {
     bool bVert = IsVertical();
-    SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+    SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
     long nLeft = (getFrameArea().*fnRect->fnGetLeft)();
     long nWidth = (getFrameArea().*fnRect->fnGetWidth)();
     long nPrtLeft = (getFramePrintArea().*fnRect->fnGetLeft)();
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 39b9fbb8009d..c76f70110990 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -300,6 +300,7 @@ SwFrame::SwFrame( SwModify *pMod, SwFrame* pSib )
     mbDerivedVert(false),
     mbVertical(false),
     mbVertLR(false),
+    mbVertLRBT(false),
     mbValidLineNum(false),
     mbFixSize(false),
     mbCompletePaint(true),
@@ -357,6 +358,11 @@ void SwFrame::CheckDir( SvxFrameDirection nDir, bool bVert, bool bOnlyBiDi, bool
                 mbVertLR = false;
             else if(SvxFrameDirection::Vertical_LR_TB==nDir)
                 mbVertLR = true;
+            else if (nDir == SvxFrameDirection::Vertical_LR_BT)
+            {
+                mbVertLR = true;
+                mbVertLRBT = true;
+            }
         }
     }
     else
@@ -712,7 +718,7 @@ Size SwFrame::ChgSize( const Size& aNewSize )
     if ( GetUpper() )
     {
         bool bNeighb = IsNeighbourFrame();
-        SwRectFn fnRect = IsVertical() == bNeighb ? fnRectHori : ( IsVertLR() ? fnRectVertL2R : fnRectVert );
+        SwRectFn fnRect = IsVertical() == bNeighb ? fnRectHori : ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert );
         SwRect aNew( Point(0,0), aNewSize );
 
         {
@@ -1319,9 +1325,9 @@ void SwLayoutFrame::Paste( SwFrame* pParent, SwFrame* pSibling)
     if ( IsHeaderFrame() || IsFooterFrame() )
         fnRect = fnRectHori;
     else if ( IsCellFrame() || IsColumnFrame() )
-        fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert );
+        fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? (GetUpper()->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert );
     else
-        fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+        fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? (GetUpper()->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
 
     if( (getFrameArea().*fnRect->fnGetWidth)() != (pParent->getFramePrintArea().*fnRect->fnGetWidth)())
         InvalidateSize_();
@@ -3364,7 +3370,7 @@ void SwLayoutFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBord
     const sal_uInt16 nLower = bHideWhitespace ? 0 : pAttrs->CalcBottom();
 
     const bool bVert = IsVertical() && !IsPageFrame();
-    SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori;
+    SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori;
     if ( !isFramePrintAreaValid() )
     {
         setFramePrintAreaValid(true);
diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
index d7d8f7a0aefc..28263abd9eaa 100644
--- a/sw/source/core/text/itratr.cxx
+++ b/sw/source/core/text/itratr.cxx
@@ -204,7 +204,8 @@ bool SwAttrIter::SeekStartAndChgAttrIter( OutputDevice* pOut, const bool bParaFo
     {
         assert(m_pMergedPara);
         m_pTextNode = m_pMergedPara->pFirstNode;
-        InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *m_pTextNode, m_pMergedPara->mergedText, nullptr);
+        InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *m_pTextNode,
+                               m_pMergedPara->mergedText, nullptr, nullptr);
     }
 
     // reset font to its original state
@@ -338,7 +339,8 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos)
         // items at all; it can only apply a previously effective item.
         // So do this by recreating the font from scratch.
         // Apply new para items:
-        InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *newPos.first, m_pMergedPara->mergedText, nullptr);
+        InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *newPos.first,
+                               m_pMergedPara->mergedText, nullptr, nullptr);
         // reset to next
         m_pTextNode = newPos.first;
         m_nStartIndex = 0;
@@ -360,7 +362,8 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos)
                 m_pTextNode = newPos.first;
                 // sw_redlinehide: hope it's okay to use the current text node
                 // here; the AttrHandler shouldn't care about non-char items
-                InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *m_pTextNode, m_pMergedPara->mergedText, nullptr);
+                InitFontAndAttrHandler(*m_pMergedPara->pParaPropsNode, *m_pTextNode,
+                                       m_pMergedPara->mergedText, nullptr, nullptr);
             }
         }
         if (m_pMergedPara || m_pTextNode->GetpSwpHints())
diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx
index 2dddd1265d8c..dd3a755c7bfd 100644
--- a/sw/source/core/text/itratr.hxx
+++ b/sw/source/core/text/itratr.hxx
@@ -67,7 +67,8 @@ private:
     void SetFnt( SwFont* pNew ) { m_pFont = pNew; }
     void InitFontAndAttrHandler(
         SwTextNode const& rPropsNode, SwTextNode const& rTextNode,
-        OUString const& rText, bool const* pbVertLayout);
+        OUString const& rText, bool const* pbVertLayout,
+        bool const* pbVertLayoutLRBT);
 
 protected:
     void Chg( SwTextAttr const *pHt );
diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index 3b481b762914..95ce480d11b5 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -307,7 +307,8 @@ void SwAttrIter::InitFontAndAttrHandler(
         SwTextNode const& rPropsNode,
         SwTextNode const& rTextNode,
         OUString const& rText,
-        bool const*const pbVertLayout)
+        bool const*const pbVertLayout,
+        bool const*const pbVertLayoutLRBT)
 {
     // Build a font matching the default paragraph style:
     SwFontAccess aFontAccess( &rPropsNode.GetAnyFormatColl(), m_pViewShell );
@@ -328,7 +329,10 @@ void SwAttrIter::InitFontAndAttrHandler(
     // if it's a re-init, the vert flag never changes
     if (pbVertLayout ? *pbVertLayout : m_aAttrHandler.IsVertLayout())
     {
-        m_pFont->SetVertical( m_pFont->GetOrientation(), true );
+        bool bVertLayoutLRBT = false;
+        if (pbVertLayoutLRBT)
+            bVertLayoutLRBT = *pbVertLayoutLRBT;
+        m_pFont->SetVertical(m_pFont->GetOrientation(), true, bVertLayoutLRBT);
     }
 
     // Initialize the default attribute of the attribute handler
@@ -385,6 +389,7 @@ void SwAttrIter::CtorInitAttrIter(SwTextNode & rTextNode,
 
     // set font to vertical if frame layout is vertical
     bool bVertLayout = false;
+    bool bVertLayoutLRBT = false;
     bool bRTL = false;
     if ( pFrame )
     {
@@ -392,6 +397,10 @@ void SwAttrIter::CtorInitAttrIter(SwTextNode & rTextNode,
         {
             bVertLayout = true;
         }
+        if (pFrame->IsVertLRBT())
+        {
+            bVertLayoutLRBT = true;
+        }
         bRTL = pFrame->IsRightToLeft();
         m_pMergedPara = pFrame->GetMergedPara();
     }
@@ -405,7 +414,8 @@ void SwAttrIter::CtorInitAttrIter(SwTextNode & rTextNode,
             m_pMergedPara ? *m_pMergedPara->pParaPropsNode : rTextNode,
             rTextNode,
             m_pMergedPara ? m_pMergedPara->mergedText : rTextNode.GetText(),
-            & bVertLayout);
+            & bVertLayout,
+            & bVertLayoutLRBT);
 
     m_nStartIndex = m_nEndIndex = m_nPosition = m_nChgCnt = 0;
     m_nPropFont = 0;
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 557a5f226afb..17d1d6f321fc 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -512,6 +512,21 @@ void SwTextFrame::SwitchHorizontalToVertical( SwRect& rRect ) const
  */
 void SwTextFrame::SwitchHorizontalToVertical( Point& rPoint ) const
 {
+    if (IsVertLRBT())
+    {
+        // The horizontal origo is the top left corner, the LRBT origo is the
+        // bottom left corner. Finally x and y has to be swapped.
+        SAL_WARN_IF(!mbIsSwapped, "sw.core",
+                    "SwTextFrame::SwitchHorizontalToVertical, IsVertLRBT, not swapped");
+        Point aPoint(rPoint);
+        rPoint.setX(getFrameArea().Left() + (aPoint.Y() - getFrameArea().Top()));
+        // This would be bottom - x delta, but bottom is top + height, finally
+        // width (and not height), as it's swapped.
+        rPoint.setY(getFrameArea().Top() + getFrameArea().Width()
+                    - (aPoint.X() - getFrameArea().Left()));
+        return;
+    }
+
     // calc offset inside frame
     const long nOfstX = rPoint.X() - getFrameArea().Left();
     const long nOfstY = rPoint.Y() - getFrameArea().Top();
diff --git a/sw/source/core/txtnode/swfont.cxx b/sw/source/core/txtnode/swfont.cxx
index 33fefa32b833..8c0e97cd30a7 100644
--- a/sw/source/core/txtnode/swfont.cxx
+++ b/sw/source/core/txtnode/swfont.cxx
@@ -363,14 +363,17 @@ sal_uInt16 SwFont::CalcShadowSpace(
 }
 
 // maps directions for vertical layout
-static sal_uInt16 MapDirection( sal_uInt16 nDir, const bool bVertFormat )
+static sal_uInt16 MapDirection(sal_uInt16 nDir, const bool bVertFormat, const bool bVertFormatLRBT)
 {
     if ( bVertFormat )
     {
         switch ( nDir )
         {
         case 0 :
-            nDir = 2700;
+            if (bVertFormatLRBT)
+                nDir = 900;
+            else
+                nDir = 2700;
             break;
         case 900 :
             nDir = 0;
@@ -420,10 +423,10 @@ sal_uInt16 SwFont::GetOrientation( const bool bVertFormat ) const
     return UnMapDirection( m_aSub[m_nActual].GetOrientation(), bVertFormat );
 }
 
-void SwFont::SetVertical( sal_uInt16 nDir, const bool bVertFormat )
+void SwFont::SetVertical(sal_uInt16 nDir, const bool bVertFormat, const bool bVertLayoutLRBT)
 {
     // map direction if frame has vertical layout
-    nDir = MapDirection( nDir, bVertFormat );
+    nDir = MapDirection(nDir, bVertFormat, bVertLayoutLRBT);
 
     if( nDir != m_aSub[SwFontScript::Latin].GetOrientation() )
     {


More information about the Libreoffice-commits mailing list