summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRegina Henschel <rb.henschel@t-online.de>2022-02-01 20:38:07 +0100
committerXisco Fauli <xiscofauli@libreoffice.org>2022-02-02 13:54:34 +0100
commitb3f426bc7ff75820c2487f1a7f9d0117b5d53831 (patch)
tree5ef252e2a71484677231a252d477b44f5c7a7981
parente19044a21287b6538ae5962c5fb29b711c09e4f9 (diff)
tdf#107727 disable border in RTF export if not drawn
A border of a text frame is not drawn, if it is really disabled or if its line style is None. The patch considers both cases. Previously the first case was missing. LO can disable single border lines and single border lines can have different styles. The patch uses a border line now, that is really drawn, to get the color and width. It uses the first one in order top, bottom, left, right. In theory RTF can describe disabling single border lines by using the flags fTopLine, fBottomLine, fLeftLine or fRightLine. But Word has only the ability to enable all or none of the border lines for an old kind text box as contained in an rtf-document. The current patch uses therefore this all-or-none approach too. It enables border if at least one is actually drawn, because that keeps the style settings for that border line. Previously all four border lines need to be drawn. If it is changed to use the flags fTopLine, fBottomLine, fLeftLine and fRightLine on export, then it would be possible to recover showing only single border lines on reimport. But that is out of scope here. Change-Id: Ib78604def154c133d3c93bc75a38731eb6b02294 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129305 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com> (cherry picked from commit 9877a0190e43241f4a5102e5d9cc7181f91d5a6f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129328 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
-rw-r--r--sw/qa/core/draw/data/tdf107727_FrameBorder.odtbin0 -> 11265 bytes
-rw-r--r--sw/qa/core/draw/draw.cxx43
-rw-r--r--sw/source/filter/ww8/rtfattributeoutput.cxx52
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
new file mode 100644
index 000000000000..6b7bc3a375fa
--- /dev/null
+++ b/sw/qa/core/draw/data/tdf107727_FrameBorder.odt
Binary files differ
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 cc5d693bf3df..cc7d61c80d75 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;
}