summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorVasily Melenchuk <vasily.melenchuk@cib.de>2021-07-30 17:22:38 +0300
committerThorsten Behrens <thorsten.behrens@allotropia.de>2022-02-07 21:20:15 +0100
commit19bca24486315cc35f873486e6a2dd18394d0614 (patch)
treef3509d1967d636584b55604cfd77b2db48a02c53 /writerfilter
parent2634c1ae4fcaadc92a86976f2f9594773f5f84ec (diff)
tdf#126287: docx import: use defered linebreak
In some cases when we have combo linebreak, endparagraph and end section at very bottom of page, MS Word does ignores linebreak to avoid empty page with same section and lonely end paragraph mark. With defered linebreak we could simulate and ignore such linebreaks during import. Change-Id: Ie6ee4c0990ee1c2e853691a76953c83191664e43 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119709 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx44
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx15
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx4
3 files changed, 60 insertions, 3 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 6a18d8d12da0..eed7ab8d45b0 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -3225,6 +3225,18 @@ void DomainMapper::lcl_startParagraphGroup()
void DomainMapper::lcl_endParagraphGroup()
{
+ if (m_pImpl->isBreakDeferred(LINE_BREAK))
+ {
+ if (m_pImpl->GetIsLastParagraphInSection())
+ m_pImpl->clearDeferredBreak(LINE_BREAK);
+
+ while (m_pImpl->isBreakDeferred(LINE_BREAK))
+ {
+ m_pImpl->clearDeferredBreak(LINE_BREAK);
+ m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
+ }
+ }
+
m_pImpl->PopProperties(CONTEXT_PARAGRAPH);
if (m_pImpl->hasTableManager())
m_pImpl->getTableManager().endParagraphGroup();
@@ -3385,6 +3397,13 @@ void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
case 0x0e: //column break
m_pImpl->deferBreak(COLUMN_BREAK);
return;
+ case 0x0a: //line break
+ if (m_pImpl->GetIsLastParagraphInSection())
+ {
+ m_pImpl->deferBreak(LINE_BREAK);
+ return;
+ }
+ break;
case 0x07:
m_pImpl->getTableManager().text(data_, len);
return;
@@ -3417,6 +3436,13 @@ void DomainMapper::lcl_text(const sal_uInt8 * data_, size_t len)
// GetTopContext() is changed by inserted breaks, but we want to keep the current context
PropertyMapPtr pContext = m_pImpl->GetTopContext();
+
+ while (m_pImpl->isBreakDeferred(LINE_BREAK))
+ {
+ m_pImpl->clearDeferredBreak(LINE_BREAK);
+ m_pImpl->appendTextPortion("\n", pContext);
+ }
+
if (!m_pImpl->GetFootnoteContext())
{
if (m_pImpl->isBreakDeferred(PAGE_BREAK))
@@ -3640,6 +3666,18 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
m_pImpl->m_bHasFtnSep = true;
return;
}
+ else if (len == 1 && sText[0] == '\r')
+ {
+ // Clear "last" one linebreak at end of section
+ if (m_pImpl->GetIsLastParagraphInSection() && m_pImpl->isBreakDeferred(LINE_BREAK))
+ m_pImpl->clearDeferredBreak(LINE_BREAK);
+ // And emit all other linebreaks
+ while (m_pImpl->isBreakDeferred(LINE_BREAK))
+ {
+ m_pImpl->clearDeferredBreak(LINE_BREAK);
+ m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
+ }
+ }
else if (len == 1 && sText[0] == '\t' )
{
if ( m_pImpl->m_bCheckFirstFootnoteTab && m_pImpl->IsInFootOrEndnote() )
@@ -3670,6 +3708,12 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
try
{
+ while (m_pImpl->isBreakDeferred(LINE_BREAK))
+ {
+ m_pImpl->clearDeferredBreak(LINE_BREAK);
+ m_pImpl->appendTextPortion("\n", m_pImpl->GetTopContext());
+ }
+
m_pImpl->getTableManager().utext(data_, len);
if (bNewLine)
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 548425914616..87c954bbe9ca 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -286,6 +286,7 @@ DomainMapper_Impl::DomainMapper_Impl(
m_bIsFirstSection( true ),
m_bIsColumnBreakDeferred( false ),
m_bIsPageBreakDeferred( false ),
+ m_nLineBreaksDeferred( 0 ),
m_bSdtEndDeferred(false),
m_bParaSdtEndDeferred(false),
m_bStartTOC(false),
@@ -1114,9 +1115,12 @@ void DomainMapper_Impl::deferBreak( BreakType deferredBreakType)
{
switch (deferredBreakType)
{
- case COLUMN_BREAK:
- m_bIsColumnBreakDeferred = true;
+ case LINE_BREAK:
+ m_nLineBreaksDeferred++;
break;
+ case COLUMN_BREAK:
+ m_bIsColumnBreakDeferred = true;
+ break;
case PAGE_BREAK:
// See SwWW8ImplReader::HandlePageBreakChar(), page break should be
// ignored inside tables.
@@ -1134,6 +1138,8 @@ bool DomainMapper_Impl::isBreakDeferred( BreakType deferredBreakType )
{
switch (deferredBreakType)
{
+ case LINE_BREAK:
+ return m_nLineBreaksDeferred > 0;
case COLUMN_BREAK:
return m_bIsColumnBreakDeferred;
case PAGE_BREAK:
@@ -1147,6 +1153,10 @@ void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType)
{
switch (deferredBreakType)
{
+ case LINE_BREAK:
+ assert(m_nLineBreaksDeferred > 0);
+ m_nLineBreaksDeferred--;
+ break;
case COLUMN_BREAK:
m_bIsColumnBreakDeferred = false;
break;
@@ -1160,6 +1170,7 @@ void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType)
void DomainMapper_Impl::clearDeferredBreaks()
{
+ m_nLineBreaksDeferred = 0;
m_bIsColumnBreakDeferred = false;
m_bIsPageBreakDeferred = false;
}
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index 7ede5cb2f91d..bbd5d566367e 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -114,7 +114,8 @@ enum { NUMBER_OF_CONTEXTS = CONTEXT_LIST + 1 };
enum BreakType
{
PAGE_BREAK,
- COLUMN_BREAK
+ COLUMN_BREAK,
+ LINE_BREAK
};
/**
@@ -478,6 +479,7 @@ private:
bool m_bIsFirstSection;
bool m_bIsColumnBreakDeferred;
bool m_bIsPageBreakDeferred;
+ sal_Int32 m_nLineBreaksDeferred;
/// If we want to set "sdt end" on the next character context.
bool m_bSdtEndDeferred;
/// If we want to set "paragraph sdt end" on the next paragraph context.