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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <com/sun/star/rendering/XSimpleCanvas.hpp>
22 #include <com/sun/star/rendering/CompositeOperation.hpp>
23 #include <com/sun/star/rendering/PanoseLetterForm.hpp>
24 #include <com/sun/star/rendering/PanoseWeight.hpp>
25 #include <com/sun/star/lang/XServiceName.hpp>
27 #include <o3tl/lazy_update.hxx>
28 #include <cppuhelper/factory.hxx>
29 #include <cppuhelper/implementationentry.hxx>
30 #include <cppuhelper/compbase2.hxx>
31 #include <cppuhelper/basemutex.hxx>
33 #include <comphelper/servicedecl.hxx>
35 #include <basegfx/matrix/b2dhommatrix.hxx>
36 #include <basegfx/matrix/b2dhommatrixtools.hxx>
38 #include <canvas/canvastools.hxx>
40 #include <boost/bind.hpp>
42 #define SERVICE_NAME "com.sun.star.rendering.SimpleCanvas"
44 using namespace ::com::sun::star
;
45 using namespace canvas
;
49 inline uno::Sequence
< double > color2Sequence( sal_Int32 nColor
)
51 // TODO(F3): Color management
52 uno::Sequence
< double > aRes( 4 );
54 aRes
[0] = static_cast<sal_uInt8
>( (nColor
&0xFF000000U
) >> 24U ) / 255.0;
55 aRes
[1] = static_cast<sal_uInt8
>( (nColor
&0x00FF0000U
) >> 16U ) / 255.0;
56 aRes
[2] = static_cast<sal_uInt8
>( (nColor
&0x0000FF00U
) >> 8U ) / 255.0;
57 aRes
[3] = static_cast<sal_uInt8
>( (nColor
&0x000000FFU
) ) / 255.0;
62 inline uno::Reference
< rendering::XPolyPolygon2D
> rect2Poly( uno::Reference
<rendering::XGraphicDevice
> const& xDevice
,
63 geometry::RealRectangle2D
const& rRect
)
65 uno::Sequence
< geometry::RealPoint2D
> rectSequence( 4 );
66 geometry::RealPoint2D
* pOutput
= rectSequence
.getArray();
67 pOutput
[0] = geometry::RealPoint2D( rRect
.X1
, rRect
.Y1
);
68 pOutput
[1] = geometry::RealPoint2D( rRect
.X2
, rRect
.Y1
);
69 pOutput
[2] = geometry::RealPoint2D( rRect
.X2
, rRect
.Y2
);
70 pOutput
[3] = geometry::RealPoint2D( rRect
.X1
, rRect
.Y2
);
72 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > sequenceSequence( 1 );
73 sequenceSequence
[0] = rectSequence
;
75 uno::Reference
< rendering::XPolyPolygon2D
> xRes(
76 xDevice
->createCompatibleLinePolyPolygon( sequenceSequence
),
79 xRes
->setClosed( 0, sal_True
);
83 struct SimpleRenderState
85 o3tl::LazyUpdate
<sal_Int32
,
86 uno::Sequence
<double>,
87 decltype(&color2Sequence
)> m_aPenColor
;
88 o3tl::LazyUpdate
<sal_Int32
,
89 uno::Sequence
<double>,
90 decltype(&color2Sequence
)> m_aFillColor
;
91 o3tl::LazyUpdate
<geometry::RealRectangle2D
,
92 uno::Reference
< rendering::XPolyPolygon2D
>,
93 boost::function1
<uno::Reference
<rendering::XPolyPolygon2D
>, geometry::RealRectangle2D
> > m_aRectClip
;
94 geometry::AffineMatrix2D m_aTransformation
;
96 explicit SimpleRenderState( uno::Reference
<rendering::XGraphicDevice
> const& xDevice
) :
97 m_aPenColor( &color2Sequence
),
98 m_aFillColor( &color2Sequence
),
99 m_aRectClip( boost::bind( &rect2Poly
,
104 tools::setIdentityAffineMatrix2D( m_aTransformation
);
109 typedef ::cppu::WeakComponentImplHelper2
< ::com::sun::star::rendering::XSimpleCanvas
,
110 ::com::sun::star::lang::XServiceName
> SimpleCanvasBase
;
112 class SimpleCanvasImpl
: private cppu::BaseMutex
,
113 public SimpleCanvasBase
116 bool isStrokingEnabled() const
118 return maRenderState
.m_aPenColor
.getInValue() && sal_Int32(0xFF) != 0;
121 rendering::RenderState
createStrokingRenderState() const
123 return rendering::RenderState(maRenderState
.m_aTransformation
,
124 *maRenderState
.m_aRectClip
,
125 *maRenderState
.m_aPenColor
,
126 rendering::CompositeOperation::OVER
);
129 bool isFillingEnabled() const
131 return maRenderState
.m_aFillColor
.getInValue() && sal_Int32(0xFF) != 0;
134 rendering::RenderState
createFillingRenderState() const
136 return rendering::RenderState(maRenderState
.m_aTransformation
,
137 *maRenderState
.m_aRectClip
,
138 *maRenderState
.m_aFillColor
,
139 rendering::CompositeOperation::OVER
);
142 static uno::Reference
<rendering::XCanvas
> grabCanvas( uno::Sequence
<uno::Any
> const& rArgs
)
144 uno::Reference
<rendering::XCanvas
> xRet
;
146 // can't do much without an XCanvas, can't we?
147 if( rArgs
.getLength() < 1 )
148 throw lang::IllegalArgumentException();
150 xRet
.set( rArgs
[0], uno::UNO_QUERY
);
152 // can't do much without an XCanvas, can't we?
154 throw lang::IllegalArgumentException();
160 SimpleCanvasImpl( const uno::Sequence
< uno::Any
>& aArguments
,
161 const uno::Reference
< uno::XComponentContext
>& ) :
162 SimpleCanvasBase( m_aMutex
),
163 mxCanvas( grabCanvas(aArguments
) ),
164 maFont(boost::bind( &rendering::XCanvas::createFont
,
165 boost::cref(mxCanvas
),
167 uno::Sequence
< beans::PropertyValue
>(),
168 geometry::Matrix2D() )),
170 maRenderState( mxCanvas
->getDevice() )
172 tools::initViewState(maViewState
);
179 virtual OUString SAL_CALL
getServiceName( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
181 return OUString( SERVICE_NAME
);
185 virtual void SAL_CALL
selectFont( const OUString
& sFontName
,
188 sal_Bool italic
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
190 ::osl::MutexGuard
aGuard( m_aMutex
);
192 maFont
->FontDescription
.FamilyName
= sFontName
;
193 maFont
->CellSize
= size
;
194 maFont
->FontDescription
.FontDescription
.Weight
=
195 bold
? rendering::PanoseWeight::BOLD
: rendering::PanoseWeight::MEDIUM
;
196 maFont
->FontDescription
.FontDescription
.Letterform
=
197 italic
? rendering::PanoseLetterForm::OBLIQUE_CONTACT
: rendering::PanoseLetterForm::ANYTHING
;
200 virtual void SAL_CALL
setPenColor( ::sal_Int32 nsRgbaColor
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
202 ::osl::MutexGuard
aGuard( m_aMutex
);
203 *(maRenderState
.m_aPenColor
) = nsRgbaColor
;
206 virtual void SAL_CALL
setFillColor( ::sal_Int32 nsRgbaColor
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
208 ::osl::MutexGuard
aGuard( m_aMutex
);
209 *(maRenderState
.m_aFillColor
) = nsRgbaColor
;
212 virtual void SAL_CALL
setRectClip( const geometry::RealRectangle2D
& aRect
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
214 ::osl::MutexGuard
aGuard( m_aMutex
);
215 *(maRenderState
.m_aRectClip
) = aRect
;
218 virtual void SAL_CALL
setTransformation( const geometry::AffineMatrix2D
& aTransform
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
220 ::osl::MutexGuard
aGuard( m_aMutex
);
221 maRenderState
.m_aTransformation
= aTransform
;
224 virtual void SAL_CALL
drawPixel( const geometry::RealPoint2D
& aPoint
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
226 ::osl::MutexGuard
aGuard( m_aMutex
);
227 mxCanvas
->drawPoint(aPoint
,
229 createFillingRenderState());
232 virtual void SAL_CALL
drawLine( const geometry::RealPoint2D
& aStartPoint
,
233 const geometry::RealPoint2D
& aEndPoint
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
235 ::osl::MutexGuard
aGuard( m_aMutex
);
236 mxCanvas
->drawLine(aStartPoint
,
239 createStrokingRenderState());
242 virtual void SAL_CALL
drawRect( const geometry::RealRectangle2D
& aRect
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
244 ::osl::MutexGuard
aGuard( m_aMutex
);
245 uno::Reference
< rendering::XPolyPolygon2D
> xPoly(
246 rect2Poly( mxCanvas
->getDevice(),
249 if( isFillingEnabled() )
250 mxCanvas
->drawPolyPolygon(xPoly
,
252 createFillingRenderState());
253 if( isStrokingEnabled() )
254 mxCanvas
->drawPolyPolygon(xPoly
,
256 createStrokingRenderState());
259 virtual void SAL_CALL
drawPolyPolygon( const uno::Reference
< rendering::XPolyPolygon2D
>& xPolyPolygon
)
260 throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
262 ::osl::MutexGuard
aGuard( m_aMutex
);
264 if( isFillingEnabled() )
265 mxCanvas
->drawPolyPolygon(xPolyPolygon
,
267 createFillingRenderState());
268 if( isStrokingEnabled() )
269 mxCanvas
->drawPolyPolygon(xPolyPolygon
,
271 createStrokingRenderState());
274 virtual void SAL_CALL
drawText( const rendering::StringContext
& aText
,
275 const geometry::RealPoint2D
& aOutPos
,
276 ::sal_Int8 nTextDirection
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
278 ::osl::MutexGuard
aGuard( m_aMutex
);
279 const basegfx::B2DHomMatrix
offsetTransform(basegfx::tools::createTranslateB2DHomMatrix(aOutPos
.X
,aOutPos
.Y
));
280 rendering::RenderState
aRenderState( createStrokingRenderState() );
281 tools::appendToRenderState(aRenderState
, offsetTransform
);
283 mxCanvas
->drawText(aText
,
284 maFont
.getOutValue(),
290 virtual void SAL_CALL
drawBitmap( const uno::Reference
< rendering::XBitmap
>& xBitmap
,
291 const geometry::RealPoint2D
& aLeftTop
)
292 throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
294 ::osl::MutexGuard
aGuard( m_aMutex
);
295 const basegfx::B2DHomMatrix
offsetTransform(basegfx::tools::createTranslateB2DHomMatrix(aLeftTop
.X
,aLeftTop
.Y
));
296 rendering::RenderState
aRenderState( createStrokingRenderState() );
297 tools::appendToRenderState(aRenderState
, offsetTransform
);
299 mxCanvas
->drawBitmap(xBitmap
,maViewState
,aRenderState
);
302 virtual uno::Reference
< rendering::XGraphicDevice
> SAL_CALL
getDevice( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
304 ::osl::MutexGuard
aGuard( m_aMutex
);
305 return mxCanvas
->getDevice();
308 virtual uno::Reference
< rendering::XCanvas
> SAL_CALL
getCanvas( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
310 ::osl::MutexGuard
aGuard( m_aMutex
);
314 virtual rendering::FontMetrics SAL_CALL
getFontMetrics( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
316 ::osl::MutexGuard
aGuard( m_aMutex
);
317 return maFont
.getOutValue()->getFontMetrics();
320 virtual uno::Reference
< rendering::XCanvasFont
> SAL_CALL
getCurrentFont( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
322 ::osl::MutexGuard
aGuard( m_aMutex
);
323 return maFont
.getOutValue();
326 virtual ::sal_Int32 SAL_CALL
getCurrentPenColor( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
328 ::osl::MutexGuard
aGuard( m_aMutex
);
329 return maRenderState
.m_aPenColor
.getInValue();
332 virtual ::sal_Int32 SAL_CALL
getCurrentFillColor( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
334 ::osl::MutexGuard
aGuard( m_aMutex
);
335 return maRenderState
.m_aFillColor
.getInValue();
338 virtual geometry::RealRectangle2D SAL_CALL
getCurrentClipRect( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
340 ::osl::MutexGuard
aGuard( m_aMutex
);
341 return maRenderState
.m_aRectClip
.getInValue();
344 virtual geometry::AffineMatrix2D SAL_CALL
getCurrentTransformation( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
346 ::osl::MutexGuard
aGuard( m_aMutex
);
347 return maRenderState
.m_aTransformation
;
350 virtual rendering::ViewState SAL_CALL
getCurrentViewState( ) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
352 ::osl::MutexGuard
aGuard( m_aMutex
);
356 virtual rendering::RenderState SAL_CALL
getCurrentRenderState( sal_Bool bUseFillColor
) throw (uno::RuntimeException
, std::exception
) SAL_OVERRIDE
358 ::osl::MutexGuard
aGuard( m_aMutex
);
360 return createFillingRenderState();
362 return createStrokingRenderState();
367 typedef o3tl::LazyUpdate
<
368 rendering::FontRequest
,
369 uno::Reference
< rendering::XCanvasFont
>,
370 boost::function1
<uno::Reference
<rendering::XCanvasFont
>, rendering::FontRequest
> > SimpleFont
;
372 uno::Reference
<rendering::XCanvas
> mxCanvas
;
374 rendering::ViewState maViewState
;
375 SimpleRenderState maRenderState
;
378 namespace sdecl
= comphelper::service_decl
;
379 const sdecl::ServiceDecl
simpleCanvasDecl(
380 sdecl::class_
<SimpleCanvasImpl
, sdecl::with_args
<true> >(),
381 "com.sun.star.comp.rendering.SimpleCanvas",
385 // The C shared lib entry points
386 COMPHELPER_SERVICEDECL_EXPORTS1(simplecanvas
, simpleCanvasDecl
)
388 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */