1912 lines
92 KiB
C++
1912 lines
92 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include <swmodeltestbase.hxx>
|
|
#include <comphelper/propertysequence.hxx>
|
|
#include <com/sun/star/linguistic2/XHyphenator.hpp>
|
|
#include <com/sun/star/text/XTextSectionsSupplier.hpp>
|
|
#include <vcl/scheduler.hxx>
|
|
#include <editeng/unolingu.hxx>
|
|
#include <editeng/editobj.hxx>
|
|
#include <comphelper/propertyvalue.hxx>
|
|
|
|
#include <wrtsh.hxx>
|
|
#include <pagefrm.hxx>
|
|
#include <sortedobjs.hxx>
|
|
#include <ndtxt.hxx>
|
|
#include <unotxdoc.hxx>
|
|
#include <rootfrm.hxx>
|
|
#include <IDocumentDrawModelAccess.hxx>
|
|
#include <unoframe.hxx>
|
|
#include <drawdoc.hxx>
|
|
#include <svx/svdpage.hxx>
|
|
#include <svx/svdotext.hxx>
|
|
#include <dcontact.hxx>
|
|
#include <frameformats.hxx>
|
|
|
|
namespace
|
|
{
|
|
/// Test to assert layout / rendering result of Writer.
|
|
class SwLayoutWriter4 : public SwModelTestBase
|
|
{
|
|
public:
|
|
SwLayoutWriter4()
|
|
: SwModelTestBase(u"/sw/qa/extras/layout/data/"_ustr)
|
|
{
|
|
}
|
|
};
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testHiddenSectionPageDescs)
|
|
{
|
|
createSwDoc("hidden-sections-with-pagestyles.odt");
|
|
|
|
// hide these just so that the height of the section is what is expected;
|
|
// otherwise height depends on which tests run previously
|
|
uno::Sequence<beans::PropertyValue> argsSH(
|
|
comphelper::InitPropertySequence({ { "ShowHiddenParagraphs", uno::Any(false) } }));
|
|
dispatchCommand(mxComponent, ".uno:ShowHiddenParagraphs", argsSH);
|
|
uno::Sequence<beans::PropertyValue> args(
|
|
comphelper::InitPropertySequence({ { "Fieldnames", uno::Any(false) } }));
|
|
dispatchCommand(mxComponent, ".uno:Fieldnames", args);
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
{
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page", 2);
|
|
assertXPath(pXmlDoc, "/root/page[1]", "formatName", u"Hotti");
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]", "formatName", u"Verfügung");
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]", "formatName", u"Verfügung");
|
|
// should be > 0, no idea why it's different on Windows
|
|
#ifdef _WIN32
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/infos/bounds", "height", u"552");
|
|
#else
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/infos/bounds", "height", u"532");
|
|
#endif
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[2]", "formatName", u"Rueckantwort");
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[2]/infos/bounds", "height", u"0");
|
|
assertXPath(pXmlDoc, "/root/page[2]", "formatName", u"Folgeseite");
|
|
}
|
|
|
|
// toggle one section hidden and other visible
|
|
executeMacro(
|
|
u"vnd.sun.star.script:Standard.Module1.Main?language=Basic&location=document"_ustr);
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
{
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
|
|
// tdf#152919: Without the fix in place, this test would have failed with
|
|
// - Expected: 3
|
|
// - Actual : 2
|
|
assertXPath(pXmlDoc, "/root/page", 3);
|
|
assertXPath(pXmlDoc, "/root/page[1]", "formatName", u"Hotti");
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]", "formatName", u"Verfügung");
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[2]", "formatName", u"Rueckantwort");
|
|
assertXPath(pXmlDoc, "/root/page[2]", "formatName", u"Empty Page");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]", "formatName", u"Rueckantwort");
|
|
// should be > 0, no idea why it's different on Windows
|
|
#ifdef _WIN32
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/infos/bounds", "height", u"552");
|
|
#else
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/infos/bounds", "height", u"532");
|
|
#endif
|
|
assertXPath(pXmlDoc, "/root/page[3]", "formatName", u"RueckantwortRechts");
|
|
}
|
|
|
|
// toggle one section hidden and other visible
|
|
executeMacro(
|
|
u"vnd.sun.star.script:Standard.Module1.Main?language=Basic&location=document"_ustr);
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
{
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page", 2);
|
|
assertXPath(pXmlDoc, "/root/page[1]", "formatName", u"Hotti");
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]", "formatName", u"Verfügung");
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]", "formatName", u"Verfügung");
|
|
// should be > 0, no idea why it's different on Windows
|
|
#ifdef _WIN32
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/infos/bounds", "height", u"552");
|
|
#else
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/infos/bounds", "height", u"532");
|
|
#endif
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[2]", "formatName", u"Rueckantwort");
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[2]/infos/bounds", "height", u"0");
|
|
assertXPath(pXmlDoc, "/root/page[2]", "formatName", u"Folgeseite");
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testSectionPageBreaksWithNestedSectionWithColumns)
|
|
{
|
|
createSwDoc("section-nested-with-pagebreaks.fodt");
|
|
|
|
auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>();
|
|
auto xSections = xTextSectionsSupplier->getTextSections();
|
|
CPPUNIT_ASSERT(xSections);
|
|
auto xSection1 = xSections->getByName(u"Section1"_ustr).queryThrow<css::beans::XPropertySet>();
|
|
auto xSection2 = xSections->getByName(u"Section2"_ustr).queryThrow<css::beans::XPropertySet>();
|
|
CPPUNIT_ASSERT(getProperty<bool>(xSection1, "IsVisible"));
|
|
CPPUNIT_ASSERT(getProperty<bool>(xSection2, "IsVisible"));
|
|
|
|
{
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"3");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"4");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/column/body/txt", 2);
|
|
assertXPath(pXmlDoc,
|
|
"/root/page[3]/body/section[2]/column/body/txt[2]/SwParaPortion/SwLineLayout",
|
|
"portion", u"6");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[1]/column/body/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[1]/column/body/txt", 2);
|
|
assertXPath(
|
|
pXmlDoc,
|
|
"/root/page[4]/body/section[1]/column[1]/body/txt[1]/SwParaPortion/SwLineLayout",
|
|
"portion", u"7");
|
|
assertXPath(
|
|
pXmlDoc,
|
|
"/root/page[4]/body/section[1]/column[2]/body/txt[1]/SwParaPortion/SwLineLayout",
|
|
"portion", u"8");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[2]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[2]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"Text following inner section");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/txt[1]/SwParaPortion/SwLineLayout", "portion",
|
|
u"Text following outer section");
|
|
}
|
|
|
|
xSection1->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(false));
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
{
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section", 3);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt", 4);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[2]/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[2]/column/body/txt", 4);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[3]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/infos/bounds", "height", u"0");
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[2]/infos/bounds", "height", u"0");
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[3]/infos/bounds", "height", u"0");
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout", "portion",
|
|
u"Text following outer section");
|
|
}
|
|
|
|
xSection1->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
{
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"3");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"4");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/column/body/txt", 2);
|
|
assertXPath(pXmlDoc,
|
|
"/root/page[3]/body/section[2]/column/body/txt[2]/SwParaPortion/SwLineLayout",
|
|
"portion", u"6");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[1]/column/body/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[1]/column/body/txt", 2);
|
|
assertXPath(
|
|
pXmlDoc,
|
|
"/root/page[4]/body/section[1]/column[1]/body/txt[1]/SwParaPortion/SwLineLayout",
|
|
"portion", u"7");
|
|
assertXPath(
|
|
pXmlDoc,
|
|
"/root/page[4]/body/section[1]/column[2]/body/txt[1]/SwParaPortion/SwLineLayout",
|
|
"portion", u"8");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[2]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[2]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"Text following inner section");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/txt[1]/SwParaPortion/SwLineLayout", "portion",
|
|
u"Text following outer section");
|
|
}
|
|
|
|
xSection2->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(false));
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
{
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"3");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section", 3);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"4");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/column/body/txt", 4);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/infos/bounds", "height", u"0");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[3]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[3]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"Text following inner section");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/txt[1]/SwParaPortion/SwLineLayout", "portion",
|
|
u"Text following outer section");
|
|
}
|
|
|
|
xSection2->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
{
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/section[1]/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/section[1]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"3");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[1]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"4");
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[3]/body/section[2]/column/body/txt", 2);
|
|
assertXPath(pXmlDoc,
|
|
"/root/page[3]/body/section[2]/column/body/txt[2]/SwParaPortion/SwLineLayout",
|
|
"portion", u"6");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section", 2);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[1]/column/body/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[1]/column/body/txt", 2);
|
|
assertXPath(
|
|
pXmlDoc,
|
|
"/root/page[4]/body/section[1]/column[1]/body/txt[1]/SwParaPortion/SwLineLayout",
|
|
"portion", u"7");
|
|
assertXPath(
|
|
pXmlDoc,
|
|
"/root/page[4]/body/section[1]/column[2]/body/txt[1]/SwParaPortion/SwLineLayout",
|
|
"portion", u"8");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[2]/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/section[2]/txt/SwParaPortion/SwLineLayout",
|
|
"portion", u"Text following inner section");
|
|
assertXPath(pXmlDoc, "/root/page[4]/body/txt[1]/SwParaPortion/SwLineLayout", "portion",
|
|
u"Text following outer section");
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf156725)
|
|
{
|
|
createSwDoc("tdf156725.fodt");
|
|
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page", 2);
|
|
// the fly has 2 columns, the section in it has 2 columns, and is split
|
|
// across the fly columns => 4 columns with 1 text frame each
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt/anchored/fly/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt/anchored/fly/column[1]/body/section/column", 2);
|
|
assertXPath(pXmlDoc,
|
|
"/root/page[2]/body/txt/anchored/fly/column[1]/body/section/column[1]/body/txt", 1);
|
|
assertXPath(pXmlDoc,
|
|
"/root/page[2]/body/txt/anchored/fly/column[1]/body/section/column[2]/body/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt/anchored/fly/column[2]/body/section/column", 2);
|
|
assertXPath(pXmlDoc,
|
|
"/root/page[2]/body/txt/anchored/fly/column[2]/body/section/column[1]/body/txt", 1);
|
|
assertXPath(pXmlDoc,
|
|
"/root/page[2]/body/txt/anchored/fly/column[2]/body/section/column[2]/body/txt", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf156419)
|
|
{
|
|
createSwDoc("linked_frames_section_bug.odt");
|
|
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page", 2);
|
|
// there are 2 flys on page 1, and 1 on page 2, all linked
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt/anchored/fly[1]/section/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt/anchored/fly[1]/section/column[1]/body/txt", 11);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt/anchored/fly[1]/section/column[2]/body/txt", 11);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt/anchored/fly[2]/section/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt/anchored/fly[2]/section/column[1]/body/txt", 12);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt/anchored/fly[2]/section/column[2]/body/txt", 12);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt/anchored/fly[1]/section/column", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt/anchored/fly[1]/section/column[1]/body/txt", 2);
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt/anchored/fly[1]/section/column[2]/body/txt", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf145826)
|
|
{
|
|
createSwDoc("tdf145826.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
CPPUNIT_ASSERT(pXmlDoc);
|
|
|
|
assertXPath(pXmlDoc, "/root/page/body/section/column", 2);
|
|
|
|
// Without the fix in place, this test would have failed with
|
|
// - Expected: 1
|
|
// - Actual : 0
|
|
assertXPath(pXmlDoc, "/root/page/body/section/column[1]/ftncont", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/section/column[2]/ftncont", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/section/column[1]/ftncont/ftn", 3);
|
|
assertXPath(pXmlDoc, "/root/page/body/section/column[2]/ftncont/ftn", 3);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTable0HeightRows)
|
|
{
|
|
createSwDoc("table-0-height-rows.fodt");
|
|
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
CPPUNIT_ASSERT(pXmlDoc);
|
|
|
|
// the problem was that the table was erroneously split across 2 or 3 pages
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/tab", 1);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row", 28);
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/infos/bounds[@height='0']", 25);
|
|
assertXPath(pXmlDoc, "/root/page", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf105481)
|
|
{
|
|
createSwDoc("tdf105481.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
CPPUNIT_ASSERT(pXmlDoc);
|
|
|
|
// Without the accompanying fix in place, this test would have failed
|
|
// because the vertical position of the as-char shape object and the
|
|
// as-char math object will be wrong (below/beyond the text frame's bottom).
|
|
|
|
SwTwips nTxtTop = getXPath(pXmlDoc,
|
|
"/root/page/anchored/fly/txt[2]"
|
|
"/infos/bounds",
|
|
"top")
|
|
.toInt32();
|
|
SwTwips nTxtBottom = nTxtTop
|
|
+ getXPath(pXmlDoc,
|
|
"/root/page/anchored/fly/txt[2]"
|
|
"/infos/bounds",
|
|
"height")
|
|
.toInt32();
|
|
|
|
SwTwips nFormula1Top = getXPath(pXmlDoc,
|
|
"/root/page/anchored/fly/txt[2]"
|
|
"/anchored/fly[1]/infos/bounds",
|
|
"top")
|
|
.toInt32();
|
|
SwTwips nFormula1Bottom = nFormula1Top
|
|
+ getXPath(pXmlDoc,
|
|
"/root/page/anchored/fly/txt[2]"
|
|
"/anchored/fly[1]/infos/bounds",
|
|
"height")
|
|
.toInt32();
|
|
|
|
SwTwips nFormula2Top = getXPath(pXmlDoc,
|
|
"/root/page/anchored/fly/txt[2]"
|
|
"/anchored/fly[2]/infos/bounds",
|
|
"top")
|
|
.toInt32();
|
|
SwTwips nFormula2Bottom = nFormula2Top
|
|
+ getXPath(pXmlDoc,
|
|
"/root/page/anchored/fly/txt[2]"
|
|
"/anchored/fly[2]/infos/bounds",
|
|
"height")
|
|
.toInt32();
|
|
|
|
// Ensure that the two formula positions are at least between top and bottom of the text frame.
|
|
// The below two are satisfied even without the fix.
|
|
CPPUNIT_ASSERT_GREATEREQUAL(nTxtTop, nFormula1Top);
|
|
CPPUNIT_ASSERT_GREATEREQUAL(nTxtTop, nFormula2Top);
|
|
|
|
// Without the accompanying fix in place, this test would have failed with:
|
|
// - Expected less than or equal to : 14423
|
|
// - Actual : 14828
|
|
// that is, the formula is below the text-frame's y bound.
|
|
CPPUNIT_ASSERT_LESSEQUAL(nTxtBottom, nFormula1Bottom);
|
|
// Similarly for formula # 2 :
|
|
// - Expected less than or equal to : 14423
|
|
// - Actual : 15035
|
|
// that is, the formula is below the text-frame's y bound.
|
|
CPPUNIT_ASSERT_LESSEQUAL(nTxtBottom, nFormula2Bottom);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf117982)
|
|
{
|
|
createSwDoc("tdf117982.docx");
|
|
SwDocShell* pShell = getSwDocShell();
|
|
std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
|
|
MetafileXmlDump dumper;
|
|
xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
|
|
assertXPathContent(pXmlDoc, "/metafile/push[1]/push[1]/push[1]/textarray[1]/text", u"FOO AAA");
|
|
//The first cell must be "FOO AAA". If not, this means the first cell content not visible in
|
|
//the source document.
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf128959)
|
|
{
|
|
// no orphan/widow control in table cells
|
|
createSwDoc("tdf128959.docx");
|
|
SwDoc* pDoc = getSwDoc();
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
|
|
// first two lines of the paragraph in the split table cell on the first page
|
|
// (these lines were completely lost)
|
|
assertXPath(
|
|
pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt[1]/SwParaPortion/SwLineLayout[1]",
|
|
"portion",
|
|
u"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas porttitor congue ");
|
|
assertXPath(
|
|
pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[1]/txt[1]/SwParaPortion/SwLineLayout[2]",
|
|
"portion",
|
|
u"massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit ");
|
|
// last line of the paragraph in the split table cell on the second page
|
|
assertXPath(pXmlDoc,
|
|
"/root/page[2]/body/tab[1]/row[1]/cell[1]/txt[1]/SwParaPortion/SwLineLayout[1]",
|
|
"portion", u"amet commodo magna eros quis urna.");
|
|
|
|
// Also check that the widow control for the paragraph is not turned off:
|
|
sw::TableFrameFormats& rTableFormats = *pDoc->GetTableFrameFormats();
|
|
SwFrameFormat* pTableFormat = rTableFormats[0];
|
|
SwTable* pTable = SwTable::FindTable(pTableFormat);
|
|
const SwTableBox* pCell = pTable->GetTableBox(u"A1"_ustr);
|
|
const SwStartNode* pStartNode = pCell->GetSttNd();
|
|
SwNodeIndex aNodeIndex(*pStartNode);
|
|
++aNodeIndex;
|
|
const SwTextNode* pTextNode = aNodeIndex.GetNode().GetTextNode();
|
|
// Without the accompanying fix in place, this test would have failed with:
|
|
// - Expected: 2
|
|
// - Actual : 0
|
|
// i.e. the original fix only worked as the entire widow / orphan control was switched off.
|
|
CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(pTextNode->GetSwAttrSet().GetWidows().GetValue()));
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf121658)
|
|
{
|
|
uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator();
|
|
if (!xHyphenator->hasLocale(lang::Locale(u"en"_ustr, u"US"_ustr, OUString())))
|
|
return;
|
|
|
|
createSwDoc("tdf121658.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
|
|
// Only 2 hyphenated words should appear in the document (in the lowercase words).
|
|
// Uppercase words should not be hyphenated.
|
|
assertXPath(pXmlDoc, "//SwLineLayout/child::*[@type='PortionType::Hyphen']", 2);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf149420)
|
|
{
|
|
uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator();
|
|
if (!xHyphenator->hasLocale(lang::Locale(u"en"_ustr, u"US"_ustr, OUString())))
|
|
return;
|
|
|
|
createSwDoc("tdf149420.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
|
|
// Only 3 hyphenated words should appear in the document (last paragraph
|
|
// has got a 1 cm hyphenation zone, removing two hyphenations, which visible
|
|
// in the second paragraph).
|
|
assertXPath(pXmlDoc, "//SwLineLayout/child::*[@type='PortionType::Hyphen']", 8);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf149324)
|
|
{
|
|
uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator();
|
|
if (!xHyphenator->hasLocale(lang::Locale(u"en"_ustr, u"US"_ustr, OUString())))
|
|
return;
|
|
|
|
createSwDoc("tdf149324.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
|
|
// Only 3 hyphenated words should appear in the document (last paragraph
|
|
// has got a 7-character word limit for hyphenation, removing the
|
|
// hyphenation "ex-cept".
|
|
assertXPath(pXmlDoc, "//SwLineLayout/child::*[@type='PortionType::Hyphen']", 3);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf149248)
|
|
{
|
|
uno::Reference<linguistic2::XHyphenator> xHyphenator = LinguMgr::GetHyphenator();
|
|
if (!xHyphenator->hasLocale(lang::Locale(u"en"_ustr, u"US"_ustr, OUString())))
|
|
return;
|
|
|
|
createSwDoc("tdf149248.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
|
|
// Only 1 hyphenated word should appear in the document (last word of the second
|
|
// paragraph). Last word should not be hyphenated for the fourth paragraph
|
|
// (the same paragraph, but with forbidden hyphenation of the last word).
|
|
assertXPath(pXmlDoc, "//SwLineLayout/child::*[@type='PortionType::Hyphen']", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testWriterImageNoCapture)
|
|
{
|
|
createSwDoc("writer-image-no-capture.docx");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
CPPUNIT_ASSERT(pXmlDoc);
|
|
sal_Int32 nPageLeft = getXPath(pXmlDoc, "//page/infos/bounds", "left").toInt32();
|
|
sal_Int32 nImageLeft = getXPath(pXmlDoc, "//anchored/fly/infos/bounds", "left").toInt32();
|
|
// Without the accompanying fix in place, this test would have failed with:
|
|
// - Expected less than: 284
|
|
// - Actual : 284
|
|
// i.e. the image position was modified to be inside the page frame ("captured"), even if Word
|
|
// does not do that.
|
|
CPPUNIT_ASSERT_LESS(nPageLeft, nImageLeft);
|
|
}
|
|
|
|
SwRect lcl_getVisibleFlyObjRect(SwWrtShell* pWrtShell)
|
|
{
|
|
SwRootFrame* pRoot = pWrtShell->GetLayout();
|
|
SwPageFrame* pPage = static_cast<SwPageFrame*>(pRoot->GetLower());
|
|
pPage = static_cast<SwPageFrame*>(pPage->GetNext());
|
|
pPage = static_cast<SwPageFrame*>(pPage->GetNext());
|
|
SwSortedObjs* pDrawObjs = pPage->GetDrawObjs();
|
|
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDrawObjs->size());
|
|
SwAnchoredObject* pDrawObj = (*pDrawObjs)[0];
|
|
CPPUNIT_ASSERT_EQUAL(u"Rahmen8"_ustr, pDrawObj->GetFrameFormat()->GetName());
|
|
pPage = static_cast<SwPageFrame*>(pPage->GetNext());
|
|
pDrawObjs = pPage->GetDrawObjs();
|
|
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDrawObjs->size());
|
|
pDrawObj = (*pDrawObjs)[0];
|
|
CPPUNIT_ASSERT_EQUAL(u"Rahmen123"_ustr, pDrawObj->GetFrameFormat()->GetName());
|
|
SwRect aFlyRect = pDrawObj->GetObjRect();
|
|
CPPUNIT_ASSERT(pPage->getFrameArea().Contains(aFlyRect));
|
|
return aFlyRect;
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testStableAtPageAnchoredFlyPosition)
|
|
{
|
|
// this doc has two page-anchored frames: one tiny on page 3 and one large on page 4.
|
|
// it also has a style:master-page named "StandardEntwurf", which contains some fields.
|
|
// if you add a break to page 2, or append some text to page 4 (or just toggle display field names),
|
|
// the page anchored frame on page 4 vanishes, as it is incorrectly moved out of the page bounds.
|
|
createSwDoc("stable-at-page-anchored-fly-position.odt");
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
// look up the layout position of the page-bound frame on page four
|
|
SwRect aOrigRect = lcl_getVisibleFlyObjRect(pWrtShell);
|
|
|
|
// append some text to the document to trigger bug / relayout
|
|
pWrtShell->SttEndDoc(false);
|
|
pWrtShell->Insert(u"foo"_ustr);
|
|
|
|
// get the current position of the frame on page four
|
|
SwRect aRelayoutRect = lcl_getVisibleFlyObjRect(pWrtShell);
|
|
|
|
// the anchored frame should not have moved
|
|
CPPUNIT_ASSERT_EQUAL(aOrigRect, aRelayoutRect);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf134548)
|
|
{
|
|
createSwDoc("tdf134548.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
|
|
// Second paragraph has two non zero width tabs in beginning of line
|
|
{
|
|
OUString sNodeType = getXPath(
|
|
pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout/SwFixPortion[1]", "type");
|
|
CPPUNIT_ASSERT_EQUAL(u"PortionType::TabLeft"_ustr, sNodeType);
|
|
sal_Int32 nWidth
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout/SwFixPortion[1]",
|
|
"width")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(0), nWidth);
|
|
}
|
|
{
|
|
OUString sNodeType = getXPath(
|
|
pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout/SwFixPortion[2]", "type");
|
|
CPPUNIT_ASSERT_EQUAL(u"PortionType::TabLeft"_ustr, sNodeType);
|
|
sal_Int32 nWidth
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout/SwFixPortion[2]",
|
|
"width")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(0), nWidth);
|
|
}
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf124423)
|
|
{
|
|
createSwDoc("tdf124423.docx");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
sal_Int32 nFly1Width
|
|
= getXPath(pXmlDoc, "(//anchored/fly)[1]/infos/prtBounds", "width").toInt32();
|
|
sal_Int32 nFly2Width
|
|
= getXPath(pXmlDoc, "(//anchored/fly)[2]/infos/prtBounds", "width").toInt32();
|
|
sal_Int32 nPageWidth = getXPath(pXmlDoc, "//page/infos/prtBounds", "width").toInt32();
|
|
CPPUNIT_ASSERT_EQUAL(nPageWidth, nFly2Width);
|
|
CPPUNIT_ASSERT_LESS(nPageWidth / 2, nFly1Width);
|
|
|
|
createSwDoc("tdf124423.odt");
|
|
pXmlDoc = parseLayoutDump();
|
|
nFly1Width = getXPath(pXmlDoc, "(//anchored/fly)[1]/infos/prtBounds", "width").toInt32();
|
|
nFly2Width = getXPath(pXmlDoc, "(//anchored/fly)[2]/infos/prtBounds", "width").toInt32();
|
|
nPageWidth = getXPath(pXmlDoc, "//page/infos/prtBounds", "width").toInt32();
|
|
CPPUNIT_ASSERT_LESS(nPageWidth / 2, nFly2Width);
|
|
CPPUNIT_ASSERT_LESS(nPageWidth / 2, nFly1Width);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf137185)
|
|
{
|
|
// First load the sample bugdoc
|
|
createSwDoc("tdf137185.odt");
|
|
// Get the doc shell
|
|
SwDoc* pDoc(getSwDoc());
|
|
|
|
// Get the DrawObject from page
|
|
auto pModel = pDoc->getIDocumentDrawModelAccess().GetDrawModel();
|
|
CPPUNIT_ASSERT(pModel);
|
|
auto pPage = pModel->GetPage(0);
|
|
CPPUNIT_ASSERT(pPage);
|
|
auto pObj = pPage->GetObj(0);
|
|
CPPUNIT_ASSERT(pObj);
|
|
|
|
// Get the format of the draw object
|
|
auto pShape = FindFrameFormat(pObj);
|
|
CPPUNIT_ASSERT(pShape);
|
|
|
|
// Check the text of the shape
|
|
uno::Reference<text::XText> xTxt(getShape(1), uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT_EQUAL(u"Align me!"_ustr, xTxt->getText()->getString());
|
|
|
|
// Add a textbox to the shape
|
|
SwTextBoxHelper::create(pShape, pShape->FindRealSdrObject(), true);
|
|
|
|
// Check if the text moved from the shape to the frame
|
|
auto pFormat = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
|
|
auto xTextFrame = SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(u"Align me!"_ustr, xTextFrame->getText()->getString());
|
|
SdrTextObj* pTextObj = DynCastSdrTextObj(pObj);
|
|
CPPUNIT_ASSERT(pTextObj);
|
|
const auto& aOutStr = pTextObj->GetOutlinerParaObject()->GetTextObject();
|
|
|
|
CPPUNIT_ASSERT(aOutStr.GetText(0).isEmpty());
|
|
// Before the patch it failed, because the text appeared 2 times on each other.
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf138782)
|
|
{
|
|
createSwDoc("tdf138782.docx");
|
|
auto pXml = parseLayoutDump();
|
|
CPPUNIT_ASSERT(pXml);
|
|
|
|
// Without the fix it failed because the 3rd shape was outside the page:
|
|
// - Expected less than: 13327
|
|
// - Actual : 14469
|
|
|
|
CPPUNIT_ASSERT_LESS(
|
|
getXPath(pXml, "/root/page/infos/bounds", "right").toInt32(),
|
|
getXPath(pXml, "/root/page/body/txt[8]/anchored/SwAnchoredDrawObject/bounds", "right")
|
|
.toInt32());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf135035)
|
|
{
|
|
createSwDoc("tdf135035.docx");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
sal_Int32 nFly1Width
|
|
= getXPath(pXmlDoc, "(//anchored/fly)[1]/infos/prtBounds", "width").toInt32();
|
|
sal_Int32 nFly2Width
|
|
= getXPath(pXmlDoc, "(//anchored/fly)[2]/infos/prtBounds", "width").toInt32();
|
|
sal_Int32 nFly3Width
|
|
= getXPath(pXmlDoc, "(//anchored/fly)[3]/infos/prtBounds", "width").toInt32();
|
|
sal_Int32 nParentWidth = getXPath(pXmlDoc, "(//txt)[1]/infos/prtBounds", "width").toInt32();
|
|
CPPUNIT_ASSERT_EQUAL(nParentWidth, nFly2Width);
|
|
CPPUNIT_ASSERT_EQUAL(nParentWidth, nFly3Width);
|
|
CPPUNIT_ASSERT_LESS(nParentWidth / 2, nFly1Width);
|
|
|
|
createSwDoc("tdf135035.odt");
|
|
pXmlDoc = parseLayoutDump();
|
|
nFly1Width = getXPath(pXmlDoc, "(//anchored/fly)[1]/infos/prtBounds", "width").toInt32();
|
|
nFly2Width = getXPath(pXmlDoc, "(//anchored/fly)[2]/infos/prtBounds", "width").toInt32();
|
|
nFly3Width = getXPath(pXmlDoc, "(//anchored/fly)[3]/infos/prtBounds", "width").toInt32();
|
|
nParentWidth = getXPath(pXmlDoc, "(//txt)[1]/infos/prtBounds", "width").toInt32();
|
|
CPPUNIT_ASSERT_LESS(nParentWidth / 2, nFly2Width);
|
|
CPPUNIT_ASSERT_LESS(nParentWidth / 2, nFly1Width);
|
|
CPPUNIT_ASSERT_GREATER(nParentWidth, nFly3Width);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf146704_EndnoteInSection)
|
|
{
|
|
createSwDoc("tdf146704_EndnoteInSection.odt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
// Without the fix, the endnote placed to 2. page
|
|
assertXPath(pXmlDoc, "/root/page", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf139336_ColumnsWithFootnoteDoNotOccupyEntirePage)
|
|
{
|
|
createSwDoc("tdf139336_ColumnsWithFootnoteDoNotOccupyEntirePage.docx");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
// Without the fix, it would be 5 pages, but with the fix the whole document
|
|
// would fit into 1 page, but it will be 2 pages right now, because
|
|
// when writer import (from docx) the last section with columns, then it does not set
|
|
// the evenly distributed settings, and this settings is required for the fix now, to
|
|
// avoid some regression.
|
|
assertXPath(pXmlDoc, "/root/page", 2);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf54465_ColumnsWithFootnoteDoNotOccupyEntirePage)
|
|
{
|
|
// Old odt files should keep their original layout, as it was before Tdf139336 fix.
|
|
// The new odt file is only 1 page long, while the old odt file (with the same content)
|
|
// was more than 1 page long.
|
|
// Note: Somewhy this test miscalculates the layout of the old odt file.
|
|
// It will be 4 pages long, while opened in Writer it is 5 pages long.
|
|
createSwDoc("tdf54465_ColumnsWithFootnoteDoNotOccupyEntirePage_Old.odt");
|
|
Scheduler::ProcessEventsToIdle();
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, "/root/page");
|
|
xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
|
|
CPPUNIT_ASSERT_GREATER(1, xmlXPathNodeSetGetLength(pXmlNodes));
|
|
xmlXPathFreeObject(pXmlObj);
|
|
|
|
createSwDoc("tdf54465_ColumnsWithFootnoteDoNotOccupyEntirePage_New.odt");
|
|
pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "/root/page", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf138124)
|
|
{
|
|
// When the only portion after the footnote number is a FlyCnt, and it doesn't fit into
|
|
// the page width, it should be moved to the next line without the footnote number, and
|
|
// not loop, nor OOM, nor fail assertions.
|
|
|
|
createSwDoc("wideBoxInFootnote.fodt");
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
// Without the fix in place, the layout would loop, creating new FootnoteNum portions
|
|
// indefinitely, until OOM.
|
|
// If the footnote paragraph had no orphan control, then the loop would finally end,
|
|
// but an assertion in SwTextPainter::DrawTextLine would fail during paint.
|
|
|
|
xmlDocUniquePtr pXml = parseLayoutDump();
|
|
assertXPath(pXml, "/root/page", 1);
|
|
assertXPath(pXml, "/root/page/ftncont/ftn/txt/anchored", 1);
|
|
|
|
// And finally, if there were no assertion in SwTextPainter::DrawTextLine, it would have
|
|
// produced multiple lines with FootnoteNum portions, failing the following check like
|
|
// - Expected: 1
|
|
// - Actual : 49
|
|
|
|
assertXPath(pXml,
|
|
"/root/page/ftncont/ftn/txt//SwFieldPortion[@type='PortionType::FootnoteNum']", 1);
|
|
assertXPath(pXml, "/root/page/ftncont/ftn/txt//SwLinePortion[@type='PortionType::FlyCnt']", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf161348)
|
|
{
|
|
createSwDoc("fdo48718-1.docx");
|
|
|
|
xmlDocUniquePtr pXml = parseLayoutDump();
|
|
|
|
// the floating table is on page 1
|
|
// apparently both parts of the split table are on this text frame
|
|
assertXPath(pXml, "/root/page[1]/body/txt[2]/anchored/fly", 2);
|
|
assertXPath(pXml, "/root/page[1]/body/txt[2]/anchored/fly/tab", 2);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf154113)
|
|
{
|
|
createSwDoc("three_sections.fodt");
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
dispatchCommand(mxComponent, u".uno:GoToStartOfDoc"_ustr, {});
|
|
dispatchCommand(mxComponent, u".uno:GoToNextPara"_ustr, {});
|
|
dispatchCommand(mxComponent, u".uno:EndOfDocumentSel"_ustr,
|
|
{}); // to the end of current section!
|
|
dispatchCommand(mxComponent, u".uno:EndOfDocumentSel"_ustr, {}); // to the end of the document.
|
|
|
|
auto xModel = mxComponent.queryThrow<frame::XModel>();
|
|
auto xSelected = xModel->getCurrentSelection().queryThrow<container::XIndexAccess>();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSelected->getCount());
|
|
auto xRange = xSelected->getByIndex(0).queryThrow<text::XTextRange>();
|
|
CPPUNIT_ASSERT_EQUAL(u"<-- Start selection here. Section1" SAL_NEWLINE_STRING
|
|
"Section2" SAL_NEWLINE_STRING "Section3. End selection here -->"_ustr,
|
|
xRange->getString());
|
|
|
|
dispatchCommand(mxComponent, u".uno:Cut"_ustr, {});
|
|
|
|
xSelected = xModel->getCurrentSelection().queryThrow<container::XIndexAccess>();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSelected->getCount());
|
|
xRange = xSelected->getByIndex(0).queryThrow<text::XTextRange>();
|
|
CPPUNIT_ASSERT_EQUAL(OUString(), xRange->getString());
|
|
|
|
dispatchCommand(mxComponent, u".uno:Paste"_ustr, {});
|
|
|
|
xmlDocUniquePtr pXml = parseLayoutDump();
|
|
|
|
// Without the fix in place, this would fail with
|
|
// - Expected: 3
|
|
// - Actual : 2
|
|
assertXPath(pXml, "/root/page/body/section", 3);
|
|
assertXPath(pXml, "/root/page/body/section[1]/txt/SwParaPortion/SwLineLayout", "portion",
|
|
u"<-- Start selection here. Section1");
|
|
assertXPath(pXml, "/root/page/body/section[2]/txt/SwParaPortion/SwLineLayout", "portion",
|
|
u"Section2");
|
|
assertXPath(pXml, "/root/page/body/section[3]/txt/SwParaPortion/SwLineLayout", "portion",
|
|
u"Section3. End selection here -->");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf155611)
|
|
{
|
|
createSwDoc("tdf155611_table_and_nested_section.fodt");
|
|
Scheduler::ProcessEventsToIdle();
|
|
|
|
xmlDocUniquePtr pXml = parseLayoutDump();
|
|
CPPUNIT_ASSERT(pXml);
|
|
|
|
// Check the layout: single page, two section frames (no section frames after the one for Inner
|
|
// section), correct table structure and content in the first section frame, including nested
|
|
// table in the last cell, and the last section text.
|
|
assertXPath(pXml, "/root/page");
|
|
// Without the fix in place, this would fail with
|
|
// - Expected: 2
|
|
// - Actual : 3
|
|
assertXPath(pXml, "/root/page/body/section", 2);
|
|
assertXPath(pXml, "/root/page/body/section[1]/tab");
|
|
assertXPath(pXml, "/root/page/body/section[1]/tab/row");
|
|
assertXPath(pXml, "/root/page/body/section[1]/tab/row/cell", 2);
|
|
assertXPath(pXml, "/root/page/body/section[1]/tab/row/cell[1]/txt/SwParaPortion/SwLineLayout/"
|
|
"SwParaPortion[@portion='foo']");
|
|
assertXPath(pXml, "/root/page/body/section[1]/tab/row/cell[2]/txt/SwParaPortion/SwLineLayout/"
|
|
"SwParaPortion[@portion='bar']");
|
|
assertXPath(pXml, "/root/page/body/section[1]/tab/row/cell[2]/tab/row/cell/txt/SwParaPortion/"
|
|
"SwLineLayout/SwParaPortion[@portion='baz']");
|
|
assertXPath(pXml, "/root/page/body/section[2]/txt[1]/SwParaPortion/SwLineLayout/"
|
|
"SwParaPortion[@portion='abc']");
|
|
|
|
// Also must not crash on close because of a frame that accidentally fell off of the layout
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf152307)
|
|
{
|
|
// Problem: On a given Writer document a table layout changed
|
|
// after doing Tools -> Update -> Update All. The last table row on page 13
|
|
// was bigger than the page size allowed and thus was hidden behind the footer.
|
|
|
|
// load the document
|
|
createSwDoc("tdf152307.odt");
|
|
|
|
// do Tools -> Update -> Update All
|
|
dispatchCommand(mxComponent, u".uno:UpdateAllIndexes"_ustr, {});
|
|
|
|
// XML dump and some basic assertions
|
|
sal_Int32 nPage = 7, nPages = 0;
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
nPages = countXPathNodes(pXmlDoc, "/root/page");
|
|
CPPUNIT_ASSERT_MESSAGE("tdf152307.odt / testTdf152307: Not enough pages.", nPage < nPages);
|
|
assertXPath(pXmlDoc, "/root/page[" + OString::number(nPage) + "]/body/section", 1);
|
|
|
|
// Actual test procedure:
|
|
// On page 7, check:
|
|
// How much tables do we have? How much rows does the last table have?
|
|
int nTables
|
|
= countXPathNodes(pXmlDoc, "/root/page[" + OString::number(nPage) + "]/body/section/tab");
|
|
int nRowsLastTable
|
|
= countXPathNodes(pXmlDoc, "/root/page[" + OString::number(nPage) + "]/body/section/tab["
|
|
+ OString::number(nTables) + "]/row");
|
|
// What is the bottom value of the last table row?
|
|
sal_Int32 nTabBottom = getXPath(pXmlDoc,
|
|
"/root/page[" + OString::number(nPage) + "]/body/section/tab["
|
|
+ OString::number(nTables) + "]/row["
|
|
+ OString::number(nRowsLastTable) + "]/infos/bounds",
|
|
"bottom")
|
|
.toInt32();
|
|
// Where does the footer start (footer/info/bounds/top)?
|
|
sal_Int32 nFooterTop
|
|
= getXPath(pXmlDoc, "/root/page[" + OString::number(nPage) + "]/footer/infos/bounds", "top")
|
|
.toInt32();
|
|
// Is the bottom value of the last row above the top value of the footer?
|
|
OString aMsg = "tdf152307.odt / testTdf152307: Bottom value of last table row on page "
|
|
+ OString::number(nPage) + " is below top value of footer: "
|
|
+ OString::number(nTabBottom) + " > " + OString::number(nFooterTop);
|
|
CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), nTabBottom < nFooterTop);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf57187_Tdf158900)
|
|
{
|
|
// Given a document with a single paragraph, having some long space runs and line breaks
|
|
createSwDoc("space+break.fodt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
// Make sure there is only one page, one paragraph, and five lines
|
|
assertXPath(pXmlDoc, "/root/page", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion", 1);
|
|
// Without the fix in place, this would fail: there used to be 6 lines
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout", 5);
|
|
|
|
// tdf#57187: Check that relatively short lines have spaces not participating in layout.
|
|
// First line has 11 spaces in the end, and then a manual line break. It is rather short:
|
|
// without block justification, it is narrower than the available space.
|
|
// It uses the "first check if everything fits to line" return path in SwTextGuess::Guess.
|
|
// Check that the spaces are put into a Hole portion, thus not participating in layout.
|
|
// Without the fix, this would fail: there were only 2 portions, no Hole nor Margin portions.
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*", 4);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[1]", "type",
|
|
u"PortionType::Text");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[1]", "length", u"11");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[2]", "type",
|
|
u"PortionType::Hole");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[2]", "length", u"11");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[3]", "type",
|
|
u"PortionType::Break");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[4]", "type",
|
|
u"PortionType::Margin");
|
|
// Second line has 101 spaces in the end, and then a manual line break.
|
|
// It uses the "second check if everything fits to line" return path in SwTextGuess::Guess.
|
|
// Check that the spaces are put into a Hole portion, thus not participating in layout.
|
|
// Without the fix, this would fail: there were only 2 portions, no Hole portion.
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*", 3);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[1]", "type",
|
|
u"PortionType::Text");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[1]", "length", u"11");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[2]", "type",
|
|
u"PortionType::Hole");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[2]", "length",
|
|
u"101");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]/*[3]", "type",
|
|
u"PortionType::Break");
|
|
|
|
// tdf#158900: Check that the break after a long line with trailing spaces is kept on same line.
|
|
// Without the fix in place, this would fail: the line had only 2 portions (text + hole),
|
|
// and the break was on a separate third line
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]/*", 3);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]/*[1]", "type",
|
|
u"PortionType::Text");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]/*[2]", "type",
|
|
u"PortionType::Hole");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]/*[3]", "type",
|
|
u"PortionType::Break");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf147666)
|
|
{
|
|
createSwDoc("tdf147666.odt");
|
|
|
|
// Move cursor into position to insert image
|
|
dispatchCommand(mxComponent, u".uno:GoToEndOfPara"_ustr, {});
|
|
dispatchCommand(mxComponent, u".uno:GoDown"_ustr, {});
|
|
|
|
save(u"writer8"_ustr);
|
|
sal_Int32 nNonInsertedViewTop = getXPathContent(parseExport(u"settings.xml"_ustr),
|
|
"//config:config-item[@config:name='ViewTop']")
|
|
.toInt32();
|
|
|
|
// Insert image below the end of the paragraph on page one
|
|
uno::Sequence<beans::PropertyValue> aArgs = {
|
|
comphelper::makePropertyValue(u"FileName"_ustr, createFileURL(u"tdf147666.png")),
|
|
};
|
|
dispatchCommand(mxComponent, u".uno:InsertGraphic"_ustr, aArgs);
|
|
|
|
save(u"writer8"_ustr);
|
|
sal_Int32 nInsertedViewTop = getXPathContent(parseExport(u"settings.xml"_ustr),
|
|
"//config:config-item[@config:name='ViewTop']")
|
|
.toInt32();
|
|
|
|
// Without the fix in place this will fail with
|
|
// nInsertedViewTop = nNonInsertedViewTop
|
|
// i.e. when the image is inserted, the view doesn't
|
|
// focus to the inserted graphic
|
|
CPPUNIT_ASSERT_LESS(nInsertedViewTop, nNonInsertedViewTop);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf159050)
|
|
{
|
|
// Given a document with a justified paragraph and a box with optimal wrapping
|
|
createSwDoc("tdf159050-wrap-adjust.fodt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
// Make sure there is only one page, one anchored object, one paragraph, and two lines
|
|
assertXPath(pXmlDoc, "/root/page", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/anchored/SwAnchoredDrawObject", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout", 2);
|
|
|
|
// Without the fix, this would fail: there was an unexpected second fly portion.
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*", 4);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[1]", "type",
|
|
u"PortionType::Text");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[1]", "length", u"91");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[2]", "type",
|
|
u"PortionType::Hole");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[2]", "length", u"1");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[3]", "type",
|
|
u"PortionType::Fly");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]/*[4]", "type",
|
|
u"PortionType::Margin");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf159271)
|
|
{
|
|
// Given a document with a field with several spaces in a field content
|
|
createSwDoc("fld-in-tbl.docx");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
// Make sure there is only one page, one table with one row and two cells, and one paragraph
|
|
assertXPath(pXmlDoc, "/root/page", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/tab", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/tab/row", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/tab/row/cell", 2);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/tab/row/cell[2]/txt/SwParaPortion", 1);
|
|
|
|
// Without the fix, this would fail:
|
|
// - Expected: 1
|
|
// - Actual : 16
|
|
// - In <>, XPath '/root/page/body/tab/row/cell[2]/txt//SwLineLayout' number of nodes is incorrect
|
|
assertXPath(pXmlDoc, "/root/page/body/tab/row/cell[2]/txt//SwLineLayout", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/tab/row/cell[2]/txt//SwFieldPortion", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf159259)
|
|
{
|
|
// Given a document with a block sdt with a single field, having framePr aligned to right
|
|
createSwDoc("sdt+framePr.docx");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
// Make sure there is only one page and one paragraph with one line and one anchored object
|
|
assertXPath(pXmlDoc, "/root/page", 1);
|
|
// Without the fix, this would fail: there were two paragraphs
|
|
assertXPath(pXmlDoc, "/root/page/body/txt", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout", 1);
|
|
// Without the fix, this would fail: there was a field portion in the line
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout/SwFieldPortion", 0);
|
|
// Without the fix, this would fail: there was no anchored objects
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/anchored", 1);
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/anchored/fly", 1);
|
|
|
|
const sal_Int32 paraRight
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/infos/bounds", "right").toInt32();
|
|
const sal_Int32 paraHeight
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/infos/bounds", "height").toInt32();
|
|
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(0), paraRight);
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(0), paraHeight);
|
|
|
|
const sal_Int32 flyRight
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/anchored/fly/infos/bounds", "right").toInt32();
|
|
const sal_Int32 flyHeight
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/anchored/fly/infos/bounds", "height").toInt32();
|
|
|
|
CPPUNIT_ASSERT_EQUAL(paraRight, flyRight); // The fly is right-aligned
|
|
CPPUNIT_ASSERT_EQUAL(paraHeight, flyHeight);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testLargeTopParaMarginAfterHiddenSection)
|
|
{
|
|
// Given a large top margin in Standard paragraph style, and the first section hidden
|
|
createSwDoc("largeTopMarginAndHiddenFirstSection.fodt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
// Make sure there is only one page and two sections, first hidden (zero-height)
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
assertXPath(pXmlDoc, "//page/body/section", 2);
|
|
assertXPath(pXmlDoc, "//page/body/section[1]/infos/bounds", "height", u"0");
|
|
// Check that the top margin (1 in = 1440 twip) is added to line height (12 pt = 240 twip)
|
|
assertXPath(pXmlDoc, "//page/body/section[2]/infos/bounds", "height", u"1680");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testPageBreakInHiddenSection)
|
|
{
|
|
// Given a paragraph with page-break-before with page style and page number
|
|
createSwDoc("pageBreakInHiddenSection.fodt");
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
assertXPath(pXmlDoc, "//page", 4);
|
|
assertXPath(pXmlDoc, "//section", 4);
|
|
assertXPath(pXmlDoc, "//page[1]/body/txt", 1);
|
|
// The page break inside the hidden section is ignored (otherwise, there would be one section
|
|
// on the first page)
|
|
assertXPath(pXmlDoc, "//page[1]/body/section", 2);
|
|
// The first section is hidden
|
|
assertXPath(pXmlDoc, "//page[1]/body/section[1]/infos/bounds", "height", u"0");
|
|
|
|
// Page 2 is empty even page (generated by the next page's section with page-break-before)
|
|
assertXPath(pXmlDoc, "//page[2]/body", 0);
|
|
|
|
// The section on page 3 is not hidden, only text in it is, therefore its page break works
|
|
assertXPath(pXmlDoc, "//page[3]/body/section", 1);
|
|
assertXPath(pXmlDoc, "//page[3]/body/section/infos/bounds", "height", u"0");
|
|
|
|
// The section on page 4 is hidden, thus page break in it is ignored (no further pages, where
|
|
// the section would be moved to otherwise)
|
|
assertXPath(pXmlDoc, "//page[4]/body/section", 1);
|
|
assertXPath(pXmlDoc, "//page[4]/body/section/infos/bounds", "height", u"0");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf159443)
|
|
{
|
|
// Given a document with chart, which have a datatable
|
|
createSwDoc("tdf159443.odt");
|
|
SwDocShell* pShell = getSwDocShell();
|
|
|
|
// Dump the rendering of the first page as an XML file.
|
|
std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
|
|
MetafileXmlDump dumper;
|
|
xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
|
|
CPPUNIT_ASSERT(pXmlDoc);
|
|
//// Without the fix, this would fail:
|
|
//// - Expected: DataSeries1
|
|
//// - Actual : 1.25
|
|
//// - In <>, XPath contents of child does not match
|
|
assertXPathContent(
|
|
pXmlDoc,
|
|
"/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/push[1]/push[47]/textarray/text",
|
|
u"DataSeries1");
|
|
assertXPathContent(
|
|
pXmlDoc,
|
|
"/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/push[1]/push[49]/textarray/text",
|
|
u"Category1");
|
|
assertXPathContent(
|
|
pXmlDoc,
|
|
"/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/push[1]/push[51]/textarray/text",
|
|
u"4.3");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf159422)
|
|
{
|
|
// Given a document with chart, which have a datatable
|
|
createSwDoc("charttable.odt");
|
|
SwDocShell* pShell = getSwDocShell();
|
|
|
|
// Dump the rendering of the first page as an XML file.
|
|
std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
|
|
MetafileXmlDump dumper;
|
|
xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
|
|
CPPUNIT_ASSERT(pXmlDoc);
|
|
//// Without the fix, this would fail:
|
|
//// - Expected: 5877
|
|
//// - Actual : 5649
|
|
//// - Delta : 20
|
|
sal_Int32 nYSymbol1 = getXPath(pXmlDoc,
|
|
"/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/"
|
|
"push[1]/push[99]/polypolygon/polygon/point[1]",
|
|
"y")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_DOUBLES_EQUAL(5877, nYSymbol1, 20);
|
|
sal_Int32 nYSymbol2 = getXPath(pXmlDoc,
|
|
"/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/"
|
|
"push[1]/push[100]/polypolygon/polygon/point[1]",
|
|
"y")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_DOUBLES_EQUAL(6225, nYSymbol2, 20);
|
|
sal_Int32 nYSymbol3 = getXPath(pXmlDoc,
|
|
"/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/"
|
|
"push[1]/push[101]/polypolygon/polygon/point[1]",
|
|
"y")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_DOUBLES_EQUAL(6573, nYSymbol3, 20);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf159456)
|
|
{
|
|
// Given a document with chart, which have a datatable
|
|
createSwDoc("charttable.odt");
|
|
SwDocShell* pShell = getSwDocShell();
|
|
|
|
// Dump the rendering of the first page as an XML file.
|
|
std::shared_ptr<GDIMetaFile> xMetaFile = pShell->GetPreviewMetaFile();
|
|
MetafileXmlDump dumper;
|
|
xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile);
|
|
//// Without the fix, this would fail:
|
|
//// - Expected: 1
|
|
//// - Actual : 1.5
|
|
//// - In <>, XPath contents of child does not match
|
|
assertXPathContent(pXmlDoc,
|
|
"/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/push[1]/"
|
|
"push[103]/textarray/text",
|
|
u"1");
|
|
assertXPathContent(pXmlDoc,
|
|
"/metafile/push[1]/push[1]/push[1]/push[3]/push[1]/push[1]/push[1]/"
|
|
"push[104]/textarray/text",
|
|
u"2");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, test_i84870)
|
|
{
|
|
// Given a document with a large as-char object, alone in its paragraph, shifted down by a
|
|
// header object: it must not hang in a layout loop on import
|
|
createSwDoc("i84870.fodt");
|
|
CPPUNIT_ASSERT_EQUAL(2, getPages());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf160549)
|
|
{
|
|
// Given a document with a large as-char object, alone in its paragraph, shifted down by a
|
|
// header object: it must not hang in a layout loop on import (similar to i84870, but not
|
|
// fixed by its fix)
|
|
createSwDoc("tdf160549.fodt");
|
|
// The object is the first in the document; it must not move to the next page
|
|
CPPUNIT_ASSERT_EQUAL(1, getPages());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf160526)
|
|
{
|
|
// Given a document with a large as-char object, alone in its paragraph, shifted down by
|
|
// another body object
|
|
createSwDoc("tdf160526.fodt");
|
|
// It must move to the next page
|
|
CPPUNIT_ASSERT_EQUAL(2, getPages());
|
|
auto pExportDump = parseLayoutDump();
|
|
assertXPath(pExportDump, "//page[2]/body/txt/anchored/SwAnchoredDrawObject");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf160958_page_break)
|
|
{
|
|
// Given a document with a section with the first paragraph having a page break
|
|
createSwDoc("tdf160958_page_break.fodt");
|
|
auto pExportDump = parseLayoutDump();
|
|
assertXPath(pExportDump, "//page", 2);
|
|
// A single paragraph on the first page, with 6 lines
|
|
assertXPath(pExportDump, "//page[1]/body/txt", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt/SwParaPortion/SwLineLayout", 6);
|
|
// A section with 7 paragraphs, and two more paragraphs after the section
|
|
assertXPath(pExportDump, "//page[2]/body/section", 1);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt", 7);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[4]/SwParaPortion/SwLineLayout", 5);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[5]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[6]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[7]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/txt", 2);
|
|
assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout", 7);
|
|
assertXPath(pExportDump, "//page[2]/body/txt[2]/SwParaPortion", 0);
|
|
|
|
// Hide the section
|
|
auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>();
|
|
auto xSections = xTextSectionsSupplier->getTextSections();
|
|
CPPUNIT_ASSERT(xSections);
|
|
auto xSection = xSections->getByName(u"Section1"_ustr).queryThrow<css::beans::XPropertySet>();
|
|
xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(false));
|
|
|
|
calcLayout();
|
|
pExportDump = parseLayoutDump();
|
|
assertXPath(pExportDump, "//page", 1);
|
|
// Three paragraphs and a hidden section on the first page
|
|
assertXPath(pExportDump, "//page/body/txt", 3);
|
|
assertXPath(pExportDump, "//page/body/section", 1);
|
|
|
|
assertXPath(pExportDump, "//page/body/section/infos/bounds", "height", u"0");
|
|
assertXPath(pExportDump, "//page/body/txt[1]/SwParaPortion/SwLineLayout", 6);
|
|
assertXPath(pExportDump, "//page/body/section/txt", 7);
|
|
assertXPath(pExportDump, "//page/body/section/txt[1]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page/body/section/txt[2]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page/body/section/txt[3]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page/body/section/txt[4]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page/body/section/txt[5]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page/body/section/txt[6]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page/body/section/txt[7]/SwParaPortion", 0);
|
|
|
|
assertXPath(pExportDump, "//page/body/txt[2]/SwParaPortion/SwLineLayout", 7);
|
|
assertXPath(pExportDump, "//page/body/txt[3]/SwParaPortion", 0);
|
|
|
|
// Show the section again
|
|
xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
|
|
|
|
// Check that the layout has been restored
|
|
calcLayout();
|
|
pExportDump = parseLayoutDump();
|
|
assertXPath(pExportDump, "//page", 2);
|
|
assertXPath(pExportDump, "//page[1]/body/txt", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt/SwParaPortion/SwLineLayout", 6);
|
|
assertXPath(pExportDump, "//page[2]/body/section", 1);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt", 7);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[4]/SwParaPortion/SwLineLayout", 5);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[5]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[6]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[7]/SwParaPortion", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/txt", 2);
|
|
assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout", 7);
|
|
assertXPath(pExportDump, "//page[2]/body/txt[2]/SwParaPortion", 0);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf160958_orphans)
|
|
{
|
|
// Given a document with a section which moves to the next page as a whole, because of orphans
|
|
createSwDoc("tdf160958_orphans_move_section.fodt");
|
|
auto pExportDump = parseLayoutDump();
|
|
assertXPath(pExportDump, "//page", 2);
|
|
// 21 paragraphs on the first page
|
|
assertXPath(pExportDump, "//page[1]/body/txt", 21);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout", 6);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout", 5);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout", 7);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[4]/SwParaPortion/SwLineLayout", 16);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[5]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[6]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[7]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[8]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[9]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[10]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[11]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[12]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[13]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[14]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[15]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[16]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[17]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[18]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[19]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[20]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[21]/SwParaPortion/SwLineLayout", 1);
|
|
// A section and one more paragraph after the section
|
|
assertXPath(pExportDump, "//page[2]/body/section", 1);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt", 3);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout", 6);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion/SwLineLayout", 5);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion/SwLineLayout", 7);
|
|
assertXPath(pExportDump, "//page[2]/body/txt", 1);
|
|
assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout", 1);
|
|
|
|
// Hide the section
|
|
auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>();
|
|
auto xSections = xTextSectionsSupplier->getTextSections();
|
|
CPPUNIT_ASSERT(xSections);
|
|
auto xSection = xSections->getByName(u"Section1"_ustr).queryThrow<css::beans::XPropertySet>();
|
|
xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(false));
|
|
|
|
calcLayout();
|
|
pExportDump = parseLayoutDump();
|
|
assertXPath(pExportDump, "//page", 1);
|
|
assertXPath(pExportDump, "//page/body/txt", 22);
|
|
assertXPath(pExportDump, "//page/body/section", 1);
|
|
assertXPath(pExportDump, "//page/body/section/infos/bounds", "height", u"0");
|
|
|
|
// Show the section again
|
|
xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
|
|
|
|
// Check that the layout has been restored
|
|
calcLayout();
|
|
pExportDump = parseLayoutDump();
|
|
assertXPath(pExportDump, "//page", 2);
|
|
assertXPath(pExportDump, "//page[1]/body/txt", 21);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout", 6);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout", 5);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout", 7);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[4]/SwParaPortion/SwLineLayout", 16);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[5]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[6]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[7]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[8]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[9]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[10]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[11]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[12]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[13]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[14]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[15]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[16]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[17]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[18]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[19]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[20]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[21]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[2]/body/section", 1);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt", 3);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout", 6);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion/SwLineLayout", 5);
|
|
assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion/SwLineLayout", 7);
|
|
assertXPath(pExportDump, "//page[2]/body/txt", 1);
|
|
assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf161368)
|
|
{
|
|
// Given a document with a text body width of 116 mm, greater than 65535 twips (115.6 mm)
|
|
createSwDoc("tdf161368.fodt");
|
|
auto pExportDump = parseLayoutDump();
|
|
// one page, three paragraphs, each one line (it was four pages, each paragraph split into
|
|
// tens of short (<= 4 mm wide) lines)
|
|
assertXPath(pExportDump, "//page", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt", 3);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout", 1);
|
|
assertXPath(pExportDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestCrashHyphenation)
|
|
{
|
|
//just care it doesn't crash/assert
|
|
createSwDoc("crashHyphen.fodt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf161508)
|
|
{
|
|
// This document must not hang on load.
|
|
createSwDoc("tdf161508.fodt");
|
|
auto pExportDump = parseLayoutDump();
|
|
// The table must move completely to the second page
|
|
assertXPath(pExportDump, "//page[1]/body/tab", 0);
|
|
assertXPath(pExportDump, "//page[2]/body/tab", 1);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf92091)
|
|
{
|
|
// This test verifies that RTL text following an LTR footnote is measured correctly
|
|
createSwDoc("tdf92091.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
sal_Int32 nLayoutWidth
|
|
= getXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout", "width")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(3210), nLayoutWidth);
|
|
|
|
sal_Int32 nPor1Width
|
|
= getXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[1]",
|
|
"width")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(55), nPor1Width);
|
|
|
|
sal_Int32 nPor2Width
|
|
= getXPath(pXmlDoc,
|
|
"/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[1]",
|
|
"width")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(75), nPor2Width);
|
|
|
|
sal_Int32 nPor3Width
|
|
= getXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[2]",
|
|
"width")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(2870), nPor3Width);
|
|
|
|
sal_Int32 nPor4Width
|
|
= getXPath(pXmlDoc,
|
|
"/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion[2]",
|
|
"width")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(75), nPor4Width);
|
|
|
|
sal_Int32 nPor5Width
|
|
= getXPath(pXmlDoc, "/root/page[1]/body/txt[1]/SwParaPortion/SwLineLayout/SwLinePortion[3]",
|
|
"width")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_GREATER(sal_Int32(110), nPor5Width);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf104209VertLTR)
|
|
{
|
|
// Verify that vertical left-to-right text after a fly portion will overflow to the next page.
|
|
createSwDoc("tdf107209-vert-ltr.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 2);
|
|
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout", "portion",
|
|
u"AAAAAAAAAAAAAAAAAAA");
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
|
|
u"BBBBBBBBBBBBBBBBBBBBBB");
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/SwParaPortion/SwLineLayout[2]", "portion",
|
|
u"B");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf104209VertRTL)
|
|
{
|
|
// Verify that vertical right-to-left text after a fly portion will overflow to the next page.
|
|
createSwDoc("tdf107209-vert-rtl.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 2);
|
|
|
|
assertXPath(pXmlDoc, "/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout", "portion",
|
|
u"AAAAAAAAAAAAAAAAAAA");
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/SwParaPortion/SwLineLayout[1]", "portion",
|
|
u"BBBBBBBBBBBBBBBBBBBBBB");
|
|
assertXPath(pXmlDoc, "/root/page[2]/body/txt[1]/SwParaPortion/SwLineLayout[2]", "portion",
|
|
u"B");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf56408LTR)
|
|
{
|
|
// Verify that line breaking a first bidi portion correctly underflows in LTR text
|
|
createSwDoc("tdf56408-ltr.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]", "portion",
|
|
u"English English English ");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]", "portion",
|
|
u"((((עברית)))) English");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf56408RTL)
|
|
{
|
|
// Verify that line breaking a first bidi portion correctly underflows in RTL text
|
|
createSwDoc("tdf56408-rtl.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]", "portion",
|
|
u"עברית עברית עברית ");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]", "portion",
|
|
u"((((English)))) עברית");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf56408NoUnderflow)
|
|
{
|
|
// The fix for tdf#56408 introduced a change to line breaking between text with
|
|
// direction changes. This test verifies behavior in the trivial case, when a
|
|
// break opportunity exists at the direction change boundary.
|
|
createSwDoc("tdf56408-no-underflow.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]", "portion",
|
|
u"English English English ");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]", "portion",
|
|
u"עברית English");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf56408AfterFieldCrash)
|
|
{
|
|
// Verify there is no crash/assertion for underflow after a number field
|
|
createSwDoc("tdf56408-after-field.fodt");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf146081)
|
|
{
|
|
// Verifies that proportional line spacing is consistent with the
|
|
// PropLineSpacingShrinksFirstLine compatibility flag set
|
|
createSwDoc("tdf146081-prop-spacing.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
SwTwips nTotalHeight
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/infos/bounds", "height").toInt32();
|
|
|
|
SwTwips nHeight1
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]", "height")
|
|
.toInt32();
|
|
SwTwips nHeight2
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]", "height")
|
|
.toInt32();
|
|
SwTwips nHeight3
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]", "height")
|
|
.toInt32();
|
|
SwTwips nHeight4
|
|
= getXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[4]", "height")
|
|
.toInt32();
|
|
|
|
// All of the lines must have the same height
|
|
CPPUNIT_ASSERT_EQUAL(nHeight1, nHeight2);
|
|
CPPUNIT_ASSERT_EQUAL(nHeight1, nHeight3);
|
|
CPPUNIT_ASSERT_EQUAL(nHeight1, nHeight4);
|
|
|
|
// The total height of the paragraph must be equal to the sum of all lines
|
|
CPPUNIT_ASSERT_EQUAL(nTotalHeight, nHeight1 * 4);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf155229RowAtLeast)
|
|
{
|
|
createSwDoc("tdf155229_row_height_at_least.docx");
|
|
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
sal_Int32 nTableHeight
|
|
= getXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[11]/infos/bounds", "bottom").toInt32();
|
|
|
|
// Without the fix, this was Actual : 14174
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(15494), nTableHeight);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf164907_rowHeightAtLeast)
|
|
{
|
|
createSwDoc("tdf164907_rowHeightAtLeast.docx");
|
|
|
|
CPPUNIT_ASSERT_EQUAL(1, getPages());
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf157829LTR)
|
|
{
|
|
// Verify that line breaking inside a bidi portion triggers underflow to previous bidi portions
|
|
createSwDoc("tdf157829-ltr.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]", "portion",
|
|
u"English English English ");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]", "portion",
|
|
u"עברית English");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf157829RTL)
|
|
{
|
|
// Verify that line breaking inside a bidi portion triggers underflow to previous bidi portions
|
|
createSwDoc("tdf157829-rtl.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]", "portion",
|
|
u"עברית עברית עברית עברית ");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]", "portion",
|
|
u"English עברית");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf162314)
|
|
{
|
|
// Regression test for bidi portion line breaking where the portion layout ends with underflow,
|
|
// but the bidi portion should not be truncated.
|
|
createSwDoc("tdf162314.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[1]", "portion",
|
|
u"Aa aa aaaa ﷽ ");
|
|
assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[2]", "portion", u"aaaa");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf162614)
|
|
{
|
|
// Given a table inside another table, having a fixed-height last row, with a merged cell
|
|
// spanning two rows, with a text (having a spacing below) wrapping inside that merged cell,
|
|
// positioned so that the first line of the text in on the first page, and the second line
|
|
// flows onto the second page:
|
|
createSwDoc("tdf162614.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
// Make sure that all the tables have the correct positions and sizes
|
|
// I find the clang-formatted version of the following awful (it is already ugly enough)
|
|
// clang-format off
|
|
|
|
assertXPath(pXmlDoc, "//page", 2);
|
|
// One top-level table on page 1 (Table1), with a single row and a single cell
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab", 1);
|
|
OUString sTable1PrecedeId = getXPath(pXmlDoc, "//page[1]/body/tab", "id");
|
|
OUString sTable1FollowId = getXPath(pXmlDoc, "//page[1]/body/tab", "follow");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/infos/bounds", "top", u"2261");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/infos/bounds", "height", u"810");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row", 1);
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell", 1);
|
|
OUString sTable1A1PrecedeId = getXPath(pXmlDoc, "//page[1]/body/tab/row/cell", "id");
|
|
OUString sTable1A1FollowId = getXPath(pXmlDoc, "//page[1]/body/tab/row/cell", "follow");
|
|
// One sub-table inside it (Table2):
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab", 1);
|
|
OUString sTable2PrecedeId = getXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab", "id");
|
|
OUString sTable2FollowId = getXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab", "follow");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/infos/bounds", "top", u"2508");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/infos/bounds", "height", u"543");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row", 1);
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell", 2);
|
|
// A1
|
|
assertXPathNoAttribute(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[1]", "follow");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[1]", "rowspan", u"1");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[1]/txt/SwParaPortion/SwLineLayout/*", 1);
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[1]/txt/SwParaPortion/SwLineLayout/*[1]", "type", u"PortionType::Para");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[1]/txt/SwParaPortion/SwLineLayout/*[1]", "portion", u"Table2.A1");
|
|
// B1
|
|
OUString sTable2B1PrecedeId = getXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]", "id");
|
|
OUString sTable2B1FollowId = getXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]", "follow");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]", "rowspan", u"2");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/infos/bounds", "height", u"523");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/infos/prtBounds", "height", u"503");
|
|
OUString sTable2B1TextPrecedeId = getXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt", "id");
|
|
OUString sTable2B1TextFollowId = getXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt", "follow");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt", "offset", u"0");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt/infos/bounds", "height", u"276");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt/infos/prtBounds", "height", u"276");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt/SwParaPortion/SwLineLayout/*", 2);
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt/SwParaPortion/SwLineLayout/*[1]", "type", u"PortionType::Text");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt/SwParaPortion/SwLineLayout/*[1]", "portion", u"Table2.B1");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row/cell/tab/row/cell[2]/txt/SwParaPortion/SwLineLayout/*[2]", "type", u"PortionType::Hole");
|
|
|
|
// Two top-level tables on page 2
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab", 2);
|
|
// Table1 (follow)
|
|
CPPUNIT_ASSERT_EQUAL(sTable1FollowId, getXPath(pXmlDoc, "//page[2]/body/tab[1]", "id"));
|
|
CPPUNIT_ASSERT_EQUAL(sTable1PrecedeId, getXPath(pXmlDoc, "//page[2]/body/tab[1]", "precede"));
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/infos/bounds", "top", u"3403");
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/infos/bounds", "height", u"514");
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row", 1);
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell", 1);
|
|
CPPUNIT_ASSERT_EQUAL(sTable1A1FollowId, getXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell", "id"));
|
|
CPPUNIT_ASSERT_EQUAL(sTable1A1PrecedeId, getXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell", "precede"));
|
|
// Table2 (follow)
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab", 1);
|
|
CPPUNIT_ASSERT_EQUAL(sTable2FollowId, getXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab", "id"));
|
|
CPPUNIT_ASSERT_EQUAL(sTable2PrecedeId, getXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab", "precede"));
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/infos/bounds", "top", u"3423");
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/infos/bounds", "height", u"474");
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row", 2);
|
|
// Table2 row 1 (continued)
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell", 2);
|
|
// Placeholder for the cell in column 1
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[1]/infos/bounds", "height", u"0");
|
|
// B1 (follow)
|
|
CPPUNIT_ASSERT_EQUAL(sTable2B1FollowId, getXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]", "id"));
|
|
CPPUNIT_ASSERT_EQUAL(sTable2B1PrecedeId, getXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]", "precede"));
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]", "rowspan", u"2");
|
|
// Without the fix, this failed with
|
|
// - Expected: 1
|
|
// - Actual : 2
|
|
// - In <>, XPath '//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]/txt' number of nodes is incorrect
|
|
CPPUNIT_ASSERT_EQUAL(sTable2B1TextFollowId, getXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]/txt", "id"));
|
|
CPPUNIT_ASSERT_EQUAL(sTable2B1TextPrecedeId, getXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]/txt", "precede"));
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]/txt/SwParaPortion/SwLineLayout/*", 1);
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]/txt/SwParaPortion/SwLineLayout/*[1]", "type", u"PortionType::Para");
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[1]/cell[2]/txt/SwParaPortion/SwLineLayout/*[1]", "portion", u"(contd.)");
|
|
// Table2 row 2
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[2]/cell", 2);
|
|
// A2
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout/*", 1);
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout/*[1]", "type", u"PortionType::Para");
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout/*[1]", "portion", u"Table2.A2");
|
|
// B2 (covered cell)
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[1]/row/cell/tab/row[2]/cell[2]", "rowspan", u"-1");
|
|
|
|
// Table3 (must not be collapsed)
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[2]/infos/bounds", "top", u"4696");
|
|
// Without the fix, this failed with
|
|
// - Expected: 770
|
|
// - Actual : 267
|
|
assertXPath(pXmlDoc, "//page[2]/body/tab[2]/infos/bounds", "height", u"770");
|
|
|
|
// Now a test for a case that took me some time to fix when creating the patch.
|
|
// It is the greatly simplified tdf124795-5.
|
|
|
|
createSwDoc("C4_must_start_on_p1.fodt");
|
|
pXmlDoc = parseLayoutDump();
|
|
|
|
// The first line of C4 text must start on the first page - the initial version of the fix
|
|
// moved it to page 2.
|
|
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row[4]/cell[3]/txt/SwParaPortion/SwLineLayout/*", 1);
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row[4]/cell[3]/txt/SwParaPortion/SwLineLayout/*[1]", "type", u"PortionType::Para");
|
|
assertXPath(pXmlDoc, "//page[1]/body/tab/row[4]/cell[3]/txt/SwParaPortion/SwLineLayout/*[1]", "portion", u"C4_xxxxxxxxxxxxxxxxxxxx");
|
|
|
|
// clang-format on
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf152142)
|
|
{
|
|
// Regression test for textbox positioning when anchored as-char in RTL context.
|
|
createSwDoc("tdf152142.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
|
|
SwTwips nTextBoxBegin
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/fly/txt/infos/bounds", "left")
|
|
.toInt32();
|
|
SwTwips nTextBoxEnd
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/fly/txt/infos/bounds", "right")
|
|
.toInt32();
|
|
|
|
SwTwips nShapeBegin
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/SwAnchoredDrawObject/bounds", "left")
|
|
.toInt32();
|
|
SwTwips nShapeEnd
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/SwAnchoredDrawObject/bounds", "right")
|
|
.toInt32();
|
|
|
|
CPPUNIT_ASSERT_GREATER(nShapeBegin, nTextBoxBegin);
|
|
CPPUNIT_ASSERT_LESS(nShapeEnd, nTextBoxEnd);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf152142DoNotMirrorRtlDrawObjs)
|
|
{
|
|
// Regression test for textbox positioning when anchored as-char in RTL context, with the
|
|
// DoNotMirrorRtlDrawObjs compatibility flag set.
|
|
createSwDoc("tdf152142-donotmirror.fodt");
|
|
auto pXmlDoc = parseLayoutDump();
|
|
|
|
assertXPath(pXmlDoc, "//page", 1);
|
|
|
|
SwTwips nTextBoxBegin
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/fly/txt/infos/bounds", "left")
|
|
.toInt32();
|
|
SwTwips nTextBoxEnd
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/fly/txt/infos/bounds", "right")
|
|
.toInt32();
|
|
|
|
SwTwips nShapeBegin
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/SwAnchoredDrawObject/bounds", "left")
|
|
.toInt32();
|
|
SwTwips nShapeEnd
|
|
= getXPath(pXmlDoc, "/root/page/body/txt[2]/anchored/SwAnchoredDrawObject/bounds", "right")
|
|
.toInt32();
|
|
|
|
CPPUNIT_ASSERT_GREATER(nShapeBegin, nTextBoxBegin);
|
|
CPPUNIT_ASSERT_LESS(nShapeEnd, nTextBoxEnd);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, testTdf152298)
|
|
{
|
|
createSwDoc("tdf152298.docx");
|
|
auto pDump = parseLayoutDump();
|
|
|
|
assertXPath(pDump, "//page", 2);
|
|
// Without the fix, this was 39
|
|
assertXPath(pDump, "//page[1]/body/tab/row", 38);
|
|
assertXPath(pDump, "//page[1]/body/tab/row[38]/cell[1]", "rowspan", u"4");
|
|
OUString a38_id = getXPath(pDump, "//page[1]/body/tab/row[38]/cell[1]", "id");
|
|
OUString follow_id = getXPath(pDump, "//page[1]/body/tab/row[38]/cell[1]", "follow");
|
|
// The text of A38, that spans four rows, must be split: empty paragraph here
|
|
assertXPathContent(pDump, "//page[1]/body/tab/row[38]/cell[1]/txt", u"");
|
|
// First row is the repeating line
|
|
assertXPathContent(pDump, "//page[2]/body/tab/row[1]/cell[1]/txt", u"1");
|
|
assertXPathContent(pDump, "//page[2]/body/tab/row[1]/cell[2]/txt", u"2");
|
|
assertXPathContent(pDump, "//page[2]/body/tab/row[1]/cell[3]/txt", u"3");
|
|
// The text in the follow row's first cell is the second paragraph of A38, "10"
|
|
assertXPath(pDump, "//page[2]/body/tab/row[2]/cell[1]", "id", follow_id);
|
|
assertXPath(pDump, "//page[2]/body/tab/row[2]/cell[1]", "precede", a38_id);
|
|
assertXPathContent(pDump, "//page[2]/body/tab/row[2]/cell[1]/txt", u"10");
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf163230)
|
|
{
|
|
createSwDoc("tdf163230.fodt");
|
|
auto pExportDump = parseLayoutDump();
|
|
// The first row must split across pages, despite its "do not break" attribute, because it
|
|
// doesn't fit on the page. Before the fix, the document had only two pages.
|
|
assertXPath(pExportDump, "//page", 3);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf163285)
|
|
{
|
|
createSwDoc("tdf163285.fodt");
|
|
auto pDump = parseLayoutDump();
|
|
// The first row must split across three pages, despite its "do not break" attribute, because it
|
|
// doesn't fit on the whole page.
|
|
// A1 text is created such that its "pg_1", "pg_2" and "pg_3" must start the respective pages.
|
|
assertXPath(pDump, "//page", 3);
|
|
OUString topText1 = getXPathContent(pDump, "//page[1]/body/tab/row[1]/cell[1]/txt[1]");
|
|
CPPUNIT_ASSERT(topText1.startsWith("pg_1"));
|
|
OUString topText2 = getXPathContent(pDump, "//page[2]/body/tab/row[1]/cell[1]/txt[1]");
|
|
CPPUNIT_ASSERT(topText2.startsWith("pg_2"));
|
|
OUString topText3 = getXPathContent(pDump, "//page[3]/body/tab/row[1]/cell[1]/txt[1]");
|
|
// Without the fix, this failed:
|
|
CPPUNIT_ASSERT(topText3.startsWith("pg_3"));
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf152839_firstRows)
|
|
{
|
|
createSwDoc("tdf152839_firstrows.rtf");
|
|
|
|
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
|
|
sal_Int32 nHeight
|
|
= getXPath(pXmlDoc, "/root/page[1]/body/tab[1]/row[1]/cell[2]/txt/infos/bounds", "height")
|
|
.toInt32();
|
|
CPPUNIT_ASSERT_EQUAL(sal_Int32(223), nHeight);
|
|
}
|
|
|
|
CPPUNIT_TEST_FIXTURE(SwLayoutWriter4, TestTdf164098)
|
|
{
|
|
createSwDoc("tdf164098.fodt");
|
|
SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
|
|
|
|
pWrtShell->StartOfSection(false);
|
|
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect*/ false, 6, /*bBasicCall*/ false);
|
|
|
|
// Without the fix, this line will cause a freeze:
|
|
pWrtShell->Insert(u"ـ"_ustr);
|
|
}
|
|
|
|
} // end of anonymous namespace
|
|
|
|
CPPUNIT_PLUGIN_IMPLEMENT();
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|