Kaydet (Commit) 4b345f95 authored tarafından Miklos Vajna's avatar Miklos Vajna

tdf#118672 sw layout, TabOverMargin: allow using the area over the tab portion

TabOverMargin in general is about allowing the cursor to jump over a
margin if there is an explicit tab stop there.

A corner-case is what to do when there is enough content so a line break
is necessary for the characters after the tab portion. Allow using the
area up to the edge of the whole text frame (i.e. over the tab
position), this matches what Word does.

Change-Id: Ie86edf030d54fba556eee26e7ea563fb8d4fbee4
Reviewed-on: https://gerrit.libreoffice.org/57275Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins
üst e50a5477
......@@ -9,6 +9,7 @@
#include <swmodeltestbase.hxx>
#include <test/mtfxmldump.hxx>
#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
static char const DATA_DIRECTORY[] = "/sw/qa/extras/layout/data/";
......@@ -24,6 +25,7 @@ public:
void testTableExtrusion2();
void testTdf116848();
void testTdf117245();
void testTdf118672();
void testTdf117923();
CPPUNIT_TEST_SUITE(SwLayoutWriter);
......@@ -35,6 +37,7 @@ public:
CPPUNIT_TEST(testTableExtrusion2);
CPPUNIT_TEST(testTdf116848);
CPPUNIT_TEST(testTdf117245);
CPPUNIT_TEST(testTdf118672);
CPPUNIT_TEST(testTdf117923);
CPPUNIT_TEST_SUITE_END();
......@@ -196,6 +199,30 @@ void SwLayoutWriter::testTdf117245()
assertXPath(pXmlDoc, "/root/page/body/txt[2]/LineBreak", 1);
}
void SwLayoutWriter::testTdf118672()
{
createDoc("tdf118672.odt");
xmlDocPtr pXmlDoc = parseLayoutDump();
// Check if we have hyphenation support, otherwise can't test SwHyphPortion.
uno::Reference<linguistic2::XLinguServiceManager2> xLinguServiceManager
= linguistic2::LinguServiceManager::create(comphelper::getProcessComponentContext());
uno::Sequence<lang::Locale> aLocales
= xLinguServiceManager->getAvailableLocales("com.sun.star.linguistic2.Hyphenator");
auto it = std::find_if(aLocales.begin(), aLocales.end(), [](const lang::Locale& rLocale) {
return rLocale.Language == "en" && rLocale.Country == "US";
});
if (it == aLocales.end())
return;
OUString aLine1("He heard quiet steps behind him. That didn't bode well. Who could be fol*1 2 "
"3 4 5 6 7 8 9 10con-");
// This ended as "fol*1 2 3 4 5 6 7 8 9", i.e. "10con-" was moved to the next line.
assertXPath(pXmlDoc, "/root/page/body/txt[1]/LineBreak[1]", "Line", aLine1);
OUString aLine2("setetur");
assertXPath(pXmlDoc, "/root/page/body/txt[1]/LineBreak[2]", "Line", aLine2);
}
void SwLayoutWriter::testTdf117923()
{
createDoc("tdf117923.doc");
......
......@@ -1702,11 +1702,13 @@ SwTwips SwTextFormatInfo::GetLineWidth()
if (!pLastTab)
return nLineWidth;
// Consider tab portions over the printing bounds of the text frame.
if (pLastTab->GetTabPos() <= Width())
return nLineWidth;
// Consider tab portions over the printing bounds of the text frame.
nLineWidth = pLastTab->GetTabPos() - X();
// If there is one such tab portion, then text is allowed to use the full
// text frame area (even over the actual tab portion).
nLineWidth = GetTextFrame()->getFrameArea().Width() - X();
return nLineWidth;
}
......
......@@ -32,6 +32,8 @@ class XmlPortionDumper:public SwPortionHandler
private:
xmlTextWriterPtr writer;
TextFrameIndex ofs;
const OUString& m_rText;
OUString m_aLine;
static const char* getTypeName( sal_uInt16 nType )
{
......@@ -105,7 +107,7 @@ class XmlPortionDumper:public SwPortionHandler
public:
explicit XmlPortionDumper( xmlTextWriterPtr some_writer ):writer( some_writer ), ofs( 0 )
explicit XmlPortionDumper( xmlTextWriterPtr some_writer, const OUString& rText ):writer( some_writer ), ofs( 0 ), m_rText(rText)
{
}
......@@ -120,7 +122,6 @@ class XmlPortionDumper:public SwPortionHandler
sal_Int32 nHeight,
sal_Int32 nWidth) override
{
ofs += nLength;
xmlTextWriterStartElement( writer, BAD_CAST( "Text" ) );
xmlTextWriterWriteFormatAttribute( writer,
BAD_CAST( "nLength" ),
......@@ -132,8 +133,13 @@ class XmlPortionDumper:public SwPortionHandler
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", static_cast<int>(nHeight));
if (nWidth > 0)
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", static_cast<int>(nWidth));
if (nLength > 0)
xmlTextWriterWriteAttribute(writer, BAD_CAST("Portion"),
BAD_CAST(m_rText.copy(ofs, nLength).toUtf8().getStr()));
xmlTextWriterEndElement( writer );
m_aLine += m_rText.copy(ofs, nLength);
ofs += nLength;
}
/**
......@@ -174,6 +180,7 @@ class XmlPortionDumper:public SwPortionHandler
pFont->dumpAsXml(writer);
xmlTextWriterEndElement( writer );
m_aLine += rText;
ofs += nLength;
}
......@@ -184,6 +191,12 @@ class XmlPortionDumper:public SwPortionHandler
xmlTextWriterWriteFormatAttribute( writer,
BAD_CAST( "nWidth" ),
"%i", static_cast<int>(nWidth) );
if (!m_aLine.isEmpty())
{
xmlTextWriterWriteAttribute(writer, BAD_CAST("Line"),
BAD_CAST(m_aLine.toUtf8().getStr()));
m_aLine.clear();
}
xmlTextWriterEndElement( writer );
}
......@@ -379,7 +392,7 @@ void SwFrame::dumpAsXml( xmlTextWriterPtr writer ) const
RTL_TEXTENCODING_UTF8 );
xmlTextWriterWriteString( writer,
reinterpret_cast<const xmlChar *>(aText8.getStr( )) );
XmlPortionDumper pdumper( writer );
XmlPortionDumper pdumper( writer, aText );
pTextFrame->VisitPortions( pdumper );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment