1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 */
10
11 #include <test/outputdevice.hxx>
12
13 #include <basegfx/matrix/b2dhommatrix.hxx>
14 #include <vcl/BitmapReadAccess.hxx>
15
16 #include <list>
17
18 namespace vcl::test {
19
20 namespace
21 {
22
drawLineOffset(OutputDevice & rDevice,tools::Rectangle const & rRect,int nOffset)23 void drawLineOffset(OutputDevice& rDevice, tools::Rectangle const & rRect, int nOffset)
24 {
25 Point aLeftTop (rRect.Left() + nOffset, rRect.Top() + nOffset);
26 Point aRightTop (rRect.Right() - nOffset, rRect.Top() + nOffset);
27 Point aLeftBottom (rRect.Left() + nOffset, rRect.Bottom() - nOffset);
28 Point aRightBottom (rRect.Right() - nOffset, rRect.Bottom() - nOffset);
29
30 rDevice.DrawLine(aLeftTop, aRightTop);
31 rDevice.DrawLine(aRightTop, aRightBottom);
32 rDevice.DrawLine(aRightBottom, aLeftBottom);
33 rDevice.DrawLine(aLeftBottom, aLeftTop);
34 }
35
36 } // end anonymous namespace
37
setupRectangle(bool bEnableAA)38 Bitmap OutputDeviceTestLine::setupRectangle(bool bEnableAA)
39 {
40 initialSetup(13, 13, constBackgroundColor, bEnableAA);
41
42 mpVirtualDevice->SetLineColor(constLineColor);
43 mpVirtualDevice->SetFillColor();
44
45 drawLineOffset(*mpVirtualDevice, maVDRectangle, 2);
46 drawLineOffset(*mpVirtualDevice, maVDRectangle, 5);
47
48 return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
49 }
50
setupDiamond()51 Bitmap OutputDeviceTestLine::setupDiamond()
52 {
53 initialSetup(11, 11, constBackgroundColor);
54
55 mpVirtualDevice->SetLineColor(constLineColor);
56 mpVirtualDevice->SetFillColor();
57
58 Point aPoint1, aPoint2, aPoint3, aPoint4;
59 OutputDeviceTestCommon::createDiamondPoints(maVDRectangle, 4, aPoint1, aPoint2, aPoint3, aPoint4);
60
61 mpVirtualDevice->DrawLine(aPoint1, aPoint2);
62 mpVirtualDevice->DrawLine(aPoint2, aPoint3);
63 mpVirtualDevice->DrawLine(aPoint3, aPoint4);
64 mpVirtualDevice->DrawLine(aPoint4, aPoint1);
65
66 return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
67 }
68
setupLines()69 Bitmap OutputDeviceTestLine::setupLines()
70 {
71 initialSetup(13, 13, constBackgroundColor);
72
73 mpVirtualDevice->SetLineColor(constLineColor);
74 mpVirtualDevice->SetFillColor();
75
76 Point aHorizontalLinePoint1, aHorizontalLinePoint2;
77 Point aVerticalLinePoint1, aVerticalLinePoint2;
78 Point aDiagonalLinePoint1, aDiagonalLinePoint2;
79
80 OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(
81 maVDRectangle, aHorizontalLinePoint1, aHorizontalLinePoint2,
82 aVerticalLinePoint1, aVerticalLinePoint2,
83 aDiagonalLinePoint1, aDiagonalLinePoint2);
84
85 mpVirtualDevice->DrawLine(aHorizontalLinePoint1, aHorizontalLinePoint2);
86 mpVirtualDevice->DrawLine(aVerticalLinePoint1, aVerticalLinePoint2);
87 mpVirtualDevice->DrawLine(aDiagonalLinePoint1, aDiagonalLinePoint2);
88
89 return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
90 }
91
setupAALines()92 Bitmap OutputDeviceTestLine::setupAALines()
93 {
94 initialSetup(13, 13, constBackgroundColor);
95
96 mpVirtualDevice->SetAntialiasing(AntialiasingFlags::Enable);
97 mpVirtualDevice->SetLineColor(constLineColor);
98 mpVirtualDevice->SetFillColor();
99
100 Point aHorizontalLinePoint1, aHorizontalLinePoint2;
101 Point aVerticalLinePoint1, aVerticalLinePoint2;
102 Point aDiagonalLinePoint1, aDiagonalLinePoint2;
103
104 OutputDeviceTestCommon::createHorizontalVerticalDiagonalLinePoints(
105 maVDRectangle, aHorizontalLinePoint1, aHorizontalLinePoint2,
106 aVerticalLinePoint1, aVerticalLinePoint2,
107 aDiagonalLinePoint1, aDiagonalLinePoint2);
108
109 mpVirtualDevice->DrawLine(aHorizontalLinePoint1, aHorizontalLinePoint2);
110 mpVirtualDevice->DrawLine(aVerticalLinePoint1, aVerticalLinePoint2);
111 mpVirtualDevice->DrawLine(aDiagonalLinePoint1, aDiagonalLinePoint2);
112
113 return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
114 }
115
setupDashedLine()116 Bitmap OutputDeviceTestLine::setupDashedLine()
117 {
118 initialSetup(13, 13, constBackgroundColor);
119
120 mpVirtualDevice->SetLineColor(constLineColor);
121 mpVirtualDevice->SetFillColor();
122
123 tools::Rectangle rectangle = maVDRectangle;
124 rectangle.shrink(2);
125
126 std::vector<double> stroke({ 2.0, 1.0 });
127 mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(),
128 basegfx::B2DPolygon{
129 basegfx::B2DPoint(rectangle.getX(), rectangle.getY()),
130 basegfx::B2DPoint(rectangle.getX(), rectangle.getY() + rectangle.getHeight()),
131 basegfx::B2DPoint(rectangle.getX() + rectangle.getWidth(),
132 rectangle.getY() + rectangle.getHeight()),
133 basegfx::B2DPoint(rectangle.getX() + rectangle.getWidth(), rectangle.getY()),
134 basegfx::B2DPoint(rectangle.getX(), rectangle.getY())},
135 1, 0, &stroke, basegfx::B2DLineJoin::NONE );
136
137 return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
138 }
139
checkDashedLine(Bitmap & rBitmap)140 TestResult OutputDeviceTestLine::checkDashedLine(Bitmap& rBitmap)
141 {
142 TestResult returnValue = TestResult::Passed;
143 for (int i = 0; i < 7; i++)
144 {
145 TestResult eResult = TestResult::Passed;
146 if( i == 2 )
147 {
148 // Build a sequence of pixels for the drawn rectangle border,
149 // check that they alternate appropriately (there should be
150 // normally 2 line, 1 background).
151 std::list< bool > dash; // true - line color, false - background
152 const int width = rBitmap.GetSizePixel().Width();
153 const int height = rBitmap.GetSizePixel().Height();
154 BitmapReadAccess access(rBitmap);
155 for( int x = 2; x < width - 2; ++x )
156 dash.push_back( access.GetPixel( 2, x ) == constLineColor );
157 for( int y = 3; y < height - 3; ++y )
158 dash.push_back( access.GetPixel( y, width - 3 ) == constLineColor );
159 for( int x = width - 3; x >= 2; --x )
160 dash.push_back( access.GetPixel( height - 3, x ) == constLineColor );
161 for( int y = height - 4; y >= 3; --y )
162 dash.push_back( access.GetPixel( y, 2 ) == constLineColor );
163 for( int x = 2; x < width - 2; ++x ) // repeat, to check also the corner
164 dash.push_back( access.GetPixel( 2, x ) == constLineColor );
165 bool last = false;
166 int lastCount = 0;
167 while( !dash.empty())
168 {
169 if( dash.front() == last )
170 {
171 ++lastCount;
172 if( lastCount > ( last ? 4 : 3 ))
173 eResult = TestResult::Failed;
174 else if( lastCount > ( last ? 3 : 2 ) && eResult != TestResult::Failed)
175 eResult = TestResult::PassedWithQuirks;
176 }
177 else
178 {
179 last = dash.front();
180 lastCount = 1;
181 }
182 dash.pop_front();
183 }
184 }
185 else
186 {
187 eResult = OutputDeviceTestCommon::checkRectangle(rBitmap, i, constBackgroundColor);
188 }
189
190 if (eResult == TestResult::Failed)
191 returnValue = TestResult::Failed;
192 if (eResult == TestResult::PassedWithQuirks && returnValue != TestResult::Failed)
193 returnValue = TestResult::PassedWithQuirks;
194 }
195 return returnValue;
196 }
197
198 constexpr int CAPSHRINK = 25;
199 constexpr int CAPWIDTH = 20;
setupLineCap(css::drawing::LineCap lineCap)200 Bitmap OutputDeviceTestLine::setupLineCap( css::drawing::LineCap lineCap )
201 {
202 initialSetup(101, 101, constBackgroundColor);
203
204 mpVirtualDevice->SetLineColor(constLineColor);
205 mpVirtualDevice->SetFillColor();
206
207 tools::Rectangle rectangle = maVDRectangle;
208 rectangle.shrink(CAPSHRINK);
209
210 const basegfx::B2DPolygon poly{
211 basegfx::B2DPoint(rectangle.LeftCenter().getX(), rectangle.LeftCenter().getY()),
212 basegfx::B2DPoint(rectangle.RightCenter().getX(), rectangle.RightCenter().getY())};
213
214 mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(),poly,
215 CAPWIDTH, 0, nullptr, basegfx::B2DLineJoin::NONE, lineCap );
216
217 mpVirtualDevice->SetLineColor(constFillColor);
218 mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(), poly,
219 0, 0, nullptr, basegfx::B2DLineJoin::NONE );
220
221 return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
222 }
223
setupLineJoin(basegfx::B2DLineJoin lineJoin)224 Bitmap OutputDeviceTestLine::setupLineJoin( basegfx::B2DLineJoin lineJoin )
225 {
226 initialSetup(101, 101, constBackgroundColor);
227
228 mpVirtualDevice->SetLineColor(constLineColor);
229 mpVirtualDevice->SetFillColor();
230
231 tools::Rectangle rectangle = maVDRectangle;
232 rectangle.shrink(CAPSHRINK);
233
234 const basegfx::B2DPolygon poly{
235 basegfx::B2DPoint(rectangle.TopLeft().getX(), rectangle.TopLeft().getY()),
236 basegfx::B2DPoint(rectangle.TopRight().getX(), rectangle.TopRight().getY()),
237 basegfx::B2DPoint(rectangle.BottomRight().getX(), rectangle.BottomRight().getY())};
238
239 mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(), poly,
240 CAPWIDTH, 0, nullptr, lineJoin );
241
242 mpVirtualDevice->SetLineColor(constFillColor);
243 mpVirtualDevice->DrawPolyLineDirect( basegfx::B2DHomMatrix(), poly,
244 0, 0, nullptr, lineJoin );
245
246 return mpVirtualDevice->GetBitmap(maVDRectangle.TopLeft(), maVDRectangle.GetSize());
247 }
248
249 } // end namespace vcl::test
250
251 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
252