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
const& 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 o3tl::LAZYUPDATE_FUNCTION_TAG
> m_aPenColor
;
88 o3tl::LazyUpdate
<sal_Int32
,
89 uno::Sequence
<double>,
90 o3tl::LAZYUPDATE_FUNCTION_TAG
> m_aFillColor
;
91 o3tl::LazyUpdate
<geometry::RealRectangle2D
,
92 uno::Reference
< rendering::XPolyPolygon2D
>,
93 o3tl::LAZYUPDATE_FUNCTOR_TAG
> 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
);
175 ///////////////////////////////////////////////////////////////////////////////////////////////
179 virtual OUString SAL_CALL
getServiceName( ) throw (uno::RuntimeException
)
181 return OUString( SERVICE_NAME
);
185 virtual void SAL_CALL
selectFont( const OUString
& sFontName
,
188 ::sal_Bool italic
) throw (uno::RuntimeException
)
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
)
202 ::osl::MutexGuard
aGuard( m_aMutex
);
203 *(maRenderState
.m_aPenColor
) = nsRgbaColor
;
206 virtual void SAL_CALL
setFillColor( ::sal_Int32 nsRgbaColor
) throw (uno::RuntimeException
)
208 ::osl::MutexGuard
aGuard( m_aMutex
);
209 *(maRenderState
.m_aFillColor
) = nsRgbaColor
;
212 virtual void SAL_CALL
setRectClip( const geometry::RealRectangle2D
& aRect
) throw (uno::RuntimeException
)
214 ::osl::MutexGuard
aGuard( m_aMutex
);
215 *(maRenderState
.m_aRectClip
) = aRect
;
218 virtual void SAL_CALL
setTransformation( const geometry::AffineMatrix2D
& aTransform
) throw (uno::RuntimeException
)
220 ::osl::MutexGuard
aGuard( m_aMutex
);
221 maRenderState
.m_aTransformation
= aTransform
;
224 virtual void SAL_CALL
drawPixel( const geometry::RealPoint2D
& aPoint
) throw (uno::RuntimeException
)
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
)
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
)
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
) throw (uno::RuntimeException
)
261 ::osl::MutexGuard
aGuard( m_aMutex
);
263 if( isFillingEnabled() )
264 mxCanvas
->drawPolyPolygon(xPolyPolygon
,
266 createFillingRenderState());
267 if( isStrokingEnabled() )
268 mxCanvas
->drawPolyPolygon(xPolyPolygon
,
270 createStrokingRenderState());
273 virtual void SAL_CALL
drawText( const rendering::StringContext
& aText
,
274 const geometry::RealPoint2D
& aOutPos
,
275 ::sal_Int8 nTextDirection
) throw (uno::RuntimeException
)
277 ::osl::MutexGuard
aGuard( m_aMutex
);
278 const basegfx::B2DHomMatrix
offsetTransform(basegfx::tools::createTranslateB2DHomMatrix(aOutPos
.X
,aOutPos
.Y
));
279 rendering::RenderState
aRenderState( createStrokingRenderState() );
280 tools::appendToRenderState(aRenderState
, offsetTransform
);
282 mxCanvas
->drawText(aText
,
283 maFont
.getOutValue(),
289 virtual void SAL_CALL
drawBitmap( const uno::Reference
< rendering::XBitmap
>& xBitmap
,
290 const geometry::RealPoint2D
& aLeftTop
) throw (uno::RuntimeException
)
292 ::osl::MutexGuard
aGuard( m_aMutex
);
293 const basegfx::B2DHomMatrix
offsetTransform(basegfx::tools::createTranslateB2DHomMatrix(aLeftTop
.X
,aLeftTop
.Y
));
294 rendering::RenderState
aRenderState( createStrokingRenderState() );
295 tools::appendToRenderState(aRenderState
, offsetTransform
);
297 mxCanvas
->drawBitmap(xBitmap
,maViewState
,aRenderState
);
300 virtual uno::Reference
< rendering::XGraphicDevice
> SAL_CALL
getDevice( ) throw (uno::RuntimeException
)
302 ::osl::MutexGuard
aGuard( m_aMutex
);
303 return mxCanvas
->getDevice();
306 virtual uno::Reference
< rendering::XCanvas
> SAL_CALL
getCanvas( ) throw (uno::RuntimeException
)
308 ::osl::MutexGuard
aGuard( m_aMutex
);
312 virtual rendering::FontMetrics SAL_CALL
getFontMetrics( ) throw (uno::RuntimeException
)
314 ::osl::MutexGuard
aGuard( m_aMutex
);
315 return maFont
.getOutValue()->getFontMetrics();
318 virtual uno::Reference
< rendering::XCanvasFont
> SAL_CALL
getCurrentFont( ) throw (uno::RuntimeException
)
320 ::osl::MutexGuard
aGuard( m_aMutex
);
321 return maFont
.getOutValue();
324 virtual ::sal_Int32 SAL_CALL
getCurrentPenColor( ) throw (uno::RuntimeException
)
326 ::osl::MutexGuard
aGuard( m_aMutex
);
327 return maRenderState
.m_aPenColor
.getInValue();
330 virtual ::sal_Int32 SAL_CALL
getCurrentFillColor( ) throw (uno::RuntimeException
)
332 ::osl::MutexGuard
aGuard( m_aMutex
);
333 return maRenderState
.m_aFillColor
.getInValue();
336 virtual geometry::RealRectangle2D SAL_CALL
getCurrentClipRect( ) throw (uno::RuntimeException
)
338 ::osl::MutexGuard
aGuard( m_aMutex
);
339 return maRenderState
.m_aRectClip
.getInValue();
342 virtual geometry::AffineMatrix2D SAL_CALL
getCurrentTransformation( ) throw (uno::RuntimeException
)
344 ::osl::MutexGuard
aGuard( m_aMutex
);
345 return maRenderState
.m_aTransformation
;
348 virtual rendering::ViewState SAL_CALL
getCurrentViewState( ) throw (uno::RuntimeException
)
350 ::osl::MutexGuard
aGuard( m_aMutex
);
354 virtual rendering::RenderState SAL_CALL
getCurrentRenderState( sal_Bool bUseFillColor
) throw (uno::RuntimeException
)
356 ::osl::MutexGuard
aGuard( m_aMutex
);
358 return createFillingRenderState();
360 return createStrokingRenderState();
363 ///////////////////////////////////////////////////////////////////////////////////////////////
365 typedef o3tl::LazyUpdate
<
366 rendering::FontRequest
,
367 uno::Reference
< rendering::XCanvasFont
>,
368 o3tl::LAZYUPDATE_FUNCTOR_TAG
> SimpleFont
;
370 uno::Reference
<rendering::XCanvas
> mxCanvas
;
372 rendering::ViewState maViewState
;
373 SimpleRenderState maRenderState
;
376 namespace sdecl
= comphelper::service_decl
;
377 const sdecl::ServiceDecl
simpleCanvasDecl(
378 sdecl::class_
<SimpleCanvasImpl
, sdecl::with_args
<true> >(),
379 "com.sun.star.comp.rendering.SimpleCanvas",
383 // The C shared lib entry points
384 COMPHELPER_SERVICEDECL_EXPORTS1(simplecanvas
, simpleCanvasDecl
)
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */