summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editeng/source/items/svxfont.cxx74
-rw-r--r--include/editeng/svxfont.hxx7
-rw-r--r--sc/inc/fillinfo.hxx4
-rw-r--r--sc/qa/unit/data/xlsx/tdf119292.xlsxbin0 -> 10764 bytes
-rw-r--r--sc/qa/unit/subsequent_filters-test.cxx41
-rw-r--r--sc/source/ui/inc/output.hxx7
-rw-r--r--sc/source/ui/view/output.cxx44
-rw-r--r--sc/source/ui/view/output2.cxx64
8 files changed, 171 insertions, 70 deletions
diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx
index f5d0e2d79a26..61039b316ac6 100644
--- a/editeng/source/items/svxfont.cxx
+++ b/editeng/source/items/svxfont.cxx
@@ -86,32 +86,62 @@ void SvxFont::SetNonAutoEscapement(short nNewEsc, const OutputDevice* pOutDev)
nEsc = -MAX_ESC_POS;
}
-void SvxFont::DrawArrow( OutputDevice &rOut, const tools::Rectangle& rRect,
- const Size& rSize, const Color& rCol, bool bLeft )
+tools::Polygon SvxFont::DrawArrow( OutputDevice &rOut, const tools::Rectangle& rRect,
+ const Size& rSize, const Color& rCol, bool bLeftOrTop, bool bVertical )
{
- tools::Long nLeft = ( rRect.Left() + rRect.Right() - rSize.Width() )/ 2;
- tools::Long nRight = nLeft + rSize.Width();
- tools::Long nMid = ( rRect.Top() + rRect.Bottom() ) / 2;
- tools::Long nTop = nMid - rSize.Height() / 2;
- tools::Long nBottom = nTop + rSize.Height();
- if( nLeft < rRect.Left() )
+ tools::Polygon aPoly;
+ Point aTmp;
+ Point aNxt;
+ if (bVertical)
{
- nLeft = rRect.Left();
- nRight = rRect.Right();
+ tools::Long nLeft = ((rRect.Left() + rRect.Right()) / 2) - (rSize.Height() / 2);
+ tools::Long nRight = ((rRect.Left() + rRect.Right()) / 2) + (rSize.Height() / 2);
+ tools::Long nMid = (rRect.Left() + rRect.Right()) / 2;
+ tools::Long nTop = ((rRect.Top() + rRect.Bottom()) / 2) - (rSize.Height() / 2);
+ tools::Long nBottom = nTop + rSize.Height();
+ if (nTop < rRect.Top())
+ {
+ if (bLeftOrTop)
+ {
+ nTop = rRect.Top();
+ nBottom = rRect.Bottom();
+ }
+ else
+ {
+ nTop = rRect.Bottom();
+ nBottom = rRect.Bottom() - (rSize.Height() / 2);
+ }
+ }
+ aTmp.setX(nRight);
+ aTmp.setY(nBottom);
+ aNxt.setX(nMid);
+ aNxt.setY(nTop);
+ aPoly.Insert(0, aTmp);
+ aPoly.Insert(0, aNxt);
+ aTmp.setX(nLeft);
+ aPoly.Insert(0, aTmp);
}
- if( nTop < rRect.Top() )
+ else
{
- nTop = rRect.Top();
- nBottom = rRect.Bottom();
+ tools::Long nLeft = (rRect.Left() + rRect.Right() - rSize.Width()) / 2;
+ tools::Long nRight = nLeft + rSize.Width();
+ tools::Long nMid = (rRect.Top() + rRect.Bottom()) / 2;
+ tools::Long nTop = nMid - rSize.Height() / 2;
+ tools::Long nBottom = nTop + rSize.Height();
+ if (nLeft < rRect.Left())
+ {
+ nLeft = rRect.Left();
+ nRight = rRect.Right();
+ }
+ aTmp.setX(bLeftOrTop ? nLeft : nRight);
+ aTmp.setY(nMid);
+ aNxt.setX(bLeftOrTop ? nRight : nLeft);
+ aNxt.setY(nTop);
+ aPoly.Insert(0, aTmp);
+ aPoly.Insert(0, aNxt);
+ aNxt.setY(nBottom);
+ aPoly.Insert(0, aNxt);
}
- tools::Polygon aPoly;
- Point aTmp( bLeft ? nLeft : nRight, nMid );
- Point aNxt( bLeft ? nRight : nLeft, nTop );
- aPoly.Insert( 0, aTmp );
- aPoly.Insert( 0, aNxt );
- aNxt.setY( nBottom );
- aPoly.Insert( 0, aNxt );
- aPoly.Insert( 0, aTmp );
Color aOldLineColor = rOut.GetLineColor();
Color aOldFillColor = rOut.GetFillColor();
rOut.SetFillColor( rCol );
@@ -120,9 +150,9 @@ void SvxFont::DrawArrow( OutputDevice &rOut, const tools::Rectangle& rRect,
rOut.DrawLine( aTmp, aNxt );
rOut.SetLineColor( aOldLineColor );
rOut.SetFillColor( aOldFillColor );
+ return aPoly;
}
-
OUString SvxFont::CalcCaseMap(const OUString &rTxt) const
{
if (!IsCaseMap() || rTxt.isEmpty())
diff --git a/include/editeng/svxfont.hxx b/include/editeng/svxfont.hxx
index c8e8c6670b12..b385ada1592d 100644
--- a/include/editeng/svxfont.hxx
+++ b/include/editeng/svxfont.hxx
@@ -23,6 +23,7 @@
#include <tools/long.hxx>
#include <vcl/font.hxx>
#include <editeng/editengdllapi.h>
+#include <tools/poly.hxx>
// Percentage of height of lower case small capital letters compared to upper case letters
// See i#1526# for full explanation
@@ -103,8 +104,10 @@ public:
const Point &rPos, const OUString &rTxt,
const sal_Int32 nIdx = 0, const sal_Int32 nLen = SAL_MAX_INT32 ) const;
- static void DrawArrow( OutputDevice &rOut, const tools::Rectangle& rRect,
- const Size& rSize, const Color& rCol, bool bLeft );
+ static tools::Polygon DrawArrow( OutputDevice &rOut, const tools::Rectangle& rRect,
+ const Size& rSize, const Color& rCol, bool bLeftOrTop,
+ bool bVertical );
+
SvxFont& operator=( const SvxFont& rFont );
SvxFont& operator=( const Font& rFont );
};
diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx
index e18e3f545536..c4f995c21c1d 100644
--- a/sc/inc/fillinfo.hxx
+++ b/sc/inc/fillinfo.hxx
@@ -42,10 +42,10 @@ enum class ScRotateDir : sal_uInt8 {
};
enum class ScClipMark : sal_uInt8 {
- NONE = 0x00, Left = 0x01, Right = 0x02
+ NONE = 0x00, Left = 0x01, Right = 0x02, Bottom = 0x03, Top = 0x04
};
namespace o3tl {
- template<> struct typed_flags<ScClipMark> : is_typed_flags<ScClipMark, 0x03> {};
+ template<> struct typed_flags<ScClipMark> : is_typed_flags<ScClipMark, 0x07> {};
}
const sal_uInt8 SC_CLIPMARK_SIZE = 64;
diff --git a/sc/qa/unit/data/xlsx/tdf119292.xlsx b/sc/qa/unit/data/xlsx/tdf119292.xlsx
new file mode 100644
index 000000000000..cf3d3dc08dbb
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/tdf119292.xlsx
Binary files differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 0807f29a3587..3d886c7b10fb 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -109,6 +109,7 @@ public:
//ods, xls, xlsx filter tests
void testCondFormatOperatorsSameRangeXLSX();
+ void testTdf119292();
void testCondFormatFormulaIsXLSX();
void testCondFormatBeginsAndEndsWithXLSX();
void testExtCondFormatXLSX();
@@ -316,6 +317,7 @@ public:
CPPUNIT_TEST_SUITE(ScFiltersTest);
CPPUNIT_TEST(testCondFormatOperatorsSameRangeXLSX);
+ CPPUNIT_TEST(testTdf119292);
CPPUNIT_TEST(testCondFormatFormulaIsXLSX);
CPPUNIT_TEST(testCondFormatBeginsAndEndsWithXLSX);
CPPUNIT_TEST(testExtCondFormatXLSX);
@@ -582,21 +584,54 @@ void ScFiltersTest::testCondFormatOperatorsSameRangeXLSX()
CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
const ScCondFormatEntry* pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
- CPPUNIT_ASSERT_EQUAL( ScConditionMode::ContainsText, pCondition->GetOperation());
+ CPPUNIT_ASSERT_EQUAL(ScConditionMode::ContainsText, pCondition->GetOperation());
pEntry = pFormat->GetEntry(1);
CPPUNIT_ASSERT(pEntry);
CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
- CPPUNIT_ASSERT_EQUAL( ScConditionMode::BeginsWith, pCondition->GetOperation());
+ CPPUNIT_ASSERT_EQUAL(ScConditionMode::BeginsWith, pCondition->GetOperation());
pEntry = pFormat->GetEntry(2);
CPPUNIT_ASSERT(pEntry);
CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
- CPPUNIT_ASSERT_EQUAL( ScConditionMode::EndsWith, pCondition->GetOperation());
+ CPPUNIT_ASSERT_EQUAL(ScConditionMode::EndsWith, pCondition->GetOperation());
+
+ xDocSh->DoClose();
+}
+
+void ScFiltersTest::testTdf119292()
+{
+ ScDocShellRef xDocSh = loadDoc(u"tdf119292.", FORMAT_XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load tdf119292.xlsx", xDocSh.is());
+
+ ScDocument& rDoc = xDocSh->GetDocument();
+ auto* pDev = rDoc.GetRefDevice();
+ Size aMarkSize(4, 6);
+ Color aArrowFillCol(COL_LIGHTRED);
+
+ // check the points of the polygon if the text is rotated 90 degrees
+ tools::Rectangle aMarkRect1(0, 0, 45, 3);
+ tools::Polygon aPoly90degrees = SvxFont::DrawArrow(*pDev, aMarkRect1, aMarkSize, aArrowFillCol, true, true);
+ Point aPoly90Pos1 = aPoly90degrees.GetPoint(0);
+ Point aPoly90Pos2 = aPoly90degrees.GetPoint(1);
+ Point aPoly90Pos3 = aPoly90degrees.GetPoint(2);
+ CPPUNIT_ASSERT_EQUAL(Point(19,3),aPoly90Pos1);
+ CPPUNIT_ASSERT_EQUAL(Point(22,0),aPoly90Pos2);
+ CPPUNIT_ASSERT_EQUAL(Point(25,3),aPoly90Pos3);
+
+ // check the points of the polygon if the text is rotated 270 degrees
+ tools::Rectangle aMarkRect2(89, 62, 134, 57);
+ tools::Polygon aPoly270degrees = SvxFont::DrawArrow(*pDev, aMarkRect2, aMarkSize, aArrowFillCol, false, true);
+ Point aPoly270Pos1 = aPoly270degrees.GetPoint(0);
+ Point aPoly270Pos2 = aPoly270degrees.GetPoint(1);
+ Point aPoly270Pos3 = aPoly270degrees.GetPoint(2);
+ CPPUNIT_ASSERT_EQUAL(Point(108,54),aPoly270Pos1);
+ CPPUNIT_ASSERT_EQUAL(Point(111,57),aPoly270Pos2);
+ CPPUNIT_ASSERT_EQUAL(Point(114,54),aPoly270Pos3);
xDocSh->DoClose();
}
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index e45fe29e14ac..b3079259f8b0 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -231,6 +231,7 @@ private:
bool bSnapPixel;
bool bAnyClipped; // internal
+ bool bVertical;
bool bTabProtected;
bool bLayoutRTL;
@@ -277,11 +278,11 @@ private:
std::unique_ptr<ScFieldEditEngine> CreateOutputEditEngine();
- void ShowClipMarks( DrawEditParam& rParam, tools::Long nEngineHeight, const Size& aCellSize,
- bool bMerged, OutputAreaParam& aAreaParam );
+ void ShowClipMarks( DrawEditParam& rParam, tools::Long nEngineWidth, const Size& aCellSize,
+ bool bMerged, OutputAreaParam& aAreaParam, bool bTop );
ClearableClipRegionPtr Clip(DrawEditParam& rParam, const Size& aCellSize, OutputAreaParam& aAreaParam,
- tools::Long nEngineHeight, bool bWrapFields);
+ tools::Long nEngineWidth, bool bWrapFields, bool bTop);
bool AdjustAreaParamClipRect(OutputAreaParam& rAreaParam);
tools::Long SetEngineTextAndGetWidth( DrawEditParam& rParam, const OUString& rSetString,
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index b73b2fd0980b..fc1750f53e14 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -173,6 +173,7 @@ ScOutputData::ScOutputData( OutputDevice* pNewDev, ScOutputType eNewType,
bMarkClipped( false ), // sal_False for printer/metafile etc.
bSnapPixel( false ),
bAnyClipped( false ),
+ bVertical(false),
mpTargetPaintWindow(nullptr), // #i74769# use SdrPaintWindow direct
mpSpellCheckCxt(nullptr)
{
@@ -2552,19 +2553,42 @@ void ScOutputData::DrawClipMarks()
tools::Long nMarkPixel = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTX );
Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
- if ( pInfo->nClipMark & ( bLayoutRTL ? ScClipMark::Right : ScClipMark::Left ) )
+ if (bVertical)
{
- // visually left
- tools::Rectangle aMarkRect = aCellRect;
- aMarkRect.SetRight( aCellRect.Left()+nMarkPixel-1 );
- SvxFont::DrawArrow( *mpDev, aMarkRect, aMarkSize, aArrowFillCol, true );
+ if (pInfo->nClipMark & (bLayoutRTL ? ScClipMark::Bottom : ScClipMark::Top))
+ {
+ // visually top
+ tools::Rectangle aMarkRect = aCellRect;
+ aMarkRect.SetBottom(aCellRect.Top() + nMarkPixel - 1);
+ SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, true, true);
+ }
+ if (pInfo->nClipMark & (bLayoutRTL ? ScClipMark::Top : ScClipMark::Bottom))
+ {
+ // visually bottom
+ tools::Rectangle aMarkRect = aCellRect;
+ aMarkRect.SetTop(aCellRect.Bottom() + nMarkPixel + 1);
+ SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, false,
+ true);
+ }
}
- if ( pInfo->nClipMark & ( bLayoutRTL ? ScClipMark::Left : ScClipMark::Right ) )
+ else
{
- // visually right
- tools::Rectangle aMarkRect = aCellRect;
- aMarkRect.SetLeft( aCellRect.Right()-nMarkPixel+1 );
- SvxFont::DrawArrow( *mpDev, aMarkRect, aMarkSize, aArrowFillCol, false );
+ if (pInfo->nClipMark & (bLayoutRTL ? ScClipMark::Right : ScClipMark::Left))
+ {
+ // visually left
+ tools::Rectangle aMarkRect = aCellRect;
+ aMarkRect.SetRight(aCellRect.Left() + nMarkPixel - 1);
+ SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, true,
+ false);
+ }
+ if (pInfo->nClipMark & (bLayoutRTL ? ScClipMark::Left : ScClipMark::Right))
+ {
+ // visually right
+ tools::Rectangle aMarkRect = aCellRect;
+ aMarkRect.SetLeft(aCellRect.Right() - nMarkPixel + 1);
+ SvxFont::DrawArrow(*mpDev, aMarkRect, aMarkSize, aArrowFillCol, false,
+ false);
+ }
}
}
nPosX += pRowInfo[0].pCellInfo[nX+1].nWidth * nLayoutSign;
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 4d5003bdc02e..e2726517a874 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -3186,48 +3186,56 @@ void ScOutputData::DrawEditStandard(DrawEditParam& rParam)
rParam.adjustForHyperlinkInPDF(aURLStart, mpDev);
}
-void ScOutputData::ShowClipMarks( DrawEditParam& rParam, tools::Long nEngineHeight, const Size& aCellSize,
- bool bMerged, OutputAreaParam& aAreaParam)
+void ScOutputData::ShowClipMarks( DrawEditParam& rParam, tools::Long nEngineWidth, const Size& aCellSize,
+ bool bMerged, OutputAreaParam& aAreaParam, bool bTop)
{
- // Show clip marks if height is at least 5pt too small and
+ // Show clip marks if width is at least 5pt too small and
// there are several lines of text.
// Not for asian vertical text, because that would interfere
// with the default right position of the text.
// Only with automatic line breaks, to avoid having to find
// the cells with the horizontal end of the text again.
- if ( !(nEngineHeight - aCellSize.Height() > 100 &&
- rParam.mbBreak && bMarkClipped &&
- ( rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1 )) )
- return;
-
- CellInfo* pClipMarkCell = nullptr;
- if ( bMerged )
+ if (nEngineWidth - aCellSize.Width() > 100 && rParam.mbBreak && bMarkClipped
+ && (rParam.mpEngine->GetParagraphCount() > 1 || rParam.mpEngine->GetLineCount(0) > 1))
{
- // anywhere in the merged area...
- SCCOL nClipX = ( rParam.mnX < nX1 ) ? nX1 : rParam.mnX;
- pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX+1];
- }
- else
- pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX+1];
-
- pClipMarkCell->nClipMark |= ScClipMark::Right; //! also allow left?
- bAnyClipped = true;
+ CellInfo* pClipMarkCell = nullptr;
+ if (bMerged)
+ {
+ // anywhere in the merged area...
+ SCCOL nClipX = (rParam.mnX < nX1) ? nX1 : rParam.mnX;
+ pClipMarkCell = &pRowInfo[(rParam.mnArrY != 0) ? rParam.mnArrY : 1].pCellInfo[nClipX + 1];
+ }
+ else
+ pClipMarkCell = &rParam.mpThisRowInfo->pCellInfo[rParam.mnX + 1];
- const tools::Long nMarkPixel = static_cast<tools::Long>( SC_CLIPMARK_SIZE * mnPPTX );
- if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() )
- aAreaParam.maClipRect.AdjustRight( -nMarkPixel );
+ bAnyClipped = true;
+ bVertical = true;
+ const tools::Long nMarkPixel = static_cast<tools::Long>(SC_CLIPMARK_SIZE * mnPPTX);
+ if (bTop)
+ {
+ pClipMarkCell->nClipMark |= ScClipMark::Top;
+ if (aAreaParam.maClipRect.Top() - nMarkPixel < aAreaParam.maClipRect.Bottom())
+ aAreaParam.maClipRect.AdjustTop(+nMarkPixel);
+ }
+ else
+ {
+ pClipMarkCell->nClipMark |= ScClipMark::Bottom;
+ if (aAreaParam.maClipRect.Top() - nMarkPixel < aAreaParam.maClipRect.Bottom())
+ aAreaParam.maClipRect.AdjustBottom(-nMarkPixel);
+ }
+ }
}
ClearableClipRegionPtr ScOutputData::Clip( DrawEditParam& rParam, const Size& aCellSize,
- OutputAreaParam& aAreaParam, tools::Long nEngineHeight,
- bool bWrapFields)
+ OutputAreaParam& aAreaParam, tools::Long nEngineWidth,
+ bool bWrapFields, bool bTop)
{
// Also take fields in a cell with automatic breaks into account: clip to cell width
bool bClip = AdjustAreaParamClipRect(aAreaParam) || aAreaParam.mbLeftClip || aAreaParam.mbRightClip || bWrapFields;
bool bSimClip = false;
const Size& aRefOne = mpRefDevice->PixelToLogic(Size(1,1));
- if ( nEngineHeight >= aCellSize.Height() + aRefOne.Height() )
+ if ( nEngineWidth >= aCellSize.Width() + aRefOne.Width() )
{
const ScMergeAttr* pMerge = &rParam.mpPattern->GetItem(ATTR_MERGE);
const bool bMerged = pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1;
@@ -3243,7 +3251,7 @@ ClearableClipRegionPtr ScOutputData::Clip( DrawEditParam& rParam, const Size& aC
else
bSimClip = true;
- ShowClipMarks( rParam, nEngineHeight, aCellSize, bMerged, aAreaParam);
+ ShowClipMarks( rParam, nEngineWidth, aCellSize, bMerged, aAreaParam, bTop);
}
// Clip marks are already handled in GetOutputArea
@@ -3425,7 +3433,7 @@ void ScOutputData::DrawEditBottomTop(DrawEditParam& rParam)
Point aURLStart;
{
- const auto pClipRegion = Clip( rParam, aCellSize, aAreaParam, nEngineHeight, bWrapFields );
+ const auto pClipRegion = Clip( rParam, aCellSize, aAreaParam, nEngineWidth, bWrapFields, true );
Point aLogicStart(nStartX, nStartY);
rParam.calcStartPosForVertical(aLogicStart, aCellSize.Width(), nEngineWidth, nTopM, mpRefDevice);
@@ -3671,7 +3679,7 @@ void ScOutputData::DrawEditTopBottom(DrawEditParam& rParam)
Point aURLStart;
{
- const auto pClipRegion = Clip( rParam, aCellSize, aAreaParam, nEngineHeight, bWrapFields );
+ const auto pClipRegion = Clip( rParam, aCellSize, aAreaParam, nEngineWidth, bWrapFields, false );
Point aLogicStart(nStartX, nStartY);
rParam.calcStartPosForVertical(aLogicStart, aCellSize.Width(), nEngineWidth, nTopM, mpRefDevice);