/* -*- 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/.
*/
namespace
{ /// Test to assert layout / rendering result of Writer. class SwLayoutWriter4 : public SwModelTestBase
{ public:
SwLayoutWriter4()
: SwModelTestBase(u"/sw/qa/extras/layout/data/"_ustr)
{
}
};
// 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");
}
}
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);
}
// 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);
}
// 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);
}
// 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).
// 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()));
}
// 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);
}
// 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);
}
// 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);
}
// 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);
}
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, 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_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);
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.
// 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.
// 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
// 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);
}
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());
// 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 -->");
}
// 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");
}
// Move cursor into position to insert image
dispatchCommand(mxComponent, u".uno:GoToEndOfPara"_ustr, {});
dispatchCommand(mxComponent, u".uno:GoDown"_ustr, {});
// 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);
// 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);
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);
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
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet)
¤
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.