summaryrefslogtreecommitdiff
path: root/sw/qa/core/objectpositioning/objectpositioning.cxx
blob: 58ea30b3ce53d8bb9524ed21a8cca9e931c34f8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* -*- 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 <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>

#include <wrtsh.hxx>
#include <unotxdoc.hxx>
#include <docsh.hxx>

char const DATA_DIRECTORY[] = "/sw/qa/core/objectpositioning/data/";

/// Covers sw/source/core/objectpositioning/ fixes.
class SwCoreObjectpositioningTest : public SwModelTestBase
{
};

CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testOverlapCrash)
{
    // Load a document with 2 images.
    load(DATA_DIRECTORY, "overlap-crash.odt");

    // Change their anchor type to to-char.
    uno::Reference<beans::XPropertySet> xShape1(getShape(1), uno::UNO_QUERY);
    xShape1->setPropertyValue("AnchorType", uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
    uno::Reference<beans::XPropertySet> xShape2(getShape(1), uno::UNO_QUERY);
    xShape2->setPropertyValue("AnchorType", uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));

    // Insert a new paragraph at the start.
    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
    SwDocShell* pDocShell = pTextDoc->GetDocShell();
    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
    // Without the accompanying fix in place, this test would have crashed.
    pWrtShell->SplitNode();
}

CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertPosFromBottom)
{
    // Create a document, insert a shape and position it 1cm above the bottom of the body area.
    mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
    uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
    uno::Reference<drawing::XShape> xShape(
        xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
    xShape->setSize(awt::Size(10000, 10000));
    uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
    xShapeProps->setPropertyValue("AnchorType",
                                  uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
    xShapeProps->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::NONE));
    xShapeProps->setPropertyValue("VertOrientRelation",
                                  uno::makeAny(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM));
    xShapeProps->setPropertyValue("VertOrientPosition",
                                  uno::makeAny(static_cast<sal_Int32>(-11000)));
    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
    xDrawPageSupplier->getDrawPage()->add(xShape);

    // Verify that the distance between the body and anchored object bottom is indeed around 1cm.
    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    sal_Int32 nBodyBottom = getXPath(pXmlDoc, "//body/infos/bounds", "bottom").toInt32();
    sal_Int32 nAnchoredBottom
        = getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds", "bottom").toInt32();
    // Without the accompanying fix in place, this test would have failed with:
    // - Expected: 564
    // - Actual  : 9035
    // i.e. the vertical position was from-top, not from-bottom.
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(564), nBodyBottom - nAnchoredBottom);
}

CPPUNIT_TEST_FIXTURE(SwCoreObjectpositioningTest, testVertAlignBottomMargin)
{
    // Create a document, insert three shapes and align it the bottom,center,top of page print area bottom.
    // The size of shapes are 284 ~ 0.5cm
    // The height of page print area bottom is 1134 ~ 2cm
    mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
    uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);

    //Create first shape and align bottom of page print area bottom.
    uno::Reference<drawing::XShape> xShapeBottom(
        xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
    xShapeBottom->setSize(awt::Size(500, 500));
    uno::Reference<beans::XPropertySet> xShapePropsBottom(xShapeBottom, uno::UNO_QUERY);
    xShapePropsBottom->setPropertyValue("AnchorType",
                                        uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
    xShapePropsBottom->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::BOTTOM));
    xShapePropsBottom->setPropertyValue("VertOrientRelation",
                                        uno::makeAny(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM));
    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplierBottom(mxComponent, uno::UNO_QUERY);
    xDrawPageSupplierBottom->getDrawPage()->add(xShapeBottom);

    //Create second shape and align center of page print area bottom.
    uno::Reference<drawing::XShape> xShapeCenter(
        xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
    xShapeCenter->setSize(awt::Size(500, 500));
    uno::Reference<beans::XPropertySet> xShapePropsCenter(xShapeCenter, uno::UNO_QUERY);
    xShapePropsCenter->setPropertyValue("AnchorType",
                                        uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
    xShapePropsCenter->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::CENTER));
    xShapePropsCenter->setPropertyValue("VertOrientRelation",
                                        uno::makeAny(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM));
    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplierCenter(mxComponent, uno::UNO_QUERY);
    xDrawPageSupplierCenter->getDrawPage()->add(xShapeCenter);

    //Create third shape and align top of page print area bottom.
    uno::Reference<drawing::XShape> xShapeTop(
        xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
    xShapeTop->setSize(awt::Size(500, 500));
    uno::Reference<beans::XPropertySet> xShapePropsTop(xShapeTop, uno::UNO_QUERY);
    xShapePropsTop->setPropertyValue("AnchorType",
                                     uno::makeAny(text::TextContentAnchorType_AT_CHARACTER));
    xShapePropsTop->setPropertyValue("VertOrient", uno::makeAny(text::VertOrientation::TOP));
    xShapePropsTop->setPropertyValue("VertOrientRelation",
                                     uno::makeAny(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM));
    uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplierTop(mxComponent, uno::UNO_QUERY);
    xDrawPageSupplierTop->getDrawPage()->add(xShapeTop);

    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
    sal_Int32 nBodyBottom = getXPath(pXmlDoc, "//body/infos/bounds", "bottom").toInt32(); //14989
    sal_Int32 nPageBottom = getXPath(pXmlDoc, "//page/infos/bounds", "bottom").toInt32(); //16123
    sal_Int32 nFirstShapeBottom
        = getXPath(pXmlDoc, "//SwAnchoredDrawObject[1]/bounds", "bottom").toInt32(); //16124
    sal_Int32 nSecondShapeBottom
        = getXPath(pXmlDoc, "//SwAnchoredDrawObject[2]/bounds", "bottom").toInt32(); //15699
    sal_Int32 nSecondShapeTop
        = getXPath(pXmlDoc, "//SwAnchoredDrawObject[2]/bounds", "top").toInt32(); //15414
    sal_Int32 nThirdShapeTop
        = getXPath(pXmlDoc, "//SwAnchoredDrawObject[3]/bounds", "top").toInt32(); //14989

    // Verify that the distance between the bottom of page and bottom of first shape is around 0cm. (align=bottom)
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), nFirstShapeBottom - nPageBottom);
    // Verify that the distance between the bottom of page and bottom of second shape is around 0.75cm and
    // verify that the distance between the bottom of body and top of second shape is around 0.75cm.(align=center)
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(424), nPageBottom - nSecondShapeBottom);
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(425), nSecondShapeTop - nBodyBottom);
    // Verify that the distance between the bottom of body and top of third shape is around 0cm. (align=top)
    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nThirdShapeTop - nBodyBottom);
}
CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */