1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
11 #include <test/bootstrapfixture.hxx>
13 #include <vcl/virdev.hxx>
14 #include <vcl/BitmapReadAccess.hxx>
15 #include <vcl/canvastools.hxx>
16 #include <vcl/graphicfilter.hxx>
17 #include <tools/stream.hxx>
19 #include <com/sun/star/rendering/XBitmap.hpp>
20 #include <com/sun/star/rendering/XCanvas.hpp>
21 #include <com/sun/star/rendering/XBitmapCanvas.hpp>
22 #include <com/sun/star/rendering/CompositeOperation.hpp>
23 #include <com/sun/star/rendering/PathCapType.hpp>
24 #include <com/sun/star/rendering/PathJoinType.hpp>
26 using namespace ::com::sun::star
;
28 class CanvasTest
: public test::BootstrapFixture
30 VclPtr
<VirtualDevice
> mVclDevice
;
31 uno::Reference
<rendering::XCanvas
> mCanvas
;
32 uno::Reference
<rendering::XGraphicDevice
> mDevice
;
33 rendering::ViewState mViewState
;
34 rendering::RenderState mRenderState
;
35 uno::Sequence
<double> mColorBlack
;
36 uno::Sequence
<double> mColorBlue
;
38 // if enabled - check the result images with:
39 // "xdg-open ./workdir/CppunitTest/canvas_test.test.core/"
40 static constexpr const bool mbExportBitmap
= false;
42 void exportDevice(const OUString
& filename
, const VclPtr
<VirtualDevice
>& device
)
46 BitmapEx
aBitmapEx(device
->GetBitmapEx(Point(0, 0), device
->GetOutputSizePixel()));
47 SvFileStream
aStream(filename
, StreamMode::WRITE
| StreamMode::TRUNC
);
48 GraphicFilter::GetGraphicFilter().compressAsPNG(aBitmapEx
, aStream
);
54 : BootstrapFixture(true, false)
58 virtual void setUp() override
60 BootstrapFixture::setUp();
61 mColorBlack
= vcl::unotools::colorToStdColorSpaceSequence(COL_BLACK
);
62 mColorBlue
= vcl::unotools::colorToStdColorSpaceSequence(COL_BLUE
);
64 geometry::AffineMatrix2D
aUnit(1, 0, 0, 0, 1, 0);
65 mViewState
.AffineTransform
= aUnit
;
66 mRenderState
.AffineTransform
= aUnit
;
67 mRenderState
.DeviceColor
= mColorBlack
;
68 mRenderState
.CompositeOperation
= rendering::CompositeOperation::OVER
;
71 virtual void tearDown() override
73 mVclDevice
.disposeAndClear();
74 mCanvas
= uno::Reference
<rendering::XCanvas
>();
75 mDevice
= uno::Reference
<rendering::XGraphicDevice
>();
76 BootstrapFixture::tearDown();
79 void setupCanvas(const Size
& size
, Color backgroundColor
= COL_WHITE
, bool alpha
= false)
82 = alpha
? VclPtr
<VirtualDevice
>::Create(DeviceFormat::DEFAULT
, DeviceFormat::DEFAULT
)
83 : VclPtr
<VirtualDevice
>::Create(DeviceFormat::DEFAULT
);
84 mVclDevice
->SetOutputSizePixel(size
);
85 mVclDevice
->SetBackground(Wallpaper(backgroundColor
));
87 mCanvas
= mVclDevice
->GetCanvas();
88 CPPUNIT_ASSERT(mCanvas
.is());
90 = uno::Reference
<rendering::XGraphicDevice
>(mCanvas
->getDevice(), uno::UNO_SET_THROW
);
91 CPPUNIT_ASSERT(mDevice
.is());
96 setupCanvas(Size(10, 10));
97 mCanvas
->drawLine(geometry::RealPoint2D(1, 1), geometry::RealPoint2D(9, 1), mViewState
,
99 exportDevice("test-draw-line.png", mVclDevice
);
100 Bitmap bitmap
= mVclDevice
->GetBitmap(Point(), mVclDevice
->GetOutputSizePixel());
101 Bitmap::ScopedReadAccess
access(bitmap
);
102 // Canvas uses AA, which blurs the line, and it cannot be turned off,
103 // so do not check the end points.
104 CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_WHITE
), access
->GetPixel(0, 0));
105 CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_BLACK
), access
->GetPixel(1, 2));
106 CPPUNIT_ASSERT_EQUAL(BitmapColor(COL_BLACK
), access
->GetPixel(1, 8));
109 // Draw a dashed line scaled, make sure the dashing is scaled properly.
112 setupCanvas(Size(1000, 100));
113 // Scale everything up by 10 (2 in render state, 5 in view state).
114 mRenderState
.AffineTransform
= geometry::AffineMatrix2D(2, 0, 0, 0, 2, 0);
115 mViewState
.AffineTransform
= geometry::AffineMatrix2D(5, 0, 0, 0, 5, 0);
117 uno::Sequence
<uno::Sequence
<geometry::RealPoint2D
>> polygonPoints
{ { { 10, 5 },
119 uno::Reference
<rendering::XLinePolyPolygon2D
> polygon
120 = mDevice
->createCompatibleLinePolyPolygon(polygonPoints
);
121 polygon
->setClosed(0, false);
123 mRenderState
.DeviceColor
= mColorBlue
;
124 rendering::StrokeAttributes strokeAttributes
;
125 strokeAttributes
.StrokeWidth
= 2.0;
126 strokeAttributes
.MiterLimit
= 2.0; // ?
127 strokeAttributes
.StartCapType
= rendering::PathCapType::ROUND
;
128 strokeAttributes
.EndCapType
= rendering::PathCapType::ROUND
;
129 strokeAttributes
.JoinType
= rendering::PathJoinType::MITER
;
130 strokeAttributes
.DashArray
= { 10, 5, 0.1, 5 };
132 mCanvas
->strokePolyPolygon(polygon
, mViewState
, mRenderState
, strokeAttributes
);
134 exportDevice("test-tdf134053.png", mVclDevice
);
135 Bitmap bitmap
= mVclDevice
->GetBitmap(Point(), mVclDevice
->GetOutputSizePixel());
136 Bitmap::ScopedReadAccess
access(bitmap
);
143 // There should be a long dash at X 100-200, a dot at 250, long one at 300-400, a dot at 450, etc.
144 // until a dot at 850. Add -5/+5 to account for round caps.
145 const Check checks
[] = { { 0, 85, COL_WHITE
}, // empty start
146 // dash, space, dot, space
147 { 95, 205, COL_BLUE
},
148 { 215, 235, COL_WHITE
},
149 { 245, 255, COL_BLUE
},
150 { 265, 285, COL_WHITE
},
151 { 295, 405, COL_BLUE
},
152 { 415, 435, COL_WHITE
},
153 { 445, 455, COL_BLUE
},
154 { 465, 485, COL_WHITE
},
155 { 495, 605, COL_BLUE
},
156 { 615, 635, COL_WHITE
},
157 { 645, 655, COL_BLUE
},
158 { 665, 685, COL_WHITE
},
159 { 695, 805, COL_BLUE
},
160 { 815, 835, COL_WHITE
},
161 { 845, 855, COL_BLUE
},
162 { 865, 999, COL_WHITE
} }; // empty end
163 for (const Check
& check
: checks
)
165 for (tools::Long x
= check
.start
; x
<= check
.end
; ++x
)
167 if (access
->GetColor(50, x
) != check
.color
)
169 std::ostringstream str
;
171 CPPUNIT_ASSERT_EQUAL_MESSAGE(str
.str(), BitmapColor(check
.color
),
172 access
->GetColor(50, x
));
178 CPPUNIT_TEST_SUITE(CanvasTest
);
179 CPPUNIT_TEST(testDrawLine
);
180 CPPUNIT_TEST(testTdf134053
);
181 CPPUNIT_TEST_SUITE_END();
184 CPPUNIT_TEST_SUITE_REGISTRATION(CanvasTest
);
186 CPPUNIT_PLUGIN_IMPLEMENT();
188 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */