Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/qa/extras/layout/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 94 kB image not shown  

Quelle  layout4.cxx   Sprache: 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>

#include <officecfg/Office/Common.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");

    // disable Field Names warning dialog
    const bool bAsk = officecfg::Office::Common::Misc::QueryShowFieldName::get();
    std::shared_ptr<comphelper::ConfigurationChanges> xChanges;
    if (bAsk)
    {
        xChanges = comphelper::ConfigurationChanges::create();
        officecfg::Office::Common::Misc::QueryShowFieldName::set(false, xChanges);
        xChanges->commit();
    }

    // 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");
    }

    if (bAsk)
    {
        officecfg::Office::Common::Misc::QueryShowFieldName::set(true, xChanges);
        xChanges->commit();
    }

    // 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().toString());
    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().toString());
    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 text and hole portions,
    // and the break was on a separate third line
    assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]/*", 4);
    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]/*[2]", "show-underline",
                u"true");
    assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]/*[3]", "type",
                u"PortionType::Hole");
    assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]/*[3]", "show-underline",
                u"false");
    assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout[3]/*[4]", "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);
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=93 H=100 G=96

¤ Dauer der Verarbeitung: 0.7 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.