diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-07-10 12:35:44 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-07-12 00:03:38 +0200 |
commit | fb5b05f92e13c064c0af1009d5597d77c949937f (patch) | |
tree | ff78e8d99e2b31fca68fb0c378eaaf35bfaa2f0a /svx | |
parent | 73c20715c10049d6203f4c9f8a279af80dd58dd9 (diff) |
editengine-columns: tdf#143258 Fix handling rotated text
This reverts modifications to existing unit tests made in commit
d0a1616ccad0dd5f5a02c1b0204f537b57d0b4b5. My idea that those changes
were required because of more correct calculations was wrong, and in
fact they were caused by off-by-1 error in height calculations.
Change-Id: Ib94878a911238c977c35a8f8e3e5694cedc79a89
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118705
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118732
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/sdr/primitive2d/sdrdecompositiontools.cxx | 101 | ||||
-rw-r--r-- | svx/source/svdraw/svdoashp.cxx | 6 | ||||
-rw-r--r-- | svx/source/svdraw/svdotext.cxx | 58 |
3 files changed, 115 insertions, 50 deletions
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx index 504862a64229..07a53a0f55d2 100644 --- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx @@ -57,6 +57,72 @@ using namespace com::sun::star; namespace drawinglayer::primitive2d { +namespace +{ +// See also: SdrTextObj::AdjustRectToTextDistance +basegfx::B2DRange getTextAnchorRange(const attribute::SdrTextAttribute& rText, + const basegfx::B2DRange& rSnapRange) +{ + // Take vertical text orientation into account when deciding + // which dimension is its width, and which is its height + const OutlinerParaObject& rOutlinerParaObj = rText.getOutlinerParaObject(); + const bool bVerticalWriting(rOutlinerParaObj.IsVertical()); + const double fWidthForText = bVerticalWriting ? rSnapRange.getHeight() : rSnapRange.getWidth(); + // create a range describing the wanted text position and size (aTextAnchorRange). This + // means to use the text distance values here + // If the margin is larger than the entire width of the text area, then limit the + // margin. + const double fTextLeftDistance + = std::min(static_cast<double>(rText.getTextLeftDistance()), fWidthForText); + const double nTextRightDistance + = std::min(static_cast<double>(rText.getTextRightDistance()), fWidthForText); + double fDistanceForTextL, fDistanceForTextT, fDistanceForTextR, fDistanceForTextB; + if (!bVerticalWriting) + { + fDistanceForTextL = fTextLeftDistance; + fDistanceForTextT = rText.getTextUpperDistance(); + fDistanceForTextR = nTextRightDistance; + fDistanceForTextB = rText.getTextLowerDistance(); + } + else if (rOutlinerParaObj.IsTopToBottom()) + { + fDistanceForTextL = rText.getTextLowerDistance(); + fDistanceForTextT = fTextLeftDistance; + fDistanceForTextR = rText.getTextUpperDistance(); + fDistanceForTextB = nTextRightDistance; + } + else + { + fDistanceForTextL = rText.getTextUpperDistance(); + fDistanceForTextT = nTextRightDistance; + fDistanceForTextR = rText.getTextLowerDistance(); + fDistanceForTextB = fTextLeftDistance; + } + const basegfx::B2DPoint aTopLeft(rSnapRange.getMinX() + fDistanceForTextL, + rSnapRange.getMinY() + fDistanceForTextT); + const basegfx::B2DPoint aBottomRight(rSnapRange.getMaxX() - fDistanceForTextR, + rSnapRange.getMaxY() - fDistanceForTextB); + basegfx::B2DRange aAnchorRange; + aAnchorRange.expand(aTopLeft); + aAnchorRange.expand(aBottomRight); + + // If the shape has no width, then don't attempt to break the text into multiple + // lines, not a single character would satisfy a zero width requirement. + // SdrTextObj::impDecomposeBlockTextPrimitive() uses the same constant to + // effectively set no limits. + if (!bVerticalWriting && aAnchorRange.getWidth() == 0) + { + aAnchorRange.expand(basegfx::B2DPoint(aTopLeft.getX() - 1000000, aTopLeft.getY())); + aAnchorRange.expand(basegfx::B2DPoint(aBottomRight.getX() + 1000000, aBottomRight.getY())); + } + else if (bVerticalWriting && aAnchorRange.getHeight() == 0) + { + aAnchorRange.expand(basegfx::B2DPoint(aTopLeft.getX(), aTopLeft.getY() - 1000000)); + aAnchorRange.expand(basegfx::B2DPoint(aBottomRight.getX(), aBottomRight.getY() + 1000000)); + } + return aAnchorRange; +} +}; class TransparencePrimitive2D; @@ -274,39 +340,8 @@ namespace drawinglayer::primitive2d aJustScaleTransform.set(1, 1, aScale.getY()); basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon); aScaledUnitPolyPolygon.transform(aJustScaleTransform); - const basegfx::B2DRange aSnapRange(basegfx::utils::getRange(aScaledUnitPolyPolygon)); - - // create a range describing the wanted text position and size (aTextAnchorRange). This - // means to use the text distance values here - sal_Int32 nTextLeftDistance = rText.getTextLeftDistance(); - // If the margin is larger than the entire width of the text area, then limit the - // margin. - if (nTextLeftDistance > aSnapRange.getWidth()) - nTextLeftDistance = aSnapRange.getWidth(); - sal_Int32 nTextRightDistance = rText.getTextRightDistance(); - if (nTextRightDistance > aSnapRange.getWidth()) - nTextRightDistance = aSnapRange.getWidth(); - const basegfx::B2DPoint aTopLeft(aSnapRange.getMinX() + nTextLeftDistance, - aSnapRange.getMinY() - + rText.getTextUpperDistance()); - const basegfx::B2DPoint aBottomRight(aSnapRange.getMaxX() - nTextRightDistance, - aSnapRange.getMaxY() - - rText.getTextLowerDistance()); - basegfx::B2DRange aTextAnchorRange; - aTextAnchorRange.expand(aTopLeft); - aTextAnchorRange.expand(aBottomRight); - - if (aTextAnchorRange.getWidth() == 0) - { - // If the shape has no width, then don't attempt to break the text into multiple - // lines, not a single character would satisfy a zero width requirement. - // SdrTextObj::impDecomposeBlockTextPrimitive() uses the same constant to - // effectively set no limits. - aTextAnchorRange.expand( - basegfx::B2DPoint(aTopLeft.getX() - 1000000, aTopLeft.getY())); - aTextAnchorRange.expand( - basegfx::B2DPoint(aBottomRight.getX() + 1000000, aBottomRight.getY())); - } + const basegfx::B2DRange aTextAnchorRange + = getTextAnchorRange(rText, basegfx::utils::getRange(aScaledUnitPolyPolygon)); // now create a transformation from this basic range (aTextAnchorRange) // #i121494# if we have no scale use at least 1.0 to have a carrier e.g. for diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx index 30552b63fa4d..53d180435e9b 100644 --- a/svx/source/svdraw/svdoashp.cxx +++ b/svx/source/svdraw/svdoashp.cxx @@ -2600,11 +2600,7 @@ void SdrObjCustomShape::TakeTextAnchorRect( tools::Rectangle& rAnchorRect ) cons if ( GetTextBounds( rAnchorRect ) ) { Point aRotateRef( maSnapRect.Center() ); - rAnchorRect.AdjustLeft(GetTextLeftDistance() ); - rAnchorRect.AdjustTop(GetTextUpperDistance() ); - rAnchorRect.AdjustRight( -(GetTextRightDistance()) ); - rAnchorRect.AdjustBottom( -(GetTextLowerDistance()) ); - ImpJustifyRect( rAnchorRect ); + AdjustRectToTextDistance(rAnchorRect); if ( rAnchorRect.GetWidth() < 2 ) rAnchorRect.SetRight( rAnchorRect.Left() + 1 ); // minimal width is 2 diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx index 855e07d4c4af..c20417942c0e 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -584,26 +584,49 @@ void SdrTextObj::TakeUnrotatedSnapRect(tools::Rectangle& rRect) const rRect=maRect; } +// See also: <unnamed>::getTextAnchorRange in svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +void SdrTextObj::AdjustRectToTextDistance(tools::Rectangle& rAnchorRect) const +{ + const tools::Long nLeftDist = GetTextLeftDistance(); + const tools::Long nRightDist = GetTextRightDistance(); + const tools::Long nUpperDist = GetTextUpperDistance(); + const tools::Long nLowerDist = GetTextLowerDistance(); + if (!IsVerticalWriting()) + { + rAnchorRect.AdjustLeft(nLeftDist); + rAnchorRect.AdjustTop(nUpperDist); + rAnchorRect.AdjustRight(-nRightDist); + rAnchorRect.AdjustBottom(-nLowerDist); + } + else if (IsTopToBottom()) + { + rAnchorRect.AdjustLeft(nLowerDist); + rAnchorRect.AdjustTop(nLeftDist); + rAnchorRect.AdjustRight(-nUpperDist); + rAnchorRect.AdjustBottom(-nRightDist); + } + else + { + rAnchorRect.AdjustLeft(nUpperDist); + rAnchorRect.AdjustTop(nRightDist); + rAnchorRect.AdjustRight(-nLowerDist); + rAnchorRect.AdjustBottom(-nLeftDist); + } + + // Since sizes may be bigger than the object bounds it is necessary to + // justify the rect now. + ImpJustifyRect(rAnchorRect); +} + void SdrTextObj::TakeTextAnchorRect(tools::Rectangle& rAnchorRect) const { - tools::Long nLeftDist=GetTextLeftDistance(); - tools::Long nRightDist=GetTextRightDistance(); - tools::Long nUpperDist=GetTextUpperDistance(); - tools::Long nLowerDist=GetTextLowerDistance(); tools::Rectangle aAnkRect(maRect); // the rectangle in which we anchor bool bFrame=IsTextFrame(); if (!bFrame) { TakeUnrotatedSnapRect(aAnkRect); } Point aRotateRef(aAnkRect.TopLeft()); - aAnkRect.AdjustLeft(nLeftDist ); - aAnkRect.AdjustTop(nUpperDist ); - aAnkRect.AdjustRight( -nRightDist ); - aAnkRect.AdjustBottom( -nLowerDist ); - - // Since sizes may be bigger than the object bounds it is necessary to - // justify the rect now. - ImpJustifyRect(aAnkRect); + AdjustRectToTextDistance(aAnkRect); if (bFrame) { // TODO: Optimize this. @@ -1525,6 +1548,17 @@ void SdrTextObj::SetVerticalWriting(bool bVertical) SetSnapRect(aObjectRect); } +bool SdrTextObj::IsTopToBottom() const +{ + if (pEdtOutl) + return pEdtOutl->IsTopToBottom(); + + if (OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject()) + return pOutlinerParaObject->IsTopToBottom(); + + return false; +} + // transformation interface for StarOfficeAPI. This implements support for // homogeneous 3x3 matrices containing the transformation of the SdrObject. At the // moment it contains a shearX, rotation and translation, but for setting all linear |