LibreOffice Module canvas (master) 1
simplecanvasimpl.cxx
Go to the documentation of this file.
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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
24#include <com/sun/star/lang/IllegalArgumentException.hpp>
25#include <com/sun/star/lang/XServiceName.hpp>
26#include <com/sun/star/rendering/CompositeOperation.hpp>
27#include <com/sun/star/rendering/PanoseLetterForm.hpp>
28#include <com/sun/star/rendering/PanoseWeight.hpp>
29#include <com/sun/star/rendering/XSimpleCanvas.hpp>
30#include <com/sun/star/uno/XComponentContext.hpp>
33#include <o3tl/lazy_update.hxx>
34
36
37
38#include <functional>
39
40using namespace ::com::sun::star;
41using namespace canvas;
42
43namespace
44{
45 uno::Sequence< double > color2Sequence( sal_Int32 nColor )
46 {
47 // TODO(F3): Color management
48 uno::Sequence< double > aRes{
49 static_cast<sal_uInt8>( (nColor&0xFF000000U) >> 24U ) / 255.0,
50 static_cast<sal_uInt8>( (nColor&0x00FF0000U) >> 16U ) / 255.0,
51 static_cast<sal_uInt8>( (nColor&0x0000FF00U) >> 8U ) / 255.0,
52 static_cast<sal_uInt8>( (nColor&0x000000FFU) ) / 255.0
53 };
54 return aRes;
55 }
56
57 uno::Reference< rendering::XPolyPolygon2D > rect2Poly( uno::Reference<rendering::XGraphicDevice> const& xDevice,
58 geometry::RealRectangle2D const& rRect )
59 {
60 uno::Sequence< geometry::RealPoint2D > rectSequence{
61 geometry::RealPoint2D( rRect.X1, rRect.Y1 ),
62 geometry::RealPoint2D( rRect.X2, rRect.Y1 ),
63 geometry::RealPoint2D( rRect.X2, rRect.Y2 ),
64 geometry::RealPoint2D( rRect.X1, rRect.Y2 )
65 };
66 uno::Sequence< uno::Sequence< geometry::RealPoint2D > > sequenceSequence{ rectSequence };
67 uno::Reference< rendering::XPolyPolygon2D > xRes =
68 xDevice->createCompatibleLinePolyPolygon( sequenceSequence );
69 if( xRes.is() )
70 xRes->setClosed( 0, true );
71 return xRes;
72 }
73
74 struct SimpleRenderState
75 {
76 o3tl::LazyUpdate<sal_Int32,
77 uno::Sequence<double>,
78 decltype(&color2Sequence)> m_aPenColor;
79 o3tl::LazyUpdate<sal_Int32,
80 uno::Sequence<double>,
81 decltype(&color2Sequence)> m_aFillColor;
82 o3tl::LazyUpdate<geometry::RealRectangle2D,
83 uno::Reference< rendering::XPolyPolygon2D >,
84 std::function<uno::Reference<rendering::XPolyPolygon2D> (geometry::RealRectangle2D)> > m_aRectClip;
85 geometry::AffineMatrix2D m_aTransformation;
86
87 explicit SimpleRenderState( uno::Reference<rendering::XGraphicDevice> const& xDevice ) :
88 m_aPenColor( &color2Sequence),
89 m_aFillColor( &color2Sequence ),
90 m_aRectClip( [&xDevice](geometry::RealRectangle2D const& rRect) { return rect2Poly(xDevice, rRect); } )
91 {
92 tools::setIdentityAffineMatrix2D( m_aTransformation );
93 }
94 };
95
96
97 typedef ::cppu::WeakComponentImplHelper< css::rendering::XSimpleCanvas,
98 css::lang::XServiceName > SimpleCanvasBase;
99
100 class SimpleCanvasImpl : private cppu::BaseMutex,
101 public SimpleCanvasBase
102 {
103 private:
104 bool isStrokingEnabled() const
105 {
106 return maRenderState.m_aPenColor.getInValue() % 0x100 != 0;
107 }
108
109 rendering::RenderState createStrokingRenderState() const
110 {
111 return rendering::RenderState(maRenderState.m_aTransformation,
112 *maRenderState.m_aRectClip,
113 *maRenderState.m_aPenColor,
114 rendering::CompositeOperation::OVER);
115 }
116
117 bool isFillingEnabled() const
118 {
119 return maRenderState.m_aFillColor.getInValue() % 0x100 != 0;
120 }
121
122 rendering::RenderState createFillingRenderState() const
123 {
124 return rendering::RenderState(maRenderState.m_aTransformation,
125 *maRenderState.m_aRectClip,
126 *maRenderState.m_aFillColor,
127 rendering::CompositeOperation::OVER);
128 }
129
130 static uno::Reference<rendering::XCanvas> grabCanvas( uno::Sequence<uno::Any> const& rArgs )
131 {
132 uno::Reference<rendering::XCanvas> xRet;
133
134 // can't do much without an XCanvas, can't we?
135 if( !rArgs.hasElements() )
136 throw lang::IllegalArgumentException();
137
138 xRet.set( rArgs[0], uno::UNO_QUERY );
139
140 // can't do much without an XCanvas, can't we?
141 if( !xRet.is() )
142 throw lang::IllegalArgumentException();
143
144 return xRet;
145 }
146
147 public:
148 SimpleCanvasImpl( const uno::Sequence< uno::Any >& aArguments,
149 const uno::Reference< uno::XComponentContext >& ) :
150 SimpleCanvasBase( m_aMutex ),
151 mxCanvas( grabCanvas(aArguments) ),
152 maFont([this](rendering::FontRequest const& rFontRequest) {
153 return mxCanvas->createFont(rFontRequest,
154 uno::Sequence< beans::PropertyValue >(),
155 geometry::Matrix2D()); } ),
156 maRenderState( mxCanvas->getDevice() )
157 {
158 tools::initViewState(maViewState);
159 }
160
161
162 private:
163 // Ifc XServiceName
164 virtual OUString SAL_CALL getServiceName( ) override
165 {
166 return "com.sun.star.rendering.SimpleCanvas";
167 }
168
169 // Ifc XSimpleCanvas
170 virtual void SAL_CALL selectFont( const OUString& sFontName,
171 double size,
172 sal_Bool bold,
173 sal_Bool italic ) override
174 {
175 ::osl::MutexGuard aGuard( m_aMutex );
176
177 maFont->FontDescription.FamilyName = sFontName;
178 maFont->CellSize = size;
179 maFont->FontDescription.FontDescription.Weight =
180 bold ? rendering::PanoseWeight::BOLD : rendering::PanoseWeight::MEDIUM;
181 maFont->FontDescription.FontDescription.Letterform =
182 italic ? rendering::PanoseLetterForm::OBLIQUE_CONTACT : rendering::PanoseLetterForm::ANYTHING;
183 }
184
185 virtual void SAL_CALL setPenColor( ::sal_Int32 nsRgbaColor ) override
186 {
187 ::osl::MutexGuard aGuard( m_aMutex );
188 *(maRenderState.m_aPenColor) = nsRgbaColor;
189 }
190
191 virtual void SAL_CALL setFillColor( ::sal_Int32 nsRgbaColor ) override
192 {
193 ::osl::MutexGuard aGuard( m_aMutex );
194 *(maRenderState.m_aFillColor) = nsRgbaColor;
195 }
196
197 virtual void SAL_CALL setRectClip( const geometry::RealRectangle2D& aRect ) override
198 {
199 ::osl::MutexGuard aGuard( m_aMutex );
200 *(maRenderState.m_aRectClip) = aRect;
201 }
202
203 virtual void SAL_CALL setTransformation( const geometry::AffineMatrix2D& aTransform ) override
204 {
205 ::osl::MutexGuard aGuard( m_aMutex );
206 maRenderState.m_aTransformation = aTransform;
207 }
208
209 virtual void SAL_CALL drawPixel( const geometry::RealPoint2D& aPoint ) override
210 {
211 ::osl::MutexGuard aGuard( m_aMutex );
212 mxCanvas->drawPoint(aPoint,
213 maViewState,
214 createFillingRenderState());
215 }
216
217 virtual void SAL_CALL drawLine( const geometry::RealPoint2D& aStartPoint,
218 const geometry::RealPoint2D& aEndPoint ) override
219 {
220 ::osl::MutexGuard aGuard( m_aMutex );
221 mxCanvas->drawLine(aStartPoint,
222 aEndPoint,
223 maViewState,
224 createStrokingRenderState());
225 }
226
227 virtual void SAL_CALL drawRect( const geometry::RealRectangle2D& aRect ) override
228 {
229 ::osl::MutexGuard aGuard( m_aMutex );
230 uno::Reference< rendering::XPolyPolygon2D > xPoly(
231 rect2Poly( mxCanvas->getDevice(),
232 aRect));
233
234 if( isFillingEnabled() )
235 mxCanvas->drawPolyPolygon(xPoly,
236 maViewState,
237 createFillingRenderState());
238 if( isStrokingEnabled() )
239 mxCanvas->drawPolyPolygon(xPoly,
240 maViewState,
241 createStrokingRenderState());
242 }
243
244 virtual void SAL_CALL drawPolyPolygon( const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon ) override
245 {
246 ::osl::MutexGuard aGuard( m_aMutex );
247
248 if( isFillingEnabled() )
249 mxCanvas->drawPolyPolygon(xPolyPolygon,
250 maViewState,
251 createFillingRenderState());
252 if( isStrokingEnabled() )
253 mxCanvas->drawPolyPolygon(xPolyPolygon,
254 maViewState,
255 createStrokingRenderState());
256 }
257
258 virtual void SAL_CALL drawText( const rendering::StringContext& aText,
259 const geometry::RealPoint2D& aOutPos,
260 ::sal_Int8 nTextDirection ) override
261 {
262 ::osl::MutexGuard aGuard( m_aMutex );
263 const basegfx::B2DHomMatrix offsetTransform(basegfx::utils::createTranslateB2DHomMatrix(aOutPos.X,aOutPos.Y));
264 rendering::RenderState aRenderState( createStrokingRenderState() );
265 tools::appendToRenderState(aRenderState, offsetTransform);
266
267 mxCanvas->drawText(aText,
268 maFont.getOutValue(),
269 maViewState,
270 aRenderState,
271 nTextDirection);
272 }
273
274 virtual void SAL_CALL drawBitmap( const uno::Reference< rendering::XBitmap >& xBitmap,
275 const geometry::RealPoint2D& aLeftTop ) override
276 {
277 ::osl::MutexGuard aGuard( m_aMutex );
278 const basegfx::B2DHomMatrix offsetTransform(basegfx::utils::createTranslateB2DHomMatrix(aLeftTop.X,aLeftTop.Y));
279 rendering::RenderState aRenderState( createStrokingRenderState() );
280 tools::appendToRenderState(aRenderState, offsetTransform);
281
282 mxCanvas->drawBitmap(xBitmap,maViewState,aRenderState);
283 }
284
285 virtual uno::Reference< rendering::XGraphicDevice > SAL_CALL getDevice( ) override
286 {
287 ::osl::MutexGuard aGuard( m_aMutex );
288 return mxCanvas->getDevice();
289 }
290
291 virtual uno::Reference< rendering::XCanvas > SAL_CALL getCanvas( ) override
292 {
293 ::osl::MutexGuard aGuard( m_aMutex );
294 return mxCanvas;
295 }
296
297 virtual rendering::FontMetrics SAL_CALL getFontMetrics( ) override
298 {
299 ::osl::MutexGuard aGuard( m_aMutex );
300 return maFont.getOutValue()->getFontMetrics();
301 }
302
303 virtual uno::Reference< rendering::XCanvasFont > SAL_CALL getCurrentFont( ) override
304 {
305 ::osl::MutexGuard aGuard( m_aMutex );
306 return maFont.getOutValue();
307 }
308
309 virtual ::sal_Int32 SAL_CALL getCurrentPenColor( ) override
310 {
311 ::osl::MutexGuard aGuard( m_aMutex );
312 return maRenderState.m_aPenColor.getInValue();
313 }
314
315 virtual ::sal_Int32 SAL_CALL getCurrentFillColor( ) override
316 {
317 ::osl::MutexGuard aGuard( m_aMutex );
318 return maRenderState.m_aFillColor.getInValue();
319 }
320
321 virtual geometry::RealRectangle2D SAL_CALL getCurrentClipRect( ) override
322 {
323 ::osl::MutexGuard aGuard( m_aMutex );
324 return maRenderState.m_aRectClip.getInValue();
325 }
326
327 virtual geometry::AffineMatrix2D SAL_CALL getCurrentTransformation( ) override
328 {
329 ::osl::MutexGuard aGuard( m_aMutex );
330 return maRenderState.m_aTransformation;
331 }
332
333 virtual rendering::ViewState SAL_CALL getCurrentViewState( ) override
334 {
335 ::osl::MutexGuard aGuard( m_aMutex );
336 return maViewState;
337 }
338
339 virtual rendering::RenderState SAL_CALL getCurrentRenderState( sal_Bool bUseFillColor ) override
340 {
341 ::osl::MutexGuard aGuard( m_aMutex );
342 if( bUseFillColor )
343 return createFillingRenderState();
344 else
345 return createStrokingRenderState();
346 }
347
348
349 typedef o3tl::LazyUpdate<
350 rendering::FontRequest,
351 uno::Reference< rendering::XCanvasFont >,
352 std::function<uno::Reference<rendering::XCanvasFont> (rendering::FontRequest)> > SimpleFont;
353
354 uno::Reference<rendering::XCanvas> mxCanvas;
355 SimpleFont maFont;
356 rendering::ViewState maViewState;
357 SimpleRenderState maRenderState;
358 };
359
360}
361
362extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
364 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& args)
365{
366 return cppu::acquire(new SimpleCanvasImpl(args, context));
367}
368
369/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< rendering::XCanvas > mxCanvas
std::mutex m_aMutex
Sequence< PropertyValue > aArguments
void drawLine(VirtualDevice *dev, Point const &orig, Point const &dest, Size const &pSize)
bold
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
size
rendering::RenderState & appendToRenderState(rendering::RenderState &renderState, const ::basegfx::B2DHomMatrix &rTransform)
geometry::AffineMatrix2D & setIdentityAffineMatrix2D(geometry::AffineMatrix2D &matrix)
rendering::ViewState & initViewState(rendering::ViewState &viewState)
Definition: canvastools.cxx:85
args
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_rendering_SimpleCanvas(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &args)
unsigned char sal_uInt8
unsigned char sal_Bool
signed char sal_Int8
::basegfx::B2DHomMatrix m_aTransformation