diff options
-rw-r--r-- | sw/qa/core/draw/data/tdf107727_FrameBorder.odt | bin | 0 -> 11265 bytes | |||
-rw-r--r-- | sw/qa/core/draw/draw.cxx | 43 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfattributeoutput.cxx | 52 |
3 files changed, 78 insertions, 17 deletions
diff --git a/sw/qa/core/draw/data/tdf107727_FrameBorder.odt b/sw/qa/core/draw/data/tdf107727_FrameBorder.odt Binary files differnew file mode 100644 index 000000000000..6b7bc3a375fa --- /dev/null +++ b/sw/qa/core/draw/data/tdf107727_FrameBorder.odt diff --git a/sw/qa/core/draw/draw.cxx b/sw/qa/core/draw/draw.cxx index 97b6a2bb7d79..c2514808f8e4 100644 --- a/sw/qa/core/draw/draw.cxx +++ b/sw/qa/core/draw/draw.cxx @@ -10,6 +10,7 @@ #include <swmodeltestbase.hxx> #include <svx/svdpage.hxx> +#include <unotools/mediadescriptor.hxx> #include <IDocumentDrawModelAccess.hxx> #include <docsh.hxx> @@ -18,6 +19,10 @@ #include <frameformats.hxx> #include <textboxhelper.hxx> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/text/XTextFramesSupplier.hpp> + constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/core/draw/data/"; /// Covers sw/source/core/draw/ fixes. @@ -98,6 +103,44 @@ CPPUNIT_TEST_FIXTURE(SwCoreDrawTest, testTextboxUndoOrdNum) } } +CPPUNIT_TEST_FIXTURE(SwCoreDrawTest, testTdf107727FrameBorder) +{ + // Load a document with a textframe without border, one with only left border + OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf107727_FrameBorder.odt"; + mxComponent = loadFromDesktop(aURL, "com.sun.star.text.TextDocument", {}); + + // Export to RTF and reload + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString("Rich Text Format"); + xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument", {}); + + // Get frame without border and inspect it. + uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xFrame0(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + auto aBorder = getProperty<table::BorderLine2>(xFrame0, "LeftBorder"); + // fo:border="none" is not available via API, and aBorder.LineWidth has wrong value (why?). + sal_uInt32 nBorderWidth + = aBorder.OuterLineWidth + aBorder.InnerLineWidth + aBorder.LineDistance; + // Without patch it failed with Expected 0, Actual 26 + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), nBorderWidth); + + // Get frame with left border and inspect it. + uno::Reference<beans::XPropertySet> xFrame1(xIndexAccess->getByIndex(1), uno::UNO_QUERY); + aBorder = getProperty<table::BorderLine2>(xFrame1, "LeftBorder"); + // Without patch it failed with Expected 127, Actual 26. Default border width was used. + nBorderWidth = aBorder.OuterLineWidth + aBorder.InnerLineWidth + aBorder.LineDistance; + CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(127), nBorderWidth); + // Without patch it failed with Expected Color: R:0 G:0 B:255 A:0, Actual Color: R:0 G:0 B:0 A:0. + // Default border color was used. + CPPUNIT_ASSERT_EQUAL(Color(0x0000ff), Color(ColorTransparency, aBorder.Color)); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 8f9d48f05da2..657160b1ee52 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -3558,27 +3558,45 @@ void RtfAttributeOutput::FormatBox(const SvxBoxItem& rBox) const editeng::SvxBorderLine* pRight = rBox.GetLine(SvxBoxItemLine::RIGHT); const editeng::SvxBorderLine* pTop = rBox.GetLine(SvxBoxItemLine::TOP); const editeng::SvxBorderLine* pBottom = rBox.GetLine(SvxBoxItemLine::BOTTOM); - if (pLeft && pRight && pTop && pBottom && *pLeft == *pRight && *pLeft == *pTop - && *pLeft == *pBottom) + + if (!pLeft && !pRight && !pBottom && !pTop) { - const Color& rColor = pTop->GetColor(); - // We in fact need RGB to BGR, but the transformation is symmetric. - m_aFlyProperties.push_back(std::make_pair<OString, OString>( - "lineColor", OString::number(wwUtility::RGBToBGR(rColor)))); + // fLine has default 'true', so need to write it out in case of no border. + m_aFlyProperties.push_back(std::make_pair<OString, OString>("fLine", "0")); + return; + } - if (pTop->GetBorderLineStyle() != SvxBorderLineStyle::NONE) - { - double const fConverted(editeng::ConvertBorderWidthToWord( - pTop->GetBorderLineStyle(), pTop->GetWidth())); - sal_Int32 nWidth = o3tl::convert(fConverted, o3tl::Length::twip, o3tl::Length::emu); - m_aFlyProperties.push_back( - std::make_pair<OString, OString>("lineWidth", OString::number(nWidth))); - } - else - // No border: no line. - m_aFlyProperties.push_back(std::make_pair<OString, OString>("fLine", "0")); + // RTF has the flags fTopLine, fBottomLine, fLeftLine and fRightLine to disable single border + // lines. But Word cannot disable single border lines. So we do not use them. In case of + // single border lines it is better to draw all four borders than drawing none. So we look + // whether a border line exists, which is effectively drawn. + const editeng::SvxBorderLine* pBorder = nullptr; + if (pTop && pTop->GetBorderLineStyle() != SvxBorderLineStyle::NONE) + pBorder = pTop; + else if (pBottom && pBottom->GetBorderLineStyle() != SvxBorderLineStyle::NONE) + pBorder = pBottom; + else if (pLeft && pLeft->GetBorderLineStyle() != SvxBorderLineStyle::NONE) + pBorder = pLeft; + else if (pRight && pRight->GetBorderLineStyle() != SvxBorderLineStyle::NONE) + pBorder = pRight; + + if (!pBorder) + { + m_aFlyProperties.push_back(std::make_pair<OString, OString>("fLine", "0")); + return; } + const Color& rColor = pBorder->GetColor(); + // We in fact need RGB to BGR, but the transformation is symmetric. + m_aFlyProperties.push_back(std::make_pair<OString, OString>( + "lineColor", OString::number(wwUtility::RGBToBGR(rColor)))); + + double const fConverted( + editeng::ConvertBorderWidthToWord(pBorder->GetBorderLineStyle(), pBorder->GetWidth())); + sal_Int32 nWidth = o3tl::convert(fConverted, o3tl::Length::twip, o3tl::Length::emu); + m_aFlyProperties.push_back( + std::make_pair<OString, OString>("lineWidth", OString::number(nWidth))); + return; } |