Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
openSUSE:Leap:42.3
libreoffice
bnc959926-Implement-text-rotation-for-Impress-t...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bnc959926-Implement-text-rotation-for-Impress-table.patch of Package libreoffice
From c0cb16c07b18f2298ff4e1f832802e72dc5bab8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Zolnai?= <tamas.zolnai@collabora.com> Date: Tue, 28 Mar 2017 19:24:49 +0200 Subject: [PATCH] tdf#105286: Implement text rotation for Impress tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Typo: TopToBotton -> TopToBottom Change-Id: I1b4d3ab9ec1d1383d76a56c9662ffeeb9fe69655 Reviewed-on: https://gerrit.libreoffice.org/36014 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com> (cherry picked from commit 334e6e2f1ad3da319be0849ec426aa64b18cb599) Add SvxTextRotateItem inherited from SvxCharRotatItem I will be use it later for text rotation inside a table. Change-Id: I4cbaf05953b0e71331d2f3fdb45b7c4254a2b8cc Reviewed-on: https://gerrit.libreoffice.org/36021 Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com> Tested-by: Tamás Zolnai <tamas.zolnai@collabora.com> (cherry picked from commit 1e30d2aface12a31687e5a27126e2061efd4b0cd) Introduce text rotation for Impress tables * Introduce new table property for text rotation * Support only two rotation angle (270° and 90°) * Implement editing and rendering of 270° rotated text (90° rotation was already implemented) (cherry picked from commit c671094154ecec6f3ba5beea9d26ff0d2d4d86ad) Change-Id: Ifc2e0f171e9c840e86b365e9af2c30aa97ecd92e Implement RotateAngle API property for Impress table cells (cherry picked from commit a0755ab8772d01797f4945016a978a2bbd8fdf20) Change-Id: I01379c0fc21e8fe294bc882bf824f64502863ff4 tdf#100926: PPTX import of table with rotated text (cherry picked from commit 2436cf17304f25c7d34da52a321d6da0e9011d19) Change-Id: I05a8e979ac11b179e15784023032a56edc5b569b ODF import / export of rotated text in Impress table (cherry picked from commit bcb371b1a830442610ad7fda476eda5271427a50) Change-Id: I57136e32ed2db5e405a45e8e4bad1b8d459b7ae8 Fix vertical text and bitmap bullet rendering Change-Id: I881fce0511c81b164516d68f72c7e750687d4e0e (cherry picked from commit 15ac3f9f4dc65fc0c6020284064e3725956f5d0a) --- cui/source/tabpages/chardlg.cxx | 4 +- editeng/source/editeng/editdoc.cxx | 3 +- editeng/source/editeng/editdoc.hxx | 5 +- editeng/source/editeng/editeng.cxx | 21 +++- editeng/source/editeng/editobj.cxx | 40 +++++-- editeng/source/editeng/editobj2.hxx | 6 +- editeng/source/editeng/impedit.cxx | 82 +++++++++++--- editeng/source/editeng/impedit.hxx | 4 +- editeng/source/editeng/impedit3.cxx | 161 ++++++++++++++++++++++------ editeng/source/editeng/impedit4.cxx | 4 +- editeng/source/items/svxitems.src | 8 ++ editeng/source/items/textitem.cxx | 119 +++++++++++++++++--- editeng/source/outliner/outlin2.cxx | 9 +- editeng/source/outliner/outliner.cxx | 29 +++-- editeng/source/outliner/outlobj.cxx | 12 ++- include/editeng/charrotateitem.hxx | 57 ++++++++-- include/editeng/editeng.hxx | 3 +- include/editeng/editobj.hxx | 3 +- include/editeng/editrids.hrc | 2 + include/editeng/outliner.hxx | 3 +- include/editeng/outlobj.hxx | 3 +- include/svx/svddef.hxx | 3 +- oox/source/drawingml/table/tablecell.cxx | 5 + sd/qa/unit/data/pptx/tdf100926.pptx | Bin 0 -> 32382 bytes sd/qa/unit/data/pptx/tdf100926_ODP.pptx | Bin 0 -> 32382 bytes sd/qa/unit/export-tests.cxx | 31 ++++++ sd/qa/unit/import-tests.cxx | 28 +++++ sd/source/ui/func/futext.cxx | 4 +- svx/source/svdraw/svdattr.cxx | 2 + svx/source/svdraw/svdotext.cxx | 2 +- svx/source/svdraw/svdotextdecomposition.cxx | 24 +++-- svx/source/table/cell.cxx | 67 +++++++++++- svx/source/table/svdotable.cxx | 4 +- svx/source/unodraw/unoshtxt.cxx | 2 +- xmloff/inc/xmlsdtypes.hxx | 2 + xmloff/source/draw/sdpropls.cxx | 64 ++++++++++- xmloff/source/table/XMLTableExport.cxx | 14 +++ xmloff/source/table/XMLTableImport.cxx | 1 + xmloff/source/table/table.hxx | 1 + 39 files changed, 712 insertions(+), 120 deletions(-) create mode 100755 sd/qa/unit/data/pptx/tdf100926.pptx create mode 100755 sd/qa/unit/data/pptx/tdf100926_ODP.pptx diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx index b606199..fcaa7b7 100644 --- a/cui/source/tabpages/chardlg.cxx +++ b/cui/source/tabpages/chardlg.cxx @@ -2954,7 +2954,7 @@ void SvxCharPositionPage::Reset( const SfxItemSet* rSet ) static_cast<const SvxCharRotateItem&>( rSet->Get( nWhich )); if (rItem.IsBottomToTop()) m_p90degRB->Check(); - else if (rItem.IsTopToBotton()) + else if (rItem.IsTopToBottom()) m_p270degRB->Check(); else { @@ -3111,7 +3111,7 @@ bool SvxCharPositionPage::FillItemSet( SfxItemSet* rSet ) if (m_p90degRB->IsChecked()) aItem.SetBottomToTop(); else if (m_p270degRB->IsChecked()) - aItem.SetTopToBotton(); + aItem.SetTopToBottom(); rSet->Put( aItem ); bModified = true; } diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx index a7a73ce..8763b07 100644 --- a/editeng/source/editeng/editdoc.cxx +++ b/editeng/source/editeng/editdoc.cxx @@ -1982,6 +1982,7 @@ EditDoc::EditDoc( SfxItemPool* pPool ) : pItemPool(pPool ? pPool : new EditEngineItemPool(false)), nDefTab(DEFTAB), bIsVertical(false), + bIsTopToBottomVert(false), bIsFixedCellHeight(false), bOwnerOfPool(pPool == nullptr), bModified(false) @@ -2116,7 +2117,7 @@ void EditDoc::CreateDefFont( bool bUseStyles ) SfxItemSet aTmpSet( GetItemPool(), EE_PARA_START, EE_CHAR_END ); CreateFont( aDefFont, aTmpSet ); aDefFont.SetVertical( IsVertical() ); - aDefFont.SetOrientation( IsVertical() ? 2700 : 0 ); + aDefFont.SetOrientation( IsVertical() ? (IsTopToBottom() ? 2700 : 900) : 0 ); for ( sal_Int32 nNode = 0; nNode < Count(); nNode++ ) { diff --git a/editeng/source/editeng/editdoc.hxx b/editeng/source/editeng/editdoc.hxx index 3bdfa01..c25ed6c 100644 --- a/editeng/source/editeng/editdoc.hxx +++ b/editeng/source/editeng/editdoc.hxx @@ -739,6 +739,7 @@ private: SvxFont aDefFont; //faster than ever from the pool!! sal_uInt16 nDefTab; bool bIsVertical:1; + bool bIsTopToBottomVert : 1; bool bIsFixedCellHeight:1; bool bOwnerOfPool:1; @@ -765,8 +766,10 @@ public: void SetDefTab( sal_uInt16 nTab ) { nDefTab = nTab ? nTab : DEFTAB; } sal_uInt16 GetDefTab() const { return nDefTab; } - void SetVertical( bool bVertical ) { bIsVertical = bVertical; } + void SetVertical( bool bVertical, bool bTopToBottom = true ) + { bIsVertical = bVertical; bIsTopToBottomVert = bVertical && bTopToBottom; } bool IsVertical() const { return bIsVertical; } + bool IsTopToBottom() const { return bIsTopToBottomVert; } void SetFixedCellHeight( bool bUseFixedCellHeight ) { bIsFixedCellHeight = bUseFixedCellHeight; } bool IsFixedCellHeight() const { return bIsFixedCellHeight; } diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx index bde286a..5f88c0e 100644 --- a/editeng/source/editeng/editeng.cxx +++ b/editeng/source/editeng/editeng.cxx @@ -429,9 +429,9 @@ const Size& EditEngine::GetPaperSize() const return pImpEditEngine->GetPaperSize(); } -void EditEngine::SetVertical( bool bVertical ) +void EditEngine::SetVertical( bool bVertical, bool bTopToBottom ) { - pImpEditEngine->SetVertical( bVertical ); + pImpEditEngine->SetVertical( bVertical, bTopToBottom); } bool EditEngine::IsVertical() const @@ -439,6 +439,11 @@ bool EditEngine::IsVertical() const return pImpEditEngine->IsVertical(); } +bool EditEngine::IsTopToBottom() const +{ + return pImpEditEngine->IsTopToBottom(); +} + void EditEngine::SetFixedCellHeight( bool bUseFixedCellHeight ) { pImpEditEngine->SetFixedCellHeight( bUseFixedCellHeight ); @@ -1767,8 +1772,16 @@ void EditEngine::StripPortions() Rectangle aBigRect( Point( 0, 0 ), Size( 0x7FFFFFFF, 0x7FFFFFFF ) ); if ( IsVertical() ) { - aBigRect.Right() = 0; - aBigRect.Left() = -0x7FFFFFFF; + if( IsTopToBottom() ) + { + aBigRect.Right() = 0; + aBigRect.Left() = -0x7FFFFFFF; + } + else + { + aBigRect.Top() = -0x7FFFFFFF; + aBigRect.Bottom() = 0; + } } pImpEditEngine->Paint( aTmpDev.get(), aBigRect, Point(), true ); } diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx index 5a37083..e64793c 100644 --- a/editeng/source/editeng/editobj.cxx +++ b/editeng/source/editeng/editobj.cxx @@ -355,9 +355,14 @@ bool EditTextObject::IsVertical() const return mpImpl->IsVertical(); } -void EditTextObject::SetVertical( bool bVertical ) +bool EditTextObject::IsTopToBottom() const { - return mpImpl->SetVertical(bVertical); + return mpImpl->IsTopToBottom(); +} + +void EditTextObject::SetVertical( bool bVertical, bool bTopToBottom ) +{ + return mpImpl->SetVertical(bVertical, bTopToBottom); } SvtScriptType EditTextObject::GetScriptType() const @@ -562,6 +567,7 @@ EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, SfxItemPool* pP } bVertical = false; + bIsTopToBottomVert = false; bStoreUnicodeStrings = false; nScriptType = SvtScriptType::NONE; } @@ -574,6 +580,7 @@ EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, const EditTextOb nUserType = r.nUserType; nObjSettings = r.nObjSettings; bVertical = r.bVertical; + bIsTopToBottomVert = r.bIsTopToBottomVert; nScriptType = r.nScriptType; pPortionInfo = nullptr; // Do not copy PortionInfo bStoreUnicodeStrings = false; @@ -655,12 +662,22 @@ std::vector<svl::SharedString> EditTextObjectImpl::GetSharedStrings() const return aSSs; } +bool EditTextObjectImpl::IsVertical() const +{ + return bVertical; +} + +bool EditTextObjectImpl::IsTopToBottom() const +{ + return bIsTopToBottomVert; +} -void EditTextObjectImpl::SetVertical( bool b ) +void EditTextObjectImpl::SetVertical( bool bVert, bool bTopToBottom) { - if ( b != bVertical ) + if (bVert != bVertical || bTopToBottom != (bVert && bIsTopToBottomVert)) { - bVertical = b; + bVertical = bVert; + bIsTopToBottomVert = bVert && bTopToBottom; ClearPortionInfo(); } } @@ -1090,7 +1107,7 @@ public: void EditTextObjectImpl::StoreData( SvStream& rOStream ) const { - sal_uInt16 nVer = 602; + sal_uInt16 nVer = 603; rOStream.WriteUInt16( nVer ); rOStream.WriteBool( bOwnerOfPool ); @@ -1229,6 +1246,7 @@ void EditTextObjectImpl::StoreData( SvStream& rOStream ) const rOStream.WriteUInt32( nObjSettings ); rOStream.WriteBool( bVertical ); + rOStream.WriteBool( bIsTopToBottomVert ); rOStream.WriteUInt16( static_cast<sal_uInt16>(nScriptType) ); rOStream.WriteBool( bStoreUnicodeStrings ); @@ -1481,6 +1499,13 @@ void EditTextObjectImpl::CreateData( SvStream& rIStream ) bVertical = bTmp; } + if (nVersion >= 603) + { + bool bTmp(false); + rIStream.ReadCharAsBool(bTmp); + bIsTopToBottomVert = bTmp; + } + if ( nVersion >= 602 ) { sal_uInt16 aTmp16; @@ -1571,7 +1596,8 @@ bool EditTextObjectImpl::operator==( const EditTextObjectImpl& rCompare ) const ( nMetric != rCompare.nMetric ) || ( nUserType!= rCompare.nUserType ) || ( nScriptType != rCompare.nScriptType ) || - ( bVertical != rCompare.bVertical ) ) + ( bVertical != rCompare.bVertical ) || + ( bIsTopToBottomVert != rCompare.bIsTopToBottomVert ) ) return false; for (size_t i = 0, n = aContents.size(); i < n; ++i) diff --git a/editeng/source/editeng/editobj2.hxx b/editeng/source/editeng/editobj2.hxx index 9aaef1d..7466354 100644 --- a/editeng/source/editeng/editobj2.hxx +++ b/editeng/source/editeng/editobj2.hxx @@ -182,6 +182,7 @@ private: bool bOwnerOfPool:1; bool bVertical:1; + bool bIsTopToBottomVert : 1; bool bStoreUnicodeStrings:1; bool ImpChangeStyleSheets( const OUString& rOldName, SfxStyleFamily eOldFamily, @@ -204,8 +205,9 @@ public: void NormalizeString( svl::SharedStringPool& rPool ); std::vector<svl::SharedString> GetSharedStrings() const; - bool IsVertical() const { return bVertical;} - void SetVertical( bool b ); + bool IsVertical() const; + bool IsTopToBottom() const; + void SetVertical( bool bVert, bool bTopToBottom = true); SvtScriptType GetScriptType() const { return nScriptType;} void SetScriptType( SvtScriptType nType ); diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx index e4eb615..a8af19d 100644 --- a/editeng/source/editeng/impedit.cxx +++ b/editeng/source/editeng/impedit.cxx @@ -513,6 +513,11 @@ bool ImpEditView::IsVertical() const return pEditEngine->pImpEditEngine->IsVertical(); } +bool ImpEditView::IsTopToBottom() const +{ + return pEditEngine->pImpEditEngine->IsTopToBottom(); +} + Rectangle ImpEditView::GetVisDocArea() const { return Rectangle( GetVisDocLeft(), GetVisDocTop(), GetVisDocRight(), GetVisDocBottom() ); @@ -530,8 +535,16 @@ Point ImpEditView::GetDocPos( const Point& rWindowPos ) const } else { - aPoint.X() = rWindowPos.Y() - aOutArea.Top() + GetVisDocLeft(); - aPoint.Y() = aOutArea.Right() - rWindowPos.X() + GetVisDocTop(); + if (pEditEngine->pImpEditEngine->IsTopToBottom()) + { + aPoint.X() = rWindowPos.Y() - aOutArea.Top() + GetVisDocLeft(); + aPoint.Y() = aOutArea.Right() - rWindowPos.X() + GetVisDocTop(); + } + else + { + aPoint.X() = aOutArea.Bottom() - rWindowPos.Y() + GetVisDocLeft(); + aPoint.Y() = rWindowPos.X() - aOutArea.Left() + GetVisDocTop(); + } } return aPoint; @@ -549,8 +562,16 @@ Point ImpEditView::GetWindowPos( const Point& rDocPos ) const } else { - aPoint.X() = aOutArea.Right() - rDocPos.Y() + GetVisDocTop(); - aPoint.Y() = rDocPos.X() + aOutArea.Top() - GetVisDocLeft(); + if (pEditEngine->pImpEditEngine->IsTopToBottom()) + { + aPoint.X() = aOutArea.Right() - rDocPos.Y() + GetVisDocTop(); + aPoint.Y() = rDocPos.X() + aOutArea.Top() - GetVisDocLeft(); + } + else + { + aPoint.X() = aOutArea.Left() + rDocPos.Y() - GetVisDocTop(); + aPoint.Y() = aOutArea.Bottom() - rDocPos.X() + GetVisDocLeft(); + } } return aPoint; @@ -916,8 +937,8 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool bForceVisCursor ) if ( nDocDiffX | nDocDiffY ) { - long nDiffX = !IsVertical() ? nDocDiffX : -nDocDiffY; - long nDiffY = !IsVertical() ? nDocDiffY : nDocDiffX; + long nDiffX = !IsVertical() ? nDocDiffX : (IsTopToBottom() ? -nDocDiffY : nDocDiffY); + long nDiffY = !IsVertical() ? nDocDiffY : (IsTopToBottom() ? nDocDiffX : -nDocDiffX); // Negative: Back to the top or left edge if ( ( std::abs( nDiffY ) > pEditEngine->GetOnePixelInRef() ) && DoBigScroll() ) @@ -993,7 +1014,7 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool bForceVisCursor ) aCursorSz.Width() = aOldSz.Height(); aCursorSz.Height() = aOldSz.Width(); GetCursor()->SetPos( aCursorRect.TopRight() ); - GetCursor()->SetOrientation( 2700 ); + GetCursor()->SetOrientation( IsTopToBottom() ? 2700 : 900 ); } else // #i32593# Reset correct orientation in horizontal layout @@ -1087,8 +1108,16 @@ Pair ImpEditView::Scroll( long ndX, long ndY, ScrollRangeCheck nRangeCheck ) } else { - aNewVisArea.Top() += ndX; - aNewVisArea.Bottom() += ndX; + if( IsTopToBottom() ) + { + aNewVisArea.Top() += ndX; + aNewVisArea.Bottom() += ndX; + } + else + { + aNewVisArea.Top() -= ndX; + aNewVisArea.Bottom() -= ndX; + } } if ( ( nRangeCheck == ScrollRangeCheck::PaperWidthTextSize ) && ( aNewVisArea.Bottom() > (long)pEditEngine->pImpEditEngine->GetTextHeight() ) ) { @@ -1107,8 +1136,16 @@ Pair ImpEditView::Scroll( long ndX, long ndY, ScrollRangeCheck nRangeCheck ) } else { - aNewVisArea.Left() -= ndY; - aNewVisArea.Right() -= ndY; + if (IsTopToBottom()) + { + aNewVisArea.Left() -= ndY; + aNewVisArea.Right() -= ndY; + } + else + { + aNewVisArea.Left() += ndY; + aNewVisArea.Right() += ndY; + } } if ( ( nRangeCheck == ScrollRangeCheck::PaperWidthTextSize ) && ( aNewVisArea.Right() > (long)pEditEngine->pImpEditEngine->CalcTextWidth( false ) ) ) { @@ -1119,8 +1156,8 @@ Pair ImpEditView::Scroll( long ndX, long ndY, ScrollRangeCheck nRangeCheck ) aNewVisArea.Move( -aNewVisArea.Left(), 0 ); // The difference must be alignt on pixel (due to scroll!) - long nDiffX = !IsVertical() ? ( GetVisDocLeft() - aNewVisArea.Left() ) : -( GetVisDocTop() - aNewVisArea.Top() ); - long nDiffY = !IsVertical() ? ( GetVisDocTop() - aNewVisArea.Top() ) : ( GetVisDocLeft() - aNewVisArea.Left() ); + long nDiffX = !IsVertical() ? ( GetVisDocLeft() - aNewVisArea.Left() ) : (IsTopToBottom() ? -( GetVisDocTop() - aNewVisArea.Top() ) : (GetVisDocTop() - aNewVisArea.Top())); + long nDiffY = !IsVertical() ? ( GetVisDocTop() - aNewVisArea.Top() ) : (IsTopToBottom() ? (GetVisDocLeft() - aNewVisArea.Left()) : -(GetVisDocTop() - aNewVisArea.Top())); Size aDiffs( nDiffX, nDiffY ); aDiffs = pOutWin->LogicToPixel( aDiffs ); @@ -1139,7 +1176,12 @@ Pair ImpEditView::Scroll( long ndX, long ndY, ScrollRangeCheck nRangeCheck ) if ( !IsVertical() ) aVisDocStartPos.Move( -nRealDiffX, -nRealDiffY ); else - aVisDocStartPos.Move( -nRealDiffY, nRealDiffX ); + { + if (IsTopToBottom()) + aVisDocStartPos.Move(-nRealDiffY, nRealDiffX); + else + aVisDocStartPos.Move(nRealDiffY, -nRealDiffX); + } // Das Move um den allignten Wert ergibt nicht unbedingt ein // alligntes Rechteck... // Aligned value of the move does not necessarily result in aligned @@ -2117,8 +2159,16 @@ void ImpEditView::dragOver(const css::datatransfer::dnd::DropTargetDragEvent& rD } else { - aEditCursor.Left()--; - aEditCursor.Right()++; + if( IsTopToBottom() ) + { + aEditCursor.Left()--; + aEditCursor.Right()++; + } + else + { + aEditCursor.Left()++; + aEditCursor.Right()--; + } } aEditCursor = GetWindow()->PixelToLogic( aEditCursor ); } diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index 291a95a..0958617 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -295,6 +295,7 @@ public: const Rectangle& GetOutputArea() const { return aOutArea; } bool IsVertical() const; + bool IsTopToBottom() const; bool PostKeyEvent( const KeyEvent& rKeyEvent, vcl::Window* pFrameWin ); @@ -720,8 +721,9 @@ public: const Size& GetPaperSize() const { return aPaperSize; } void SetPaperSize( const Size& rSz ) { aPaperSize = rSz; } - void SetVertical( bool bVertical ); + void SetVertical( bool bVertical, bool bTopToBottom = true); bool IsVertical() const { return GetEditDoc().IsVertical(); } + bool IsTopToBottom() const { return GetEditDoc().IsTopToBottom(); } bool IsPageOverflow( ) const; diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx index 9334293..dee5f65 100644 --- a/editeng/source/editeng/impedit3.cxx +++ b/editeng/source/editeng/impedit3.cxx @@ -2580,11 +2580,11 @@ void ImpEditEngine::SetTextRanger( TextRanger* pRanger ) } } -void ImpEditEngine::SetVertical( bool bVertical ) +void ImpEditEngine::SetVertical( bool bVertical, bool bTopToBottom) { - if ( IsVertical() != bVertical ) + if ( IsVertical() != bVertical || IsTopToBottom() != (bVertical && bTopToBottom)) { - GetEditDoc().SetVertical( bVertical ); + GetEditDoc().SetVertical( bVertical, bTopToBottom); bool bUseCharAttribs = bool(aStatus.GetControlWord() & EEControlBits::USECHARATTRIBS); GetEditDoc().CreateDefFont( bUseCharAttribs ); if ( IsFormatted() ) @@ -2963,7 +2963,8 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt sal_Int32 nIndex = 0; if ( pPortion->IsVisible() && ( ( !IsVertical() && ( ( aStartPos.Y() + nParaHeight ) > aClipRect.Top() ) ) || - ( IsVertical() && ( ( aStartPos.X() - nParaHeight ) < aClipRect.Right() ) ) ) ) + ( IsVertical() && IsTopToBottom() && ( ( aStartPos.X() - nParaHeight ) < aClipRect.Right() ) ) || + ( IsVertical() && !IsTopToBottom() && ( ( aStartPos.X() + nParaHeight ) > aClipRect.Left() ) ) ) ) { @@ -2977,7 +2978,12 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt if ( !IsVertical() ) aStartPos.Y() += pPortion->GetFirstLineOffset(); else - aStartPos.X() -= pPortion->GetFirstLineOffset(); + { + if( IsTopToBottom() ) + aStartPos.X() -= pPortion->GetFirstLineOffset(); + else + aStartPos.X() += pPortion->GetFirstLineOffset(); + } Point aParaStart( aStartPos ); @@ -3002,15 +3008,27 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt } else { - aTmpPos.Y() += pLine->GetStartPosX(); - aTmpPos.X() -= pLine->GetMaxAscent(); - aStartPos.X() -= pLine->GetHeight(); - if (nLine != nLastLine) - aStartPos.X() -= nVertLineSpacing; + if ( IsTopToBottom() ) + { + aTmpPos.Y() += pLine->GetStartPosX(); + aTmpPos.X() -= pLine->GetMaxAscent(); + aStartPos.X() -= pLine->GetHeight(); + if (nLine != nLastLine) + aStartPos.X() -= nVertLineSpacing; + } + else + { + aTmpPos.Y() -= pLine->GetStartPosX(); + aTmpPos.X() += pLine->GetMaxAscent(); + aStartPos.X() += pLine->GetHeight(); + if (nLine != nLastLine) + aStartPos.X() += nVertLineSpacing; + } } if ( ( !IsVertical() && ( aStartPos.Y() > aClipRect.Top() ) ) - || ( IsVertical() && aStartPos.X() < aClipRect.Right() ) ) + || ( IsVertical() && IsTopToBottom() && aStartPos.X() < aClipRect.Right() ) + || ( IsVertical() && !IsTopToBottom() && aStartPos.X() > aClipRect.Left() ) ) { bPaintBullet = false; @@ -3048,9 +3066,18 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt } else { - aTmpPos.Y() = aStartPos.Y() + nPortionXOffset; - if ( aTmpPos.Y() > aClipRect.Bottom() ) - break; // No further output in line necessary + if( IsTopToBottom() ) + { + aTmpPos.Y() = aStartPos.Y() + nPortionXOffset; + if ( aTmpPos.Y() > aClipRect.Bottom() ) + break; // No further output in line necessary + } + else + { + aTmpPos.Y() = aStartPos.Y() - nPortionXOffset; + if (aTmpPos.Y() < aClipRect.Top()) + break; // No further output in line necessary + } } switch ( rTextPortion.GetKind() ) @@ -3141,8 +3168,16 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt } else { - aTopLeftRectPos.Y() += nAdvanceX; - aTopLeftRectPos.X() -= nAdvanceY; + if( IsTopToBottom() ) + { + aTopLeftRectPos.Y() -= nAdvanceX; + aTopLeftRectPos.X() += nAdvanceY; + } + else + { + aTopLeftRectPos.Y() += nAdvanceX; + aTopLeftRectPos.X() -= nAdvanceY; + } } Point aBottomRightRectPos( aTopLeftRectPos ); @@ -3153,8 +3188,16 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt } else { - aBottomRightRectPos.X() -= pLine->GetHeight(); - aBottomRightRectPos.Y() += 2 * nHalfBlankWidth; + if (IsTopToBottom()) + { + aBottomRightRectPos.X() += pLine->GetHeight(); + aBottomRightRectPos.Y() -= 2 * nHalfBlankWidth; + } + else + { + aBottomRightRectPos.X() -= pLine->GetHeight(); + aBottomRightRectPos.Y() += 2 * nHalfBlankWidth; + } } pOutDev->Push( PushFlags::FILLCOLOR ); @@ -3187,7 +3230,10 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt } else { - aSlashPos.Y() = aTopLeftRectPos.Y() + nAddX; + if (IsTopToBottom()) + aSlashPos.Y() = aTopLeftRectPos.Y() + nAddX; + else + aSlashPos.Y() = aTopLeftRectPos.Y() - nAddX; } aTmpFont.QuickDrawText( pOutDev, aSlashPos, aSlash, 0, 1 ); @@ -3226,8 +3272,16 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt } else { - aTmpPos.X() -= pLine->GetMaxAscent(); - aStartPos.X() -= pLine->GetHeight(); + if (IsTopToBottom()) + { + aTmpPos.X() -= pLine->GetMaxAscent(); + aStartPos.X() -= pLine->GetHeight(); + } + else + { + aTmpPos.X() += pLine->GetMaxAscent(); + aStartPos.X() += pLine->GetHeight(); + } } } ::std::vector< sal_Int32 >::iterator curIt = itSubLines; @@ -3404,7 +3458,12 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt if ( !IsVertical() ) aOutPos.Y() -= nDiff; else - aOutPos.X() += nDiff; + { + if (IsTopToBottom()) + aOutPos.X() += nDiff; + else + aOutPos.X() -= nDiff; + } aRedLineTmpPos = aOutPos; aTmpFont.SetEscapement( 0 ); } @@ -3534,7 +3593,10 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt if( !IsVertical() ) aRedLineTmpPos.Y() -= nShift; else - aRedLineTmpPos.X() += nShift; + if (IsTopToBottom()) + aRedLineTmpPos.X() += nShift; + else + aRedLineTmpPos.X() -= nShift; } } Color aOldColor( pOutDev->GetLineColor() ); @@ -3651,13 +3713,20 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt if ( !IsVertical() ) aStartPos.Y() += nSBL; else - aStartPos.X() -= nSBL; + { + if( IsTopToBottom() ) + aStartPos.X() -= nSBL; + else + aStartPos.X() += nSBL; + } } // no more visible actions? if ( !IsVertical() && ( aStartPos.Y() >= aClipRect.Bottom() ) ) break; - else if ( IsVertical() && ( aStartPos.X() <= aClipRect.Left() ) ) + else if ( IsVertical() && IsTopToBottom() && ( aStartPos.X() <= aClipRect.Left() ) ) + break; + else if (IsVertical() && !IsTopToBottom() && (aStartPos.X() >= aClipRect.Right())) break; } @@ -3668,7 +3737,12 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt if ( !IsVertical() ) aStartPos.Y() += nUL; else - aStartPos.X() -= nUL; + { + if (IsTopToBottom()) + aStartPos.X() -= nUL; + else + aStartPos.X() += nUL; + } } // #108052# Safer way for #i108052# and #i118881#: If for the current ParaPortion @@ -3697,7 +3771,12 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt if ( !IsVertical() ) aStartPos.Y() += nParaHeight; else - aStartPos.X() -= nParaHeight; + { + if (IsTopToBottom()) + aStartPos.X() -= nParaHeight; + else + aStartPos.X() += nParaHeight; + } } if ( pPDFExtOutDevData ) @@ -3706,7 +3785,9 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, Rectangle aClipRect, Point aSt // no more visible actions? if ( !IsVertical() && ( aStartPos.Y() > aClipRect.Bottom() ) ) break; - if ( IsVertical() && ( aStartPos.X() < aClipRect.Left() ) ) + if ( IsVertical() && IsTopToBottom() && ( aStartPos.X() < aClipRect.Left() ) ) + break; + if (IsVertical() && !IsTopToBottom() && ( aStartPos.X() > aClipRect.Right() ) ) break; } if ( aStatus.DoRestoreFont() ) @@ -3735,9 +3816,18 @@ void ImpEditEngine::Paint( ImpEditView* pView, const Rectangle& rRect, OutputDev } else { - aStartPos = pView->GetOutputArea().TopRight(); - aStartPos.X() += pView->GetVisDocTop(); - aStartPos.Y() -= pView->GetVisDocLeft(); + if( IsTopToBottom() ) + { + aStartPos = pView->GetOutputArea().TopRight(); + aStartPos.X() += pView->GetVisDocTop(); + aStartPos.Y() -= pView->GetVisDocLeft(); + } + else + { + aStartPos = pView->GetOutputArea().BottomLeft(); + aStartPos.X() -= pView->GetVisDocTop(); + aStartPos.Y() += pView->GetVisDocLeft(); + } } // If Doc-width < Output Area,Width and not wrapped fields, @@ -4029,8 +4119,13 @@ long ImpEditEngine::CalcVertLineSpacing(Point& rStartPos) const return 0; if (IsVertical()) - // Shift the text to the right for the asian layout mode. - rStartPos.X() += nTotalSpace; + { + if( IsTopToBottom() ) + // Shift the text to the right for the asian layout mode. + rStartPos.X() += nTotalSpace; + else + rStartPos.X() -= nTotalSpace; + } return nTotalSpace / (nTotalLineCount-1); } diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx index dde54ad..7cf098b 100644 --- a/editeng/source/editeng/impedit4.cxx +++ b/editeng/source/editeng/impedit4.cxx @@ -1026,7 +1026,7 @@ EditTextObject* ImpEditEngine::CreateTextObject(const EditSelection& rSel) EditTextObject* ImpEditEngine::CreateTextObject( EditSelection aSel, SfxItemPool* pPool, bool bAllowBigObjects, sal_Int32 nBigObjectStart ) { EditTextObject* pTxtObj = new EditTextObject(pPool); - pTxtObj->SetVertical( IsVertical() ); + pTxtObj->SetVertical( IsVertical(), IsTopToBottom()); MapUnit eMapUnit = aEditDoc.GetItemPool().GetMetric( DEF_METRIC ); pTxtObj->mpImpl->SetMetric( (sal_uInt16) eMapUnit ); if ( pTxtObj->mpImpl->IsOwnerOfPool() ) @@ -1184,7 +1184,7 @@ void ImpEditEngine::SetText( const EditTextObject& rTextObject ) EnableUndo( false ); InsertText( rTextObject, EditSelection( aPaM, aPaM ) ); - SetVertical( rTextObject.IsVertical() ); + SetVertical( rTextObject.IsVertical(), rTextObject.IsTopToBottom()); DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "From where comes the Undo in SetText ?!" ); SetUpdateMode( _bUpdate ); diff --git a/editeng/source/items/svxitems.src b/editeng/source/items/svxitems.src index e173867..c39eb0dc 100644 --- a/editeng/source/items/svxitems.src +++ b/editeng/source/items/svxitems.src @@ -943,6 +943,14 @@ String RID_SVXITEMS_CHARROTATE_FITLINE { Text [ en-US ] = "Fit to line"; }; +String RID_SVXITEMS_TEXTROTATE_OFF +{ + Text [ en-US ] = "Text is not rotated"; +}; +String RID_SVXITEMS_TEXTROTATE +{ + Text [ en-US ] = "Text is rotated by $(ARG1)°"; +}; String RID_SVXITEMS_CHARSCALE { Text [ en-US ] = "Characters scaled $(ARG1)%"; diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx index 1e01793..2bc2b9d 100644 --- a/editeng/source/items/textitem.cxx +++ b/editeng/source/items/textitem.cxx @@ -2878,13 +2878,114 @@ sal_uInt16 SvxTwoLinesItem::GetVersion( sal_uInt16 nFFVer ) const /************************************************************************* +|* class SvxTextRotateItem +*************************************************************************/ + +SvxTextRotateItem::SvxTextRotateItem(sal_uInt16 nValue, const sal_uInt16 nW) + : SfxUInt16Item(nW, nValue) +{ +} + +SfxPoolItem* SvxTextRotateItem::Clone(SfxItemPool*) const +{ + return new SvxTextRotateItem(GetValue(), Which()); +} + +SfxPoolItem* SvxTextRotateItem::Create(SvStream& rStrm, sal_uInt16) const +{ + sal_uInt16 nVal; + rStrm.ReadUInt16(nVal); + return new SvxTextRotateItem(nVal, Which()); +} + +SvStream& SvxTextRotateItem::Store(SvStream & rStrm, sal_uInt16) const +{ + rStrm.WriteUInt16(GetValue()); + return rStrm; +} + +sal_uInt16 SvxTextRotateItem::GetVersion(sal_uInt16 nFFVer) const +{ + return SOFFICE_FILEFORMAT_50 > nFFVer ? USHRT_MAX : 0; +} + +bool SvxTextRotateItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper*) const +{ + if (!GetValue()) + rText = EE_RESSTR(RID_SVXITEMS_TEXTROTATE_OFF); + else + { + rText = EE_RESSTR(RID_SVXITEMS_TEXTROTATE); + rText = rText.replaceFirst("$(ARG1)", + OUString::number(GetValue() / 10)); + } + return true; +} + +bool SvxTextRotateItem::QueryValue(css::uno::Any& rVal, + sal_uInt8 nMemberId) const +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch (nMemberId) + { + case MID_ROTATE: + rVal <<= (sal_Int16)GetValue(); + break; + default: + bRet = false; + break; + } + return bRet; +} + +bool SvxTextRotateItem::PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch (nMemberId) + { + case MID_ROTATE: + { + sal_Int16 nVal = 0; + if ((rVal >>= nVal) && (0 == nVal || 900 == nVal || 2700 == nVal)) + SetValue((sal_uInt16)nVal); + else + bRet = false; + break; + } + default: + bRet = false; + } + return bRet; +} + +bool SvxTextRotateItem::operator==(const SfxPoolItem& rItem) const +{ + assert(SfxPoolItem::operator==(rItem)); + return SfxUInt16Item::operator==(rItem); +} + +void SvxTextRotateItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("SvxTextRotateItem")); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(GetValue()).getStr())); + xmlTextWriterEndElement(pWriter); +} + + +/************************************************************************* |* class SvxCharRotateItem *************************************************************************/ SvxCharRotateItem::SvxCharRotateItem( sal_uInt16 nValue, bool bFitIntoLine, const sal_uInt16 nW ) - : SfxUInt16Item( nW, nValue ), bFitToLine( bFitIntoLine ) + : SvxTextRotateItem(nValue, nW), bFitToLine( bFitIntoLine ) { } @@ -2934,12 +3035,11 @@ bool SvxCharRotateItem::GetPresentation( bool SvxCharRotateItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) const { - nMemberId &= ~CONVERT_TWIPS; bool bRet = true; - switch( nMemberId ) + switch(nMemberId & ~CONVERT_TWIPS) { case MID_ROTATE: - rVal <<= (sal_Int16)GetValue(); + SvxTextRotateItem::QueryValue(rVal, nMemberId); break; case MID_FITTOLINE: rVal = css::uno::makeAny<bool>( IsFitToLine() ); @@ -2954,17 +3054,12 @@ bool SvxCharRotateItem::QueryValue( css::uno::Any& rVal, bool SvxCharRotateItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId ) { - nMemberId &= ~CONVERT_TWIPS; bool bRet = true; - switch( nMemberId ) + switch(nMemberId & ~CONVERT_TWIPS) { case MID_ROTATE: { - sal_Int16 nVal = 0; - if((rVal >>= nVal) && (0 == nVal || 900 == nVal || 2700 == nVal)) - SetValue( (sal_uInt16)nVal ); - else - bRet = false; + bRet = SvxTextRotateItem::PutValue(rVal, nMemberId); break; } @@ -2980,7 +3075,7 @@ bool SvxCharRotateItem::PutValue( const css::uno::Any& rVal, bool SvxCharRotateItem::operator==( const SfxPoolItem& rItem ) const { assert(SfxPoolItem::operator==(rItem)); - return SfxUInt16Item::operator==( rItem ) && + return SvxTextRotateItem::operator==( rItem ) && IsFitToLine() == static_cast<const SvxCharRotateItem&>(rItem).IsFitToLine(); } diff --git a/editeng/source/outliner/outlin2.cxx b/editeng/source/outliner/outlin2.cxx index 3248ba3..c89a89f 100644 --- a/editeng/source/outliner/outlin2.cxx +++ b/editeng/source/outliner/outlin2.cxx @@ -526,9 +526,9 @@ const EditEngine& Outliner::GetEditEngine() const return *pEditEngine; } -void Outliner::SetVertical( bool b ) +void Outliner::SetVertical( bool bVertical, bool bTopToBottom) { - pEditEngine->SetVertical( b ); + pEditEngine->SetVertical(bVertical, bTopToBottom); } bool Outliner::IsVertical() const @@ -536,6 +536,11 @@ bool Outliner::IsVertical() const return pEditEngine->IsVertical(); } +bool Outliner::IsTopToBottom() const +{ + return pEditEngine->IsTopToBottom(); +} + void Outliner::SetFixedCellHeight( bool bUseFixedCellHeight ) { pEditEngine->SetFixedCellHeight( bUseFixedCellHeight ); diff --git a/editeng/source/outliner/outliner.cxx b/editeng/source/outliner/outliner.cxx index a77e881..9943efd 100644 --- a/editeng/source/outliner/outliner.cxx +++ b/editeng/source/outliner/outliner.cxx @@ -861,7 +861,7 @@ vcl::Font Outliner::ImpCalcBulletFont( sal_Int32 nPara ) const aBulletFont.SetFontSize( Size( 0, nScaledLineHeight ) ); bool bVertical = IsVertical(); aBulletFont.SetVertical( bVertical ); - aBulletFont.SetOrientation( bVertical ? 2700 : 0 ); + aBulletFont.SetOrientation( bVertical ? (IsTopToBottom() ? 2700 : 900) : 0 ); Color aColor( COL_AUTO ); if( !pEditEngine->IsFlatMode() && !( pEditEngine->GetControlWord() & EEControlBits::NOCOLORS ) ) @@ -890,6 +890,7 @@ void Outliner::PaintBullet( sal_Int32 nPara, const Point& rStartPos, if (bDrawBullet && ImplHasNumberFormat(nPara)) { bool bVertical = IsVertical(); + bool bTopToBottom = IsTopToBottom(); bool bRightToLeftPara = pEditEngine->IsRightToLeft( nPara ); @@ -927,9 +928,17 @@ void Outliner::PaintBullet( sal_Int32 nPara, const Point& rStartPos, } else { -// aTextPos.X() = rStartPos.X() - aBulletArea.Bottom(); - aTextPos.X() = rStartPos.X() - ( bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent ); - aTextPos.Y() = rStartPos.Y() + aBulletArea.Left(); + if (bTopToBottom) + { +// aTextPos.X() = rStartPos.X() - aBulletArea.Bottom(); + aTextPos.X() = rStartPos.X() - (bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent); + aTextPos.Y() = rStartPos.Y() + aBulletArea.Left(); + } + else + { + aTextPos.X() = rStartPos.X() + (bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent); + aTextPos.Y() = rStartPos.Y() + aBulletArea.Left(); + } } if ( nOrientation ) @@ -998,8 +1007,16 @@ void Outliner::PaintBullet( sal_Int32 nPara, const Point& rStartPos, } else { - aBulletPos.X() = rStartPos.X() - aBulletArea.Bottom(); - aBulletPos.Y() = rStartPos.Y() + aBulletArea.Left(); + if (bTopToBottom) + { + aBulletPos.X() = rStartPos.X() - aBulletArea.Bottom(); + aBulletPos.Y() = rStartPos.Y() + aBulletArea.Left(); + } + else + { + aBulletPos.X() = rStartPos.X() + aBulletArea.Top(); + aBulletPos.Y() = rStartPos.Y() - aBulletArea.Right(); + } } if(bStrippingPortions) diff --git a/editeng/source/outliner/outlobj.cxx b/editeng/source/outliner/outlobj.cxx index 3eba88e..a993b82 100644 --- a/editeng/source/outliner/outlobj.cxx +++ b/editeng/source/outliner/outlobj.cxx @@ -131,12 +131,18 @@ bool OutlinerParaObject::IsVertical() const return mpImpl->mpEditTextObject->IsVertical(); } -void OutlinerParaObject::SetVertical(bool bNew) +bool OutlinerParaObject::IsTopToBottom() const +{ + return mpImpl->mpEditTextObject->IsTopToBottom(); +} + +void OutlinerParaObject::SetVertical(bool bNew, bool bTopToBottom) { const ::o3tl::cow_wrapper< OutlinerParaObjData >* pImpl = &mpImpl; - if ( ( *pImpl )->mpEditTextObject->IsVertical() != bNew ) + if ( ( *pImpl )->mpEditTextObject->IsVertical() != bNew || + (*pImpl)->mpEditTextObject->IsTopToBottom() != (bNew && bTopToBottom)) { - mpImpl->mpEditTextObject->SetVertical(bNew); + mpImpl->mpEditTextObject->SetVertical(bNew, bTopToBottom); } } diff --git a/include/editeng/charrotateitem.hxx b/include/editeng/charrotateitem.hxx index 2ab87f2..32a84a5 100644 --- a/include/editeng/charrotateitem.hxx +++ b/include/editeng/charrotateitem.hxx @@ -22,6 +22,55 @@ #include <svl/intitem.hxx> #include <editeng/editengdllapi.h> + // class SvxTextRotateItem ---------------------------------------------- + + /* [Description] + + This item defines a text rotation value. Currently + text can only be rotated 90,0 and 270,0 degrees. + + */ + +class EDITENG_DLLPUBLIC SvxTextRotateItem : public SfxUInt16Item +{ +public: + static SfxPoolItem* CreateDefault(); + + SvxTextRotateItem(sal_uInt16 nValue, const sal_uInt16 nId); + + virtual SfxPoolItem* Clone(SfxItemPool *pPool = nullptr) const override; + virtual SfxPoolItem* Create(SvStream &, sal_uInt16) const override; + virtual SvStream& Store(SvStream & rStrm, sal_uInt16 nIVer) const override; + virtual sal_uInt16 GetVersion(sal_uInt16 nFileVersion) const override; + + virtual bool GetPresentation(SfxItemPresentation ePres, + MapUnit eCoreMetric, + MapUnit ePresMetric, + OUString &rText, + const IntlWrapper * = nullptr) const override; + + virtual bool QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId = 0) const override; + virtual bool PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) override; + + SvxTextRotateItem& operator=(const SvxTextRotateItem& rItem) + { + SetValue(rItem.GetValue()); + return *this; + } + + virtual bool operator==(const SfxPoolItem&) const override; + + // our currently only degree values + void SetTopToBottom() { SetValue(2700); } + void SetBottomToTop() { SetValue(900); } + bool IsTopToBottom() const { return 2700 == GetValue(); } + bool IsBottomToTop() const { return 900 == GetValue(); } + bool IsVertical() const { return IsTopToBottom() || IsBottomToTop(); } + + void dumpAsXml(struct _xmlTextWriter* pWriter) const override; +}; + + // class SvxCharRotateItem ---------------------------------------------- /* [Description] @@ -33,7 +82,7 @@ */ -class EDITENG_DLLPUBLIC SvxCharRotateItem : public SfxUInt16Item +class EDITENG_DLLPUBLIC SvxCharRotateItem : public SvxTextRotateItem { bool bFitToLine; public: @@ -66,12 +115,6 @@ public: virtual bool operator==( const SfxPoolItem& ) const override; - // our currently only degree values - void SetTopToBotton() { SetValue( 2700 ); } - void SetBottomToTop() { SetValue( 900 ); } - bool IsTopToBotton() const { return 2700 == GetValue(); } - bool IsBottomToTop() const { return 900 == GetValue(); } - bool IsFitToLine() const { return bFitToLine; } void SetFitToLine( bool b ) { bFitToLine = b; } diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx index d8be7c6..4d77107 100644 --- a/include/editeng/editeng.hxx +++ b/include/editeng/editeng.hxx @@ -237,8 +237,9 @@ public: void SetPaperSize( const Size& rSize ); const Size& GetPaperSize() const; - void SetVertical( bool bVertical ); + void SetVertical( bool bVertical, bool bTopToBottom = true ); bool IsVertical() const; + bool IsTopToBottom() const; void SetFixedCellHeight( bool bUseFixedCellHeight ); diff --git a/include/editeng/editobj.hxx b/include/editeng/editobj.hxx index da35f32..aba1c86 100644 --- a/include/editeng/editobj.hxx +++ b/include/editeng/editobj.hxx @@ -87,7 +87,8 @@ public: void SetUserType( OutlinerMode n ); bool IsVertical() const; - void SetVertical( bool bVertical ); + bool IsTopToBottom() const; + void SetVertical( bool bVertical, bool bTopToBottom = true); SvtScriptType GetScriptType() const; diff --git a/include/editeng/editrids.hrc b/include/editeng/editrids.hrc index cff44d4..522d858 100644 --- a/include/editeng/editrids.hrc +++ b/include/editeng/editrids.hrc @@ -113,6 +113,8 @@ #define RID_SVXITEMS_CHARROTATE_OFF (RID_EDIT_START + 81) #define RID_SVXITEMS_CHARROTATE (RID_EDIT_START + 82) #define RID_SVXITEMS_CHARROTATE_FITLINE (RID_EDIT_START + 83) +#define RID_SVXITEMS_TEXTROTATE_OFF (RID_EDIT_START + 84) +#define RID_SVXITEMS_TEXTROTATE (RID_EDIT_START + 116) #define RID_SVXITEMS_RELIEF_BEGIN (RID_EDIT_START + 85) #define RID_SVXITEMS_RELIEF_NONE (RID_EDIT_START + 85) diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx index dad3d11..ae04cd0 100644 --- a/include/editeng/outliner.hxx +++ b/include/editeng/outliner.hxx @@ -686,8 +686,9 @@ public: void Init( OutlinerMode nOutlinerMode ); OutlinerMode GetMode() const { return nOutlinerMode; } - void SetVertical( bool bVertical ); + void SetVertical( bool bVertical, bool bTopToBottom = true); bool IsVertical() const; + bool IsTopToBottom() const; void SetFixedCellHeight( bool bUseFixedCellHeight ); diff --git a/include/editeng/outlobj.hxx b/include/editeng/outlobj.hxx index 6bde289..b34cf00 100644 --- a/include/editeng/outlobj.hxx +++ b/include/editeng/outlobj.hxx @@ -80,7 +80,8 @@ public: // vertical access bool IsVertical() const; - void SetVertical(bool bNew); + bool IsTopToBottom() const; + void SetVertical(bool bNew, bool bTopToBottom = true); // data read access sal_Int32 Count() const; diff --git a/include/svx/svddef.hxx b/include/svx/svddef.hxx index 0f93472..0d889fe 100644 --- a/include/svx/svddef.hxx +++ b/include/svx/svddef.hxx @@ -296,8 +296,9 @@ #define SDRATTR_TABLE_BORDER_INNER (SDRATTR_TABLE_FIRST+1) #define SDRATTR_TABLE_BORDER_TLBR (SDRATTR_TABLE_FIRST+2) #define SDRATTR_TABLE_BORDER_BLTR (SDRATTR_TABLE_FIRST+3) +#define SDRATTR_TABLE_TEXT_ROTATION (SDRATTR_TABLE_FIRST+4) -#define SDRATTR_TABLE_LAST (SDRATTR_TABLE_BORDER_BLTR) +#define SDRATTR_TABLE_LAST (SDRATTR_TABLE_TEXT_ROTATION) #define SDRATTR_END SDRATTR_TABLE_LAST /* 1357 */ /* 1333 V4+++*/ /* 1243 V4+++*/ /*1213*/ /*1085*/ /*1040*/ /*Pool V2: 1123,V1: 1065 */ diff --git a/oox/source/drawingml/table/tablecell.cxx b/oox/source/drawingml/table/tablecell.cxx index 1c0d086..ebc2ed7 100644 --- a/oox/source/drawingml/table/tablecell.cxx +++ b/oox/source/drawingml/table/tablecell.cxx @@ -467,6 +467,11 @@ void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, cons } getTextBody()->insertAt( rFilterBase, xText, xAt, aTextStyleProps, pMasterTextListStyle ); + + if (getVertToken() == XML_vert) + xPropSet->setPropertyValue("RotateAngle", Any(short(27000))); + else if (getVertToken() == XML_vert270) + xPropSet->setPropertyValue("RotateAngle", Any(short(9000))); } } } } diff --git a/sd/source/ui/func/futext.cxx b/sd/source/ui/func/futext.cxx index 37fb65c..cb9bdc3 100644 --- a/sd/source/ui/func/futext.cxx +++ b/sd/source/ui/func/futext.cxx @@ -1055,7 +1055,9 @@ void FuText::SetInEditMode(const MouseEvent& rMEvt, bool bQuickDrag) if( pTextObj ) { OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject(); - if( ( pOPO && pOPO->IsVertical() ) || (nSlotId == SID_ATTR_CHAR_VERTICAL) || (nSlotId == SID_TEXT_FITTOSIZE_VERTICAL) ) + if( pOPO && pOPO->IsVertical() ) + pOutl->SetVertical( true, pOPO->IsTopToBottom()); + else if (nSlotId == SID_ATTR_CHAR_VERTICAL || nSlotId == SID_TEXT_FITTOSIZE_VERTICAL) pOutl->SetVertical( true ); if( pTextObj->getTextCount() > 1 ) diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx index 196a344..c3519a3 100644 --- a/svx/source/svdraw/svdattr.cxx +++ b/svx/source/svdraw/svdattr.cxx @@ -38,6 +38,7 @@ #include <editeng/adjustitem.hxx> #include <editeng/editdata.hxx> #include <editeng/writingmodeitem.hxx> +#include <editeng/charrotateitem.hxx> #include <i18nutil/unicode.hxx> #include <svl/solar.hrc> #include <tools/bigint.hxx> @@ -319,6 +320,7 @@ SdrItemPool::SdrItemPool( mppLocalPoolDefaults[ SDRATTR_TABLE_BORDER_INNER - SDRATTR_START ] = pBoxInfoItem; mppLocalPoolDefaults[ SDRATTR_TABLE_BORDER_TLBR - SDRATTR_START ] = new SvxLineItem( SDRATTR_TABLE_BORDER_TLBR ); mppLocalPoolDefaults[ SDRATTR_TABLE_BORDER_BLTR - SDRATTR_START ] = new SvxLineItem( SDRATTR_TABLE_BORDER_BLTR ); + mppLocalPoolDefaults[SDRATTR_TABLE_TEXT_ROTATION - SDRATTR_START] = new SvxTextRotateItem(0, SDRATTR_TABLE_TEXT_ROTATION); // set own ItemInfos mpLocalItemInfos[SDRATTR_SHADOW-SDRATTR_START]._nSID=SID_ATTR_FILL_SHADOW; diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx index f052d69..6824c46 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -1384,7 +1384,7 @@ void SdrTextObj::NbcSetOutlinerParaObjectForText( OutlinerParaObject* pTextObjec if (pText && pText->GetOutlinerParaObject()) { - SvxWritingModeItem aWritingMode(pText->GetOutlinerParaObject()->IsVertical() + SvxWritingModeItem aWritingMode(pText->GetOutlinerParaObject()->IsVertical() && pText->GetOutlinerParaObject()->IsTopToBottom() ? css::text::WritingMode_TB_RL : css::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION); diff --git a/svx/source/svdraw/svdotextdecomposition.cxx b/svx/source/svdraw/svdotextdecomposition.cxx index c567477..e97b77cf 100644 --- a/svx/source/svdraw/svdotextdecomposition.cxx +++ b/svx/source/svdraw/svdotextdecomposition.cxx @@ -759,6 +759,7 @@ void SdrTextObj::impDecomposeAutoFitTextPrimitive( const OutlinerParaObject* pOutlinerParaObject = rSdrAutofitTextPrimitive.getSdrText()->GetOutlinerParaObject(); OSL_ENSURE(pOutlinerParaObject, "impDecomposeBlockTextPrimitive used with no OutlinerParaObject (!)"); const bool bVerticalWriting(pOutlinerParaObject->IsVertical()); + const bool bTopToBottom(pOutlinerParaObject->IsTopToBottom()); const Size aAnchorTextSize(Size(nAnchorTextWidth, nAnchorTextHeight)); if((rSdrAutofitTextPrimitive.getWordWrap() || IsTextFrame())) @@ -829,8 +830,9 @@ void SdrTextObj::impDecomposeAutoFitTextPrimitive( // translate relative to given primitive to get same rotation and shear // as the master shape we are working on. For vertical, use the top-right // corner - const double fStartInX(bVerticalWriting ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX()); - aNewTransformA.translate(fStartInX, aAdjustTranslate.getY()); + const double fStartInX(bVerticalWriting && bTopToBottom ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX()); + const double fStartInY(bVerticalWriting && !bTopToBottom ? aAdjustTranslate.getY() + aOutlinerScale.getY() : aAdjustTranslate.getY()); + aNewTransformA.translate(fStartInX, fStartInY); // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y, // move the null point which was top left to bottom right. @@ -922,6 +924,7 @@ void SdrTextObj::impDecomposeBlockTextPrimitive( const sal_uInt32 nAnchorTextWidth(FRound(aAnchorTextRange.getWidth() + 1L)); const sal_uInt32 nAnchorTextHeight(FRound(aAnchorTextRange.getHeight() + 1L)); const bool bVerticalWriting(rSdrBlockTextPrimitive.getOutlinerParaObject().IsVertical()); + const bool bTopToBottom(rSdrBlockTextPrimitive.getOutlinerParaObject().IsTopToBottom()); const Size aAnchorTextSize(Size(nAnchorTextWidth, nAnchorTextHeight)); if(bIsCell) @@ -1082,8 +1085,9 @@ void SdrTextObj::impDecomposeBlockTextPrimitive( // Translate relative to given primitive to get same rotation and shear // as the master shape we are working on. For vertical, use the top-right // corner - const double fStartInX(bVerticalWriting ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX()); - const basegfx::B2DTuple aAdjOffset(fStartInX, aAdjustTranslate.getY()); + const double fStartInX(bVerticalWriting && bTopToBottom ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX()); + const double fStartInY(bVerticalWriting && !bTopToBottom ? aAdjustTranslate.getY() + aOutlinerScale.getY() : aAdjustTranslate.getY()); + const basegfx::B2DTuple aAdjOffset(fStartInX, fStartInY); basegfx::B2DHomMatrix aNewTransformA(basegfx::tools::createTranslateB2DHomMatrix(aAdjOffset.getX(), aAdjOffset.getY())); // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y, @@ -1162,10 +1166,14 @@ void SdrTextObj::impDecomposeStretchTextPrimitive( // needs to translate the text initially around object width to orient // it relative to the topper right instead of the topper left const bool bVertical(rSdrStretchTextPrimitive.getOutlinerParaObject().IsVertical()); + const bool bTopToBottom(rSdrStretchTextPrimitive.getOutlinerParaObject().IsTopToBottom()); if(bVertical) { - aNewTransformA.translate(aScale.getX(), 0.0); + if(bTopToBottom) + aNewTransformA.translate(aScale.getX(), 0.0); + else + aNewTransformA.translate(0.0, aScale.getY()); } // calculate global char stretching scale parameters. Use non-mirrored sizes @@ -1517,6 +1525,7 @@ void SdrTextObj::impDecomposeChainedTextPrimitive( OSL_ENSURE(pOutlinerParaObject, "impDecomposeBlockTextPrimitive used with no OutlinerParaObject (!)"); const bool bVerticalWriting(pOutlinerParaObject->IsVertical()); + const bool bTopToBottom(pOutlinerParaObject->IsTopToBottom()); const Size aAnchorTextSize(Size(nAnchorTextWidth, nAnchorTextHeight)); if(IsTextFrame()) @@ -1593,8 +1602,9 @@ void SdrTextObj::impDecomposeChainedTextPrimitive( // translate relative to given primitive to get same rotation and shear // as the master shape we are working on. For vertical, use the top-right // corner - const double fStartInX(bVerticalWriting ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX()); - aNewTransformA.translate(fStartInX, aAdjustTranslate.getY()); + const double fStartInX(bVerticalWriting && bTopToBottom ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX()); + const double fStartInY(bVerticalWriting && !bTopToBottom ? aAdjustTranslate.getY() + aOutlinerScale.getY() : aAdjustTranslate.getY()); + aNewTransformA.translate(fStartInX, fStartInY); // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y, // move the null point which was top left to bottom right. diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx index 5eaa3f9..3f484d3 100644 --- a/svx/source/table/cell.cxx +++ b/svx/source/table/cell.cxx @@ -51,6 +51,7 @@ #include "svx/unoshape.hxx" #include "editeng/editobj.hxx" #include "editeng/boxitem.hxx" +#include <editeng/charrotateitem.hxx> #include "svx/xflbstit.hxx" #include "svx/xflbmtit.hxx" #include <svx/svdpool.hxx> @@ -89,6 +90,7 @@ static const SvxItemPropertySet* ImplGetSvxCellPropertySet() { OUString("BottomBorder"), SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, BOTTOM_BORDER }, \ { OUString("LeftBorder"), SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, LEFT_BORDER }, \ { OUString("RightBorder"), SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, RIGHT_BORDER }, \ + { OUString("RotateAngle"), SDRATTR_TABLE_TEXT_ROTATION, cppu::UnoType<sal_Int32>::get(), 0, 0 }, \ SVX_UNOEDIT_OUTLINER_PROPERTIES, SVX_UNOEDIT_CHAR_PROPERTIES, @@ -291,7 +293,6 @@ namespace sdr OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, nParaCount); pOutliner->Clear(); - mxCell->SetOutlinerParaObject(pTemp); } @@ -314,8 +315,7 @@ namespace sdr bool bVertical(css::text::WritingMode_TB_RL == static_cast<const SvxWritingModeItem*>(pNewItem)->GetValue()); sdr::table::SdrTableObj& rObj = static_cast<sdr::table::SdrTableObj&>(GetSdrObject()); - if( rObj.IsVerticalWriting() != bVertical ) - rObj.SetVerticalWriting(bVertical); + rObj.SetVerticalWriting(bVertical); // Set a cell vertical property OutlinerParaObject* pParaObj = mxCell->GetEditOutlinerParaObject(); @@ -334,6 +334,50 @@ namespace sdr } } + if (pNewItem && (SDRATTR_TABLE_TEXT_ROTATION == nWhich)) + { + const SvxTextRotateItem* pRotateItem = static_cast<const SvxTextRotateItem*>(pNewItem); + + // Set a cell vertical property + OutlinerParaObject* pParaObj = mxCell->GetEditOutlinerParaObject(); + + const bool bOwnParaObj = pParaObj != nullptr; + + if (pParaObj == nullptr) + pParaObj = mxCell->GetOutlinerParaObject(); + + if (pParaObj) + { + pParaObj->SetVertical(pRotateItem->IsVertical(), pRotateItem->IsTopToBottom()); + + if (bOwnParaObj) + delete pParaObj; + } + + // Change autogrow direction + SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject()); + + // rescue object size + Rectangle aObjectRect = rObj.GetSnapRect(); + + const SfxItemSet& rSet = rObj.GetObjectItemSet(); + bool bAutoGrowWidth = static_cast<const SdrOnOffItem&>(rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH)).GetValue(); + bool bAutoGrowHeight = static_cast<const SdrOnOffItem&>(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue(); + + // prepare ItemSet to set exchanged width and height items + SfxItemSet aNewSet(*rSet.GetPool(), + SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT, + 0, 0); + + aNewSet.Put(rSet); + aNewSet.Put(makeSdrTextAutoGrowWidthItem(bAutoGrowHeight)); + aNewSet.Put(makeSdrTextAutoGrowHeightItem(bAutoGrowWidth)); + rObj.SetObjectItemSet(aNewSet); + + // restore object size + rObj.SetSnapRect(aObjectRect); + } + // call parent AttributeProperties::ItemChange( nWhich, pNewItem ); } @@ -1068,6 +1112,18 @@ void SAL_CALL Cell::setPropertyValue( const OUString& rPropertyName, const Any& mpProperties->SetObjectItem( XFillBmpTileItem( eMode == BitmapMode_REPEAT ) ); return; } + case SDRATTR_TABLE_TEXT_ROTATION: + { + sal_Int32 nRotVal = 0; + if (!(rValue >>= nRotVal)) + throw IllegalArgumentException(); + + if (nRotVal != 27000 && nRotVal != 9000 && nRotVal != 0) + throw IllegalArgumentException(); + + mpProperties->SetObjectItem(SvxTextRotateItem(nRotVal/10, SDRATTR_TABLE_TEXT_ROTATION)); + return; + } default: { SfxItemSet aSet( GetModel()->GetItemPool(), pMap->nWID, pMap->nWID); @@ -1183,6 +1239,11 @@ Any SAL_CALL Cell::getPropertyValue( const OUString& PropertyName ) throw(Unknow return Any( BitmapMode_NO_REPEAT ); } } + case SDRATTR_TABLE_TEXT_ROTATION: + { + const SvxTextRotateItem& rTextRotate = static_cast<const SvxTextRotateItem&>(mpProperties->GetItem(SDRATTR_TABLE_TEXT_ROTATION)); + return Any(sal_Int32(rTextRotate.GetValue() * 10)); + } default: { SfxItemSet aSet( GetModel()->GetItemPool(), pMap->nWID, pMap->nWID); diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx index d53ddff..a4374b9 100644 --- a/svx/source/table/svdotable.cxx +++ b/svx/source/table/svdotable.cxx @@ -1950,9 +1950,9 @@ bool SdrTableObj::IsVerticalWriting() const } -void SdrTableObj::SetVerticalWriting(bool bVertical ) +void SdrTableObj::SetVerticalWriting(bool bVertical) { - if( bVertical != IsVerticalWriting() ) + if(bVertical != IsVerticalWriting() ) { SvxWritingModeItem aModeItem( css::text::WritingMode_LR_TB, SDRATTR_TEXTDIRECTION ); SetObjectItem( aModeItem ); diff --git a/svx/source/unodraw/unoshtxt.cxx b/svx/source/unodraw/unoshtxt.cxx index 3a5705f..b7bd9a66 100644 --- a/svx/source/unodraw/unoshtxt.cxx +++ b/svx/source/unodraw/unoshtxt.cxx @@ -636,7 +636,7 @@ SvxTextForwarder* SvxTextEditSourceImpl::GetBackgroundTextForwarder() mpOutliner->SetStyleSheet( 0, pStyleSheet ); if( bVertical ) - mpOutliner->SetVertical( true ); + mpOutliner->SetVertical( true, pOutlinerParaObject->IsTopToBottom()); } // maybe we have to set the border attributes diff --git a/xmloff/inc/xmlsdtypes.hxx b/xmloff/inc/xmlsdtypes.hxx index 8e388cf..86e81ba 100644 --- a/xmloff/inc/xmlsdtypes.hxx +++ b/xmloff/inc/xmlsdtypes.hxx @@ -117,6 +117,8 @@ ////////////////////////////////////////////////////////////////////////////// +#define XML_SD_TYPE_CELL_ROTATION_ANGLE (XML_SD_TYPES_START + 79 ) + #define CTF_NUMBERINGRULES 1000 #define CTF_CONTROLWRITINGMODE 1001 #define CTF_WRITINGMODE 1002 diff --git a/xmloff/source/draw/sdpropls.cxx b/xmloff/source/draw/sdpropls.cxx index 72d6315..3afbf33 100644 --- a/xmloff/source/draw/sdpropls.cxx +++ b/xmloff/source/draw/sdpropls.cxx @@ -32,6 +32,7 @@ #include <com/sun/star/drawing/BitmapMode.hpp> #include <com/sun/star/text/WritingMode.hpp> +#include <com/sun/star/text/WritingMode2.hpp> #include <xmloff/EnumPropertyHdl.hxx> #include <xmloff/NamedBoolPropertyHdl.hxx> #include <xmloff/WordWrapPropertyHdl.hxx> @@ -62,6 +63,7 @@ #include "XMLPercentOrMeasurePropertyHandler.hxx" #include "animations.hxx" #include <sax/tools/converter.hxx> +#include "xmlsdtypes.hxx" #include "sdxmlexp_impl.hxx" @@ -853,6 +855,52 @@ bool XMLSdHeaderFooterVisibilityTypeHdl::exportXML( return bRet; } +class XMLSdRotationAngleTypeHdl : public XMLPropertyHandler +{ +public: + virtual bool importXML(const OUString& rStrImpValue, css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter) const override; + virtual bool exportXML(OUString& rStrExpValue, const css::uno::Any& rValue, const SvXMLUnitConverter& rUnitConverter) const override; +}; + +bool XMLSdRotationAngleTypeHdl::importXML( + const OUString& rStrImpValue, + css::uno::Any& rValue, + const SvXMLUnitConverter&) const +{ + sal_Int32 nValue; + bool const bRet = ::sax::Converter::convertNumber(nValue, rStrImpValue); + if (bRet) + { + nValue = (nValue % 360); + if (nValue < 0) + nValue = 360 + nValue; + sal_Int32 nAngle; + if (nValue < 45 || nValue > 315) + nAngle = 0; + else if (nValue < 180) + nAngle = 9000; + else /* if nValalue <= 315 ) */ + nAngle = 27000; + + rValue <<= nAngle; + } + return bRet; +} + +bool XMLSdRotationAngleTypeHdl::exportXML( + OUString& rStrExpValue, + const Any& rValue, + const SvXMLUnitConverter&) const +{ + sal_Int32 nAngle; + bool bRet = (rValue >>= nAngle) && nAngle != 0; + if (bRet) + { + rStrExpValue = OUString::number(nAngle / 100); + } + return bRet; +} + XMLSdPropHdlFactory::XMLSdPropHdlFactory( uno::Reference< frame::XModel > const & xModel, SvXMLImport& rImport ) : mxModel( xModel ), mpExport(nullptr), mpImport( &rImport ) { @@ -1154,6 +1202,9 @@ const XMLPropertyHandler* XMLSdPropHdlFactory::GetPropertyHandler( sal_Int32 nTy case XML_SD_TYPE_HEADER_FOOTER_VISIBILITY_TYPE: pHdl = new XMLSdHeaderFooterVisibilityTypeHdl(); break; + case XML_SD_TYPE_CELL_ROTATION_ANGLE: + pHdl = new XMLSdRotationAngleTypeHdl; + break; } if(pHdl) @@ -1276,7 +1327,18 @@ void XMLShapeExportPropertyMapper::ContextFilter( pControlWritingMode = property; break; case CTF_TEXTWRITINGMODE: - pTextWritingMode = property; + { + pTextWritingMode = property; + sal_Int32 eWritingMode; + if (property->maValue >>= eWritingMode) + { + if (text::WritingMode2::LR_TB == eWritingMode) + { + property->mnIndex = -1; + pTextWritingMode = nullptr; + } + } + } break; case CTF_REPEAT_OFFSET_X: pRepeatOffsetX = property; diff --git a/xmloff/source/table/XMLTableExport.cxx b/xmloff/source/table/XMLTableExport.cxx index 4a47857..12d7590 100644 --- a/xmloff/source/table/XMLTableExport.cxx +++ b/xmloff/source/table/XMLTableExport.cxx @@ -44,6 +44,7 @@ #include <xmloff/xmlexppr.hxx> #include <xmloff/xmlexp.hxx> #include <xmloff/xmltypes.hxx> +#include "xmlsdtypes.hxx" #include <xmloff/maptype.hxx> #include <xmloff/prhdlfac.hxx> #include <xmloff/txtprmap.hxx> @@ -62,6 +63,7 @@ using namespace ::com::sun::star::style; #define MAP_(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010, false } #define CMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_COLUMN,context) #define RMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_ROW,context) +#define CELLMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_CELL,context) #define MAP_END { nullptr, 0, 0, XML_EMPTY, 0, 0, SvtSaveOptions::ODFVER_010, false } const XMLPropertyMapEntry* getColumnPropertiesMap() @@ -89,6 +91,17 @@ const XMLPropertyMapEntry* getRowPropertiesMap() return &aXMLRowProperties[0]; } +const XMLPropertyMapEntry* getCellPropertiesMap() +{ + static const XMLPropertyMapEntry aXMLCellProperties[] = + { + CELLMAP( "RotateAngle", XML_NAMESPACE_STYLE, XML_ROTATION_ANGLE, XML_SD_TYPE_CELL_ROTATION_ANGLE, 0), + MAP_END + }; + + return &aXMLCellProperties[0]; +} + class StringStatisticHelper { private: @@ -167,6 +180,7 @@ XMLTableExport::XMLTableExport(SvXMLExport& rExp, const rtl::Reference< SvXMLExp { mxCellExportPropertySetMapper = xExportPropertyMapper; mxCellExportPropertySetMapper->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp)); + mxCellExportPropertySetMapper->ChainExportMapper(new SvXMLExportPropertyMapper(new XMLPropertySetMapper(getCellPropertiesMap(), xFactoryRef.get(), true))); } mxRowExportPropertySetMapper = new SvXMLExportPropertyMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef.get(), true ) ); diff --git a/xmloff/source/table/XMLTableImport.cxx b/xmloff/source/table/XMLTableImport.cxx index d844d2f..4a4d6d9 100644 --- a/xmloff/source/table/XMLTableImport.cxx +++ b/xmloff/source/table/XMLTableImport.cxx @@ -219,6 +219,7 @@ XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLP { mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper.get(), rImport ); mxCellImportPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport)); + mxCellImportPropertySetMapper->ChainImportMapper(new SvXMLImportPropertyMapper(new XMLPropertySetMapper(getCellPropertiesMap(), xFactoryRef.get(), true), rImport)); } rtl::Reference < XMLPropertySetMapper > xRowMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef.get(), false ) ); diff --git a/xmloff/source/table/table.hxx b/xmloff/source/table/table.hxx index cb00e7c..2eddd38 100644 --- a/xmloff/source/table/table.hxx +++ b/xmloff/source/table/table.hxx @@ -34,6 +34,7 @@ extern const TableStyleElement* getTableStyleMap(); extern const TableStyleElement* getWriterSpecificTableStyleMap(); extern const XMLPropertyMapEntry* getColumnPropertiesMap(); extern const XMLPropertyMapEntry* getRowPropertiesMap(); +extern const XMLPropertyMapEntry* getCellPropertiesMap(); #endif -- 2.8.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor