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/.
10 #include <config_cairo_canvas.h>
12 #include <sal/config.h>
14 #include <vcl/wrkwin.hxx>
15 #include <vcl/canvastools.hxx>
16 #include <vcl/virdev.hxx>
17 #include <vcl/gdimtf.hxx>
18 #include <vcl/metaact.hxx>
20 #include <com/sun/star/rendering/XBitmap.hpp>
21 #include <com/sun/star/rendering/XCanvas.hpp>
22 #include <com/sun/star/rendering/XBitmapCanvas.hpp>
24 #include <cppcanvas/vclfactory.hxx>
26 using namespace ::com::sun::star
;
28 static std::ostream
& operator<<(std::ostream
& rStream
, const KernArray
& rArray
)
37 for (size_t i
= 0; i
< rArray
.size() - 1; i
++)
38 rStream
<< rArray
[i
] << ", ";
39 rStream
<< rArray
.back();
44 static std::ostream
& operator<<(std::ostream
& rStream
, const std::vector
<sal_Bool
>& rVec
)
53 for (size_t i
= 0; i
< rVec
.size() - 1; i
++)
54 rStream
<< std::boolalpha
<< bool(rVec
[i
]) << ", ";
55 rStream
<< std::boolalpha
<< bool(rVec
.back());
60 #include <test/bootstrapfixture.hxx>
62 class CanvasTest
: public test::BootstrapFixture
66 : BootstrapFixture(true, false)
71 CPPUNIT_TEST_FIXTURE(CanvasTest
, testComposite
)
73 ScopedVclPtrInstance
<WorkWindow
> pWin(nullptr, WB_STDWORK
);
75 uno::Reference
<rendering::XCanvas
> xCanvas
= pWin
->GetOutDev()->GetCanvas();
76 CPPUNIT_ASSERT(xCanvas
.is());
80 uno::Reference
<rendering::XBitmap
> xBitmap
= xCanvas
->getDevice()->createCompatibleAlphaBitmap(
81 vcl::unotools::integerSize2DFromSize(aSize
));
82 CPPUNIT_ASSERT(xBitmap
.is());
84 uno::Reference
<rendering::XBitmapCanvas
> xBitmapCanvas(xBitmap
, uno::UNO_QUERY
);
85 CPPUNIT_ASSERT(xBitmapCanvas
.is());
89 // clear the canvas and basic sanity check ...
90 xBitmapCanvas
->clear();
91 CPPUNIT_ASSERT(aBitmapEx
.Create(xBitmapCanvas
, aSize
));
92 CPPUNIT_ASSERT(aBitmapEx
.IsAlpha());
93 CPPUNIT_ASSERT(!aBitmapEx
.GetAlphaMask().IsEmpty());
98 rendering::RenderState aDefaultState
;
99 uno::Sequence
<double> aRedTransparent
{ 1.0, // R
103 aDefaultState
.DeviceColor
= aRedTransparent
;
105 // words fail me to describe the sheer beauty of allocating a UNO
106 // object to represent a polygon, and manually handling the ViewState
107 // and there being no public helper for this - to render ... a rectangle.
108 XCachedPrimitive
fillPolyPolygon( [in
] XPolyPolygon2D xPolyPolygon
, [in
] ViewState aViewState
, [in
] RenderState aRenderState
)
113 CPPUNIT_TEST_FIXTURE(CanvasTest
, testTdf155810
)
115 GDIMetaFile aInputMetaFile
, aOutputMetaFile
;
117 std::vector
<sal_Bool
> aKashidaArray
;
119 // First create a meta file with a text array action that has Kashida adjustments.
121 ScopedVclPtrInstance
<VirtualDevice
> pDev
;
123 vcl::Font
aFont(u
"Noto Naskh Arabic"_ustr
, u
"Regular"_ustr
, Size(0, 72));
124 pDev
->SetFont(aFont
);
126 aInputMetaFile
.Record(pDev
.get());
128 OUString
aText(u
"خالد"_ustr
);
129 pDev
->GetTextArray(aText
, &aDXArray
);
132 aDXArray
[0] += nKashida
;
133 aDXArray
[2] += nKashida
;
134 aKashidaArray
= { true, false, true, false };
136 pDev
->DrawTextArray(Point(0, 0), aText
, aDXArray
, aKashidaArray
, 0, -1);
138 aInputMetaFile
.Stop();
141 // Then draw it using canvas
143 ScopedVclPtrInstance
<VirtualDevice
> pDev
;
145 aOutputMetaFile
.Record(pDev
.get());
147 auto xCanvas
= pDev
->GetCanvas();
148 CPPUNIT_ASSERT(xCanvas
.is());
149 auto pCanvas
= cppcanvas::VCLFactory::createCanvas(xCanvas
);
151 auto pRenderer
= cppcanvas::VCLFactory::createRenderer(pCanvas
, aInputMetaFile
, {});
154 aOutputMetaFile
.Stop();
157 // Then check that the text array drawn by the canvas renderer didn’t loose
158 // the Kashida insertion positions.
160 auto pInputAction
= aInputMetaFile
.GetAction(aInputMetaFile
.GetActionSize() - 1);
161 auto pOutputAction
= aOutputMetaFile
.GetAction(aOutputMetaFile
.GetActionSize() - 2);
163 CPPUNIT_ASSERT_EQUAL(MetaActionType::TEXTARRAY
, pInputAction
->GetType());
164 CPPUNIT_ASSERT_EQUAL(pInputAction
->GetType(), pOutputAction
->GetType());
166 MetaTextArrayAction
* pInputTextAction
= static_cast<MetaTextArrayAction
*>(pInputAction
);
167 MetaTextArrayAction
* pOutputTextAction
= static_cast<MetaTextArrayAction
*>(pOutputAction
);
169 CPPUNIT_ASSERT_EQUAL(pInputTextAction
->GetDXArray(), aDXArray
);
170 CPPUNIT_ASSERT_EQUAL(pInputTextAction
->GetDXArray(), pOutputTextAction
->GetDXArray());
172 CPPUNIT_ASSERT_EQUAL(pInputTextAction
->GetKashidaArray(), aKashidaArray
);
173 CPPUNIT_ASSERT_EQUAL(pInputTextAction
->GetKashidaArray(),
174 pOutputTextAction
->GetKashidaArray());
177 // Now, test drawSubset
179 ScopedVclPtrInstance
<VirtualDevice
> pDev
;
181 aOutputMetaFile
.Clear();
182 aOutputMetaFile
.Record(pDev
.get());
184 auto xCanvas
= pDev
->GetCanvas();
185 CPPUNIT_ASSERT(xCanvas
.is());
186 auto pCanvas
= cppcanvas::VCLFactory::createCanvas(xCanvas
);
188 auto pRenderer
= cppcanvas::VCLFactory::createRenderer(pCanvas
, aInputMetaFile
, {});
189 pRenderer
->drawSubset(1, 3);
191 aOutputMetaFile
.Stop();
195 auto pOutputAction
= aOutputMetaFile
.GetAction(aOutputMetaFile
.GetActionSize() - 2);
197 CPPUNIT_ASSERT_EQUAL(MetaActionType::TEXTARRAY
, pOutputAction
->GetType());
199 MetaTextArrayAction
* pOutputTextAction
= static_cast<MetaTextArrayAction
*>(pOutputAction
);
200 std::vector
<sal_Bool
> aSubsetKashidaArray({ false, true });
202 CPPUNIT_ASSERT_EQUAL(aSubsetKashidaArray
, pOutputTextAction
->GetKashidaArray());
206 CPPUNIT_PLUGIN_IMPLEMENT();
208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */