Better handling of text rotation attribute.
We need to have a separate attribute for vertical option and
for rotation option. So rotation won't be lost by setting
the text direction.
So I added a rotation member variable and use that as an orthogonal
variable to the vertical text direction.
A follow-up fix for tdf#100926. The problem was that the rotation
was imported / exported correctly from/in ODP, but the text was not
displayed as rotated.
Change-Id: Icddc0689f06fdcd52df6dc911e02a9a948c42654
Reviewed-on: https://gerrit.libreoffice.org/83809
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
Tested-by: Tamás Zolnai <tamas.zolnai@collabora.com>
diff --git a/editeng/inc/editdoc.hxx b/editeng/inc/editdoc.hxx
index 2924a0e..ccff24f1 100644
--- a/editeng/inc/editdoc.hxx
+++ b/editeng/inc/editdoc.hxx
@@ -38,6 +38,7 @@
class ImpEditEngine;
class SvxTabStop;
enum class TextRotation;
#define CHARPOSGROW 16
@@ -742,7 +743,7 @@ private:
SvxFont aDefFont; //faster than ever from the pool!!
sal_uInt16 nDefTab;
bool bIsVertical:1;
bool bIsTopToBottomVert : 1;
TextRotation mnRotation;
bool bIsFixedCellHeight:1;
bool bOwnerOfPool:1;
@@ -769,10 +770,12 @@ public:
void SetDefTab( sal_uInt16 nTab ) { nDefTab = nTab ? nTab : DEFTAB; }
sal_uInt16 GetDefTab() const { return nDefTab; }
void SetVertical( bool bVertical, bool bTopToBottom )
{ bIsVertical = bVertical; bIsTopToBottomVert = bVertical && bTopToBottom; }
bool IsVertical() const { return bIsVertical; }
bool IsTopToBottom() const { return bIsTopToBottomVert; }
void SetVertical( bool bVertical ) { bIsVertical = bVertical; }
bool IsVertical() const;
bool IsTopToBottom() const;
bool GetDirectVertical() const;
void SetRotation( TextRotation nRotation ) { mnRotation = nRotation; }
TextRotation GetRotation() const { return mnRotation; }
void SetFixedCellHeight( bool bUseFixedCellHeight ) { bIsFixedCellHeight = bUseFixedCellHeight; }
bool IsFixedCellHeight() const { return bIsFixedCellHeight; }
diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx
index ad71436..a745beb 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -1903,7 +1903,7 @@ EditDoc::EditDoc( SfxItemPool* pPool ) :
pItemPool(pPool ? pPool : new EditEngineItemPool()),
nDefTab(DEFTAB),
bIsVertical(false),
bIsTopToBottomVert(false),
mnRotation(TextRotation::NONE),
bIsFixedCellHeight(false),
bOwnerOfPool(pPool == nullptr),
bModified(false)
@@ -2051,6 +2051,23 @@ void EditDoc::CreateDefFont( bool bUseStyles )
}
}
bool EditDoc::IsVertical() const
{
return (bIsVertical && mnRotation == TextRotation::NONE) ||
(!bIsVertical && mnRotation != TextRotation::NONE);
}
bool EditDoc::IsTopToBottom() const
{
return (bIsVertical && mnRotation == TextRotation::NONE) ||
(!bIsVertical && mnRotation == TextRotation::TOPTOBOTTOM);
}
bool EditDoc::GetDirectVertical() const
{
return bIsVertical;
}
sal_Int32 EditDoc::GetPos(const ContentNode* p) const
{
return FastGetPos(maContents, p, nLastCache);
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index ac9fdd5..e7faf82 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -431,9 +431,19 @@ const Size& EditEngine::GetPaperSize() const
return pImpEditEngine->GetPaperSize();
}
void EditEngine::SetVertical( bool bVertical, bool bTopToBottom )
void EditEngine::SetVertical(bool bVertical)
{
pImpEditEngine->SetVertical( bVertical, bTopToBottom);
pImpEditEngine->SetVertical(bVertical);
}
void EditEngine::SetRotation(TextRotation nRotation)
{
pImpEditEngine->SetRotation(nRotation);
}
TextRotation EditEngine::GetRotation() const
{
return pImpEditEngine->GetRotation();
}
bool EditEngine::IsVertical() const
@@ -446,6 +456,11 @@ bool EditEngine::IsTopToBottom() const
return pImpEditEngine->IsTopToBottom();
}
bool EditEngine::GetDirectVertical() const
{
return pImpEditEngine->GetDirectVertical();
}
void EditEngine::SetFixedCellHeight( bool bUseFixedCellHeight )
{
pImpEditEngine->SetFixedCellHeight( bUseFixedCellHeight );
diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx
index eab2d36..9bd5859 100644
--- a/editeng/source/editeng/editobj.cxx
+++ b/editeng/source/editeng/editobj.cxx
@@ -361,14 +361,29 @@ bool EditTextObject::IsVertical() const
return mpImpl->IsVertical();
}
bool EditTextObject::GetDirectVertical() const
{
return mpImpl->GetDirectVertical();
}
bool EditTextObject::IsTopToBottom() const
{
return mpImpl->IsTopToBottom();
}
void EditTextObject::SetVertical( bool bVertical, bool bTopToBottom )
void EditTextObject::SetVertical( bool bVertical )
{
return mpImpl->SetVertical(bVertical, bTopToBottom);
return mpImpl->SetVertical(bVertical);
}
void EditTextObject::SetRotation( TextRotation nRotation )
{
mpImpl->SetRotation(nRotation);
}
TextRotation EditTextObject::GetRotation() const
{
return mpImpl->GetRotation();
}
SvtScriptType EditTextObject::GetScriptType() const
@@ -493,7 +508,7 @@ EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, SfxItemPool* pP
, nUserType(OutlinerMode::DontKnow)
, nScriptType(SvtScriptType::NONE)
, bVertical(false)
, bIsTopToBottomVert(false)
, mnRotation(TextRotation::NONE)
{
// #i101239# ensure target is an EditEngineItemPool, else
// fallback to pool ownership. This is needed to ensure that at
@@ -526,7 +541,7 @@ EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, const EditTextOb
, nUserType(r.nUserType)
, nScriptType(r.nScriptType)
, bVertical(r.bVertical)
, bIsTopToBottomVert(r.bIsTopToBottomVert)
, mnRotation(r.mnRotation)
{
// Do not copy PortionInfo
@@ -606,24 +621,44 @@ std::vector<svl::SharedString> EditTextObjectImpl::GetSharedStrings() const
bool EditTextObjectImpl::IsVertical() const
{
return bVertical;
return (bVertical && mnRotation == TextRotation::NONE) ||
(!bVertical && mnRotation != TextRotation::NONE);
}
bool EditTextObjectImpl::IsTopToBottom() const
{
return bIsTopToBottomVert;
return (bVertical && mnRotation == TextRotation::NONE) ||
(!bVertical && mnRotation == TextRotation::TOPTOBOTTOM);
}
void EditTextObjectImpl::SetVertical( bool bVert, bool bTopToBottom)
void EditTextObjectImpl::SetVertical( bool bVert)
{
if (bVert != bVertical || bTopToBottom != (bVert && bIsTopToBottomVert))
if (bVert != bVertical)
{
bVertical = bVert;
bIsTopToBottomVert = bVert && bTopToBottom;
ClearPortionInfo();
}
}
bool EditTextObjectImpl::GetDirectVertical() const
{
return bVertical;
}
void EditTextObjectImpl::SetRotation(TextRotation nRotation)
{
if (mnRotation != nRotation)
{
mnRotation = nRotation;
ClearPortionInfo();
}
}
TextRotation EditTextObjectImpl::GetRotation() const
{
return mnRotation;
}
void EditTextObjectImpl::SetScriptType( SvtScriptType nType )
{
@@ -1031,7 +1066,7 @@ bool EditTextObjectImpl::Equals( const EditTextObjectImpl& rCompare, bool bCompa
( nUserType!= rCompare.nUserType ) ||
( nScriptType != rCompare.nScriptType ) ||
( bVertical != rCompare.bVertical ) ||
( bIsTopToBottomVert != rCompare.bIsTopToBottomVert ) )
( mnRotation != rCompare.mnRotation ) )
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 e2a1fef..51879ed 100644
--- a/editeng/source/editeng/editobj2.hxx
+++ b/editeng/source/editeng/editobj2.hxx
@@ -189,7 +189,7 @@ private:
bool bOwnerOfPool:1;
bool bVertical:1;
bool bIsTopToBottomVert : 1;
TextRotation mnRotation;
bool ImpChangeStyleSheets( const OUString& rOldName, SfxStyleFamily eOldFamily,
const OUString& rNewName, SfxStyleFamily eNewFamily );
@@ -209,8 +209,11 @@ public:
std::vector<svl::SharedString> GetSharedStrings() const;
bool IsVertical() const;
bool GetDirectVertical() const;
bool IsTopToBottom() const;
void SetVertical( bool bVert, bool bTopToBottom);
void SetVertical( bool bVert);
void SetRotation(TextRotation nRotation);
TextRotation GetRotation() const;
SvtScriptType GetScriptType() const { return nScriptType;}
void SetScriptType( SvtScriptType nType );
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 6980e39..5d3db66 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -744,9 +744,12 @@ public:
const Size& GetPaperSize() const { return aPaperSize; }
void SetPaperSize( const Size& rSz ) { aPaperSize = rSz; }
void SetVertical( bool bVertical, bool bTopToBottom);
void SetVertical( bool bVertical);
bool IsVertical() const { return GetEditDoc().IsVertical(); }
bool IsTopToBottom() const { return GetEditDoc().IsTopToBottom(); }
bool GetDirectVertical() const { return GetEditDoc().GetDirectVertical(); }
void SetRotation( TextRotation nRotation);
TextRotation GetRotation() const { return GetEditDoc().GetRotation(); }
bool IsPageOverflow( ) const;
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index 2128434..4a3ece2 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -2612,11 +2612,11 @@ void ImpEditEngine::SetTextRanger( std::unique_ptr<TextRanger> pRanger )
pActiveView->ShowCursor(false, false);
}
void ImpEditEngine::SetVertical( bool bVertical, bool bTopToBottom)
void ImpEditEngine::SetVertical( bool bVertical)
{
if ( IsVertical() != bVertical || IsTopToBottom() != (bVertical && bTopToBottom))
if ( IsVertical() != bVertical)
{
GetEditDoc().SetVertical( bVertical, bTopToBottom);
GetEditDoc().SetVertical(bVertical);
bool bUseCharAttribs = bool(aStatus.GetControlWord() & EEControlBits::USECHARATTRIBS);
GetEditDoc().CreateDefFont( bUseCharAttribs );
if ( IsFormatted() )
@@ -2627,6 +2627,18 @@ void ImpEditEngine::SetVertical( bool bVertical, bool bTopToBottom)
}
}
void ImpEditEngine::SetRotation(TextRotation nRotation)
{
GetEditDoc().SetRotation(nRotation);
bool bUseCharAttribs = bool(aStatus.GetControlWord() & EEControlBits::USECHARATTRIBS);
GetEditDoc().CreateDefFont( bUseCharAttribs );
if ( IsFormatted() )
{
FormatFullDoc();
UpdateViews( GetActiveView() );
}
}
void ImpEditEngine::SetFixedCellHeight( bool bUseFixedCellHeight )
{
if ( IsFixedCellHeight() != bUseFixedCellHeight )
diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx
index 7db33ba..d6435f9 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -982,7 +982,8 @@ std::unique_ptr<EditTextObject> ImpEditEngine::CreateTextObject(const EditSelect
std::unique_ptr<EditTextObject> ImpEditEngine::CreateTextObject( EditSelection aSel, SfxItemPool* pPool, bool bAllowBigObjects, sal_Int32 nBigObjectStart )
{
std::unique_ptr<EditTextObject> pTxtObj(new EditTextObject(pPool));
pTxtObj->SetVertical( IsVertical(), IsTopToBottom());
pTxtObj->SetVertical( GetDirectVertical() );
pTxtObj->SetRotation( GetRotation() );
MapUnit eMapUnit = aEditDoc.GetItemPool().GetMetric( DEF_METRIC );
pTxtObj->mpImpl->SetMetric( static_cast<sal_uInt16>(eMapUnit) );
if ( pTxtObj->mpImpl->IsOwnerOfPool() )
@@ -1141,7 +1142,8 @@ void ImpEditEngine::SetText( const EditTextObject& rTextObject )
EnableUndo( false );
InsertText( rTextObject, EditSelection( aPaM, aPaM ) );
SetVertical( rTextObject.IsVertical(), rTextObject.IsTopToBottom());
SetVertical(rTextObject.GetDirectVertical());
SetRotation(rTextObject.GetRotation());
DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "From where comes the Undo in SetText ?!" );
SetUpdateMode( _bUpdate );
diff --git a/editeng/source/outliner/outlin2.cxx b/editeng/source/outliner/outlin2.cxx
index 8718c00..efdbc2a 100644
--- a/editeng/source/outliner/outlin2.cxx
+++ b/editeng/source/outliner/outlin2.cxx
@@ -517,9 +517,14 @@ const EditEngine& Outliner::GetEditEngine() const
return *pEditEngine;
}
void Outliner::SetVertical( bool bVertical, bool bTopToBottom)
void Outliner::SetVertical(bool bVertical)
{
pEditEngine->SetVertical(bVertical, bTopToBottom);
pEditEngine->SetVertical(bVertical);
}
void Outliner::SetRotation(TextRotation nRotation)
{
pEditEngine->SetRotation(nRotation);
}
bool Outliner::IsVertical() const
diff --git a/editeng/source/outliner/outlobj.cxx b/editeng/source/outliner/outlobj.cxx
index 2320612..d402666 100644
--- a/editeng/source/outliner/outlobj.cxx
+++ b/editeng/source/outliner/outlobj.cxx
@@ -135,20 +135,33 @@ bool OutlinerParaObject::IsVertical() const
return mpImpl->mpEditTextObject->IsVertical();
}
bool OutlinerParaObject::GetDirectVertical() const
{
return mpImpl->mpEditTextObject->GetDirectVertical();
}
bool OutlinerParaObject::IsTopToBottom() const
{
return mpImpl->mpEditTextObject->IsTopToBottom();
}
void OutlinerParaObject::SetVertical(bool bNew, bool bTopToBottom)
void OutlinerParaObject::SetVertical(bool bNew)
{
const ::o3tl::cow_wrapper< OutlinerParaObjData >* pImpl = &mpImpl;
if ( ( *pImpl )->mpEditTextObject->IsVertical() != bNew ||
(*pImpl)->mpEditTextObject->IsTopToBottom() != (bNew && bTopToBottom))
if ( ( *pImpl )->mpEditTextObject->IsVertical() != bNew)
{
mpImpl->mpEditTextObject->SetVertical(bNew, bTopToBottom);
mpImpl->mpEditTextObject->SetVertical(bNew);
}
}
void OutlinerParaObject::SetRotation(TextRotation nRotation)
{
mpImpl->mpEditTextObject->SetRotation(nRotation);
}
TextRotation OutlinerParaObject::GetRotation() const
{
return mpImpl->mpEditTextObject->GetRotation();
}
sal_Int32 OutlinerParaObject::Count() const
{
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index 414c0ef..368fae7 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -229,9 +229,12 @@ public:
void SetPaperSize( const Size& rSize );
const Size& GetPaperSize() const;
void SetVertical( bool bVertical, bool bTopToBottom = true );
void SetVertical( bool bVertical );
bool IsVertical() const;
bool IsTopToBottom() const;
bool GetDirectVertical() const;
void SetRotation(TextRotation nRotation);
TextRotation GetRotation() const;
void SetFixedCellHeight( bool bUseFixedCellHeight );
diff --git a/include/editeng/editobj.hxx b/include/editeng/editobj.hxx
index b098326..f635a93 100644
--- a/include/editeng/editobj.hxx
+++ b/include/editeng/editobj.hxx
@@ -52,6 +52,8 @@ class SharedStringPool;
}
enum class TextRotation { NONE, TOPTOBOTTOM, BOTTOMTOTOP };
class EditTextObjectImpl;
class EDITENG_DLLPUBLIC EditTextObject final : public SfxItemPoolUser
@@ -83,8 +85,11 @@ public:
void SetUserType( OutlinerMode n );
bool IsVertical() const;
bool GetDirectVertical() const;
bool IsTopToBottom() const;
void SetVertical( bool bVertical, bool bTopToBottom = true);
void SetVertical( bool bVertical );
void SetRotation( TextRotation nRotation );
TextRotation GetRotation() const;
SvtScriptType GetScriptType() const;
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index acb4849..70c08e5 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -75,6 +75,7 @@ enum class TransliterationFlags;
class SvxFieldData;
enum class PointerStyle;
class SvxNumRule;
enum class TextRotation;
namespace com { namespace sun { namespace star { namespace linguistic2 {
class XSpellChecker1;
@@ -653,7 +654,8 @@ public:
void Init( OutlinerMode nOutlinerMode );
OutlinerMode GetMode() const { return nOutlinerMode; }
void SetVertical( bool bVertical, bool bTopToBottom = true);
void SetVertical( bool bVertical);
void SetRotation(TextRotation nRotation);
bool IsVertical() const;
bool IsTopToBottom() const;
diff --git a/include/editeng/outlobj.hxx b/include/editeng/outlobj.hxx
index a28e255..98414de 100644
--- a/include/editeng/outlobj.hxx
+++ b/include/editeng/outlobj.hxx
@@ -30,6 +30,7 @@
class EditTextObject;
enum class OutlinerMode;
enum class TextRotation;
/**
* This is the guts of OutlinerParaObject, refcounted and shared among
@@ -88,8 +89,11 @@ public:
// vertical access
bool IsVertical() const;
bool GetDirectVertical() const;
bool IsTopToBottom() const;
void SetVertical(bool bNew, bool bTopToBottom = true);
void SetVertical(bool bNew);
void SetRotation(TextRotation nRotation);
TextRotation GetRotation() const;
// data read access
sal_Int32 Count() const;
diff --git a/sd/source/ui/func/futext.cxx b/sd/source/ui/func/futext.cxx
index 3d5abb8..30aa80e 100644
--- a/sd/source/ui/func/futext.cxx
+++ b/sd/source/ui/func/futext.cxx
@@ -1078,7 +1078,10 @@ void FuText::SetInEditMode(const MouseEvent& rMEvt, bool bQuickDrag)
{
OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject();
if( pOPO && pOPO->IsVertical() )
pOutl->SetVertical( true, pOPO->IsTopToBottom());
{
pOutl->SetVertical(pOPO->GetDirectVertical());
pOutl->SetRotation(pOPO->GetRotation());
}
else if (nSlotId == SID_ATTR_CHAR_VERTICAL || nSlotId == SID_TEXT_FITTOSIZE_VERTICAL)
pOutl->SetVertical( true );
diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx
index 8b01fa9..f16b5a4 100644
--- a/svx/source/table/cell.cxx
+++ b/svx/source/table/cell.cxx
@@ -341,7 +341,12 @@ namespace sdr
if (pParaObj)
{
pParaObj->SetVertical(pRotateItem->IsVertical(), pRotateItem->IsTopToBottom());
if(pRotateItem->IsVertical() && pRotateItem->IsTopToBottom())
pParaObj->SetRotation(TextRotation::TOPTOBOTTOM);
else if (pRotateItem->IsVertical())
pParaObj->SetRotation(TextRotation::BOTTOMTOTOP);
else
pParaObj->SetRotation(TextRotation::NONE);
if (bOwnParaObj)
delete pParaObj;
diff --git a/svx/source/unodraw/unoshtxt.cxx b/svx/source/unodraw/unoshtxt.cxx
index 64e1301..ab46fbb 100644
--- a/svx/source/unodraw/unoshtxt.cxx
+++ b/svx/source/unodraw/unoshtxt.cxx
@@ -575,7 +575,10 @@ SvxTextForwarder* SvxTextEditSourceImpl::GetBackgroundTextForwarder()
mpOutliner->SetStyleSheet( 0, pStyleSheet );
if( bVertical )
mpOutliner->SetVertical( true, pOutlinerParaObject->IsTopToBottom());
{
mpOutliner->SetVertical( pOutlinerParaObject->GetDirectVertical());
mpOutliner->SetRotation( pOutlinerParaObject->GetRotation());
}
}
// maybe we have to set the border attributes