1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: simplecanvasimpl.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_canvas.hxx"
34 #include <com/sun/star/rendering/XSimpleCanvas.hpp>
35 #include <com/sun/star/rendering/CompositeOperation.hpp>
36 #include <com/sun/star/rendering/PanoseLetterForm.hpp>
37 #include <com/sun/star/rendering/PanoseWeight.hpp>
38 #include <com/sun/star/lang/XServiceName.hpp>
40 #include <o3tl/lazy_update.hxx>
41 #include <cppuhelper/factory.hxx>
42 #include <cppuhelper/implementationentry.hxx>
43 #include <cppuhelper/compbase2.hxx>
44 #include <cppuhelper/basemutex.hxx>
46 #include <comphelper/servicedecl.hxx>
48 #include <basegfx/matrix/b2dhommatrix.hxx>
50 #include "canvas/canvastools.hxx"
52 #include <boost/bind.hpp>
54 #define SERVICE_NAME "com.sun.star.rendering.SimpleCanvas"
56 using namespace ::com::sun::star
;
57 using namespace canvas
;
61 inline uno::Sequence
< double > color2Sequence( sal_Int32
const& nColor
)
63 // TODO(F3): Color management
64 uno::Sequence
< double > aRes( 4 );
66 aRes
[0] = static_cast<sal_uInt8
>( (nColor
&0xFF000000U
) >> 24U ) / 255.0;
67 aRes
[1] = static_cast<sal_uInt8
>( (nColor
&0x00FF0000U
) >> 16U ) / 255.0;
68 aRes
[2] = static_cast<sal_uInt8
>( (nColor
&0x0000FF00U
) >> 8U ) / 255.0;
69 aRes
[3] = static_cast<sal_uInt8
>( (nColor
&0x000000FFU
) ) / 255.0;
74 inline uno::Reference
< rendering::XPolyPolygon2D
> rect2Poly( uno::Reference
<rendering::XGraphicDevice
> const& xDevice
,
75 geometry::RealRectangle2D
const& rRect
)
77 uno::Sequence
< geometry::RealPoint2D
> rectSequence( 4 );
78 geometry::RealPoint2D
* pOutput
= rectSequence
.getArray();
79 pOutput
[0] = geometry::RealPoint2D( rRect
.X1
, rRect
.Y1
);
80 pOutput
[1] = geometry::RealPoint2D( rRect
.X2
, rRect
.Y1
);
81 pOutput
[2] = geometry::RealPoint2D( rRect
.X2
, rRect
.Y2
);
82 pOutput
[3] = geometry::RealPoint2D( rRect
.X1
, rRect
.Y2
);
84 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > sequenceSequence( 1 );
85 sequenceSequence
[0] = rectSequence
;
87 uno::Reference
< rendering::XPolyPolygon2D
> xRes(
88 xDevice
->createCompatibleLinePolyPolygon( sequenceSequence
),
91 xRes
->setClosed( 0, sal_True
);
95 struct SimpleRenderState
97 o3tl::LazyUpdate
<sal_Int32
,
98 uno::Sequence
<double>,
99 o3tl::LAZYUPDATE_FUNCTION_TAG
> m_aPenColor
;
100 o3tl::LazyUpdate
<sal_Int32
,
101 uno::Sequence
<double>,
102 o3tl::LAZYUPDATE_FUNCTION_TAG
> m_aFillColor
;
103 o3tl::LazyUpdate
<geometry::RealRectangle2D
,
104 uno::Reference
< rendering::XPolyPolygon2D
>,
105 o3tl::LAZYUPDATE_FUNCTOR_TAG
> m_aRectClip
;
106 geometry::AffineMatrix2D m_aTransformation
;
108 explicit SimpleRenderState( uno::Reference
<rendering::XGraphicDevice
> const& xDevice
) :
109 m_aPenColor( &color2Sequence
),
110 m_aFillColor( &color2Sequence
),
111 m_aRectClip( boost::bind( &rect2Poly
,
116 tools::setIdentityAffineMatrix2D( m_aTransformation
);
121 typedef ::cppu::WeakComponentImplHelper2
< ::com::sun::star::rendering::XSimpleCanvas
,
122 ::com::sun::star::lang::XServiceName
> SimpleCanvasBase
;
124 class SimpleCanvasImpl
: private cppu::BaseMutex
,
125 public SimpleCanvasBase
128 bool isStrokingEnabled() const
130 return maRenderState
.m_aPenColor
.getInValue() && sal_Int32(0xFF) != 0;
133 rendering::RenderState
createStrokingRenderState() const
135 return rendering::RenderState(maRenderState
.m_aTransformation
,
136 *maRenderState
.m_aRectClip
,
137 *maRenderState
.m_aPenColor
,
138 rendering::CompositeOperation::OVER
);
141 bool isFillingEnabled() const
143 return maRenderState
.m_aFillColor
.getInValue() && sal_Int32(0xFF) != 0;
146 rendering::RenderState
createFillingRenderState() const
148 return rendering::RenderState(maRenderState
.m_aTransformation
,
149 *maRenderState
.m_aRectClip
,
150 *maRenderState
.m_aFillColor
,
151 rendering::CompositeOperation::OVER
);
154 static uno::Reference
<rendering::XCanvas
> grabCanvas( uno::Sequence
<uno::Any
> const& rArgs
)
156 uno::Reference
<rendering::XCanvas
> xRet
;
158 // can't do much without an XCanvas, can't we?
159 if( rArgs
.getLength() < 1 )
160 throw lang::IllegalArgumentException();
162 xRet
.set( rArgs
[0], uno::UNO_QUERY
);
164 // can't do much without an XCanvas, can't we?
166 throw lang::IllegalArgumentException();
172 SimpleCanvasImpl( const uno::Sequence
< uno::Any
>& aArguments
,
173 const uno::Reference
< uno::XComponentContext
>& ) :
174 SimpleCanvasBase( m_aMutex
),
175 mxCanvas( grabCanvas(aArguments
) ),
176 maFont(boost::bind( &rendering::XCanvas::createFont
,
177 boost::cref(mxCanvas
),
179 uno::Sequence
< beans::PropertyValue
>(),
180 geometry::Matrix2D() )),
182 maRenderState( mxCanvas
->getDevice() )
184 tools::initViewState(maViewState
);
187 ///////////////////////////////////////////////////////////////////////////////////////////////
191 virtual ::rtl::OUString SAL_CALL
getServiceName( ) throw (uno::RuntimeException
)
193 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME
) );
197 virtual void SAL_CALL
selectFont( const ::rtl::OUString
& sFontName
,
200 ::sal_Bool italic
) throw (uno::RuntimeException
)
202 ::osl::MutexGuard
aGuard( m_aMutex
);
204 maFont
->FontDescription
.FamilyName
= sFontName
;
205 maFont
->CellSize
= size
;
206 maFont
->FontDescription
.FontDescription
.Weight
=
207 bold
? rendering::PanoseWeight::BOLD
: rendering::PanoseWeight::MEDIUM
;
208 maFont
->FontDescription
.FontDescription
.Letterform
=
209 italic
? rendering::PanoseLetterForm::OBLIQUE_CONTACT
: rendering::PanoseLetterForm::ANYTHING
;
212 virtual void SAL_CALL
setPenColor( ::sal_Int32 nsRgbaColor
) throw (uno::RuntimeException
)
214 ::osl::MutexGuard
aGuard( m_aMutex
);
215 *(maRenderState
.m_aPenColor
) = nsRgbaColor
;
218 virtual void SAL_CALL
setFillColor( ::sal_Int32 nsRgbaColor
) throw (uno::RuntimeException
)
220 ::osl::MutexGuard
aGuard( m_aMutex
);
221 *(maRenderState
.m_aFillColor
) = nsRgbaColor
;
224 virtual void SAL_CALL
setRectClip( const geometry::RealRectangle2D
& aRect
) throw (uno::RuntimeException
)
226 ::osl::MutexGuard
aGuard( m_aMutex
);
227 *(maRenderState
.m_aRectClip
) = aRect
;
230 virtual void SAL_CALL
setTransformation( const geometry::AffineMatrix2D
& aTransform
) throw (uno::RuntimeException
)
232 ::osl::MutexGuard
aGuard( m_aMutex
);
233 maRenderState
.m_aTransformation
= aTransform
;
236 virtual void SAL_CALL
drawPixel( const geometry::RealPoint2D
& aPoint
) throw (uno::RuntimeException
)
238 ::osl::MutexGuard
aGuard( m_aMutex
);
239 mxCanvas
->drawPoint(aPoint
,
241 createFillingRenderState());
244 virtual void SAL_CALL
drawLine( const geometry::RealPoint2D
& aStartPoint
,
245 const geometry::RealPoint2D
& aEndPoint
) throw (uno::RuntimeException
)
247 ::osl::MutexGuard
aGuard( m_aMutex
);
248 mxCanvas
->drawLine(aStartPoint
,
251 createStrokingRenderState());
254 virtual void SAL_CALL
drawRect( const geometry::RealRectangle2D
& aRect
) throw (uno::RuntimeException
)
256 ::osl::MutexGuard
aGuard( m_aMutex
);
257 uno::Reference
< rendering::XPolyPolygon2D
> xPoly(
258 rect2Poly( mxCanvas
->getDevice(),
261 if( isFillingEnabled() )
262 mxCanvas
->drawPolyPolygon(xPoly
,
264 createFillingRenderState());
265 if( isStrokingEnabled() )
266 mxCanvas
->drawPolyPolygon(xPoly
,
268 createStrokingRenderState());
271 virtual void SAL_CALL
drawPolyPolygon( const uno::Reference
< rendering::XPolyPolygon2D
>& xPolyPolygon
) throw (uno::RuntimeException
)
273 ::osl::MutexGuard
aGuard( m_aMutex
);
275 if( isFillingEnabled() )
276 mxCanvas
->drawPolyPolygon(xPolyPolygon
,
278 createFillingRenderState());
279 if( isStrokingEnabled() )
280 mxCanvas
->drawPolyPolygon(xPolyPolygon
,
282 createStrokingRenderState());
285 virtual void SAL_CALL
drawText( const rendering::StringContext
& aText
,
286 const geometry::RealPoint2D
& aOutPos
,
287 ::sal_Int8 nTextDirection
) throw (uno::RuntimeException
)
289 ::osl::MutexGuard
aGuard( m_aMutex
);
291 basegfx::B2DHomMatrix offsetTransform
;
292 offsetTransform
.translate(aOutPos
.X
,aOutPos
.Y
);
294 rendering::RenderState
aRenderState( createStrokingRenderState() );
295 tools::appendToRenderState(aRenderState
, offsetTransform
);
297 mxCanvas
->drawText(aText
,
298 maFont
.getOutValue(),
304 virtual void SAL_CALL
drawBitmap( const uno::Reference
< rendering::XBitmap
>& xBitmap
,
305 const geometry::RealPoint2D
& aLeftTop
) throw (uno::RuntimeException
)
307 ::osl::MutexGuard
aGuard( m_aMutex
);
309 basegfx::B2DHomMatrix offsetTransform
;
310 offsetTransform
.translate(aLeftTop
.X
,aLeftTop
.Y
);
312 rendering::RenderState
aRenderState( createStrokingRenderState() );
313 tools::appendToRenderState(aRenderState
, offsetTransform
);
315 mxCanvas
->drawBitmap(xBitmap
,maViewState
,aRenderState
);
318 virtual uno::Reference
< rendering::XGraphicDevice
> SAL_CALL
getDevice( ) throw (uno::RuntimeException
)
320 ::osl::MutexGuard
aGuard( m_aMutex
);
321 return mxCanvas
->getDevice();
324 virtual uno::Reference
< rendering::XCanvas
> SAL_CALL
getCanvas( ) throw (uno::RuntimeException
)
326 ::osl::MutexGuard
aGuard( m_aMutex
);
330 virtual rendering::FontMetrics SAL_CALL
getFontMetrics( ) throw (uno::RuntimeException
)
332 ::osl::MutexGuard
aGuard( m_aMutex
);
333 return maFont
.getOutValue()->getFontMetrics();
336 virtual uno::Reference
< rendering::XCanvasFont
> SAL_CALL
getCurrentFont( ) throw (uno::RuntimeException
)
338 ::osl::MutexGuard
aGuard( m_aMutex
);
339 return maFont
.getOutValue();
342 virtual ::sal_Int32 SAL_CALL
getCurrentPenColor( ) throw (uno::RuntimeException
)
344 ::osl::MutexGuard
aGuard( m_aMutex
);
345 return maRenderState
.m_aPenColor
.getInValue();
348 virtual ::sal_Int32 SAL_CALL
getCurrentFillColor( ) throw (uno::RuntimeException
)
350 ::osl::MutexGuard
aGuard( m_aMutex
);
351 return maRenderState
.m_aFillColor
.getInValue();
354 virtual geometry::RealRectangle2D SAL_CALL
getCurrentClipRect( ) throw (uno::RuntimeException
)
356 ::osl::MutexGuard
aGuard( m_aMutex
);
357 return maRenderState
.m_aRectClip
.getInValue();
360 virtual geometry::AffineMatrix2D SAL_CALL
getCurrentTransformation( ) throw (uno::RuntimeException
)
362 ::osl::MutexGuard
aGuard( m_aMutex
);
363 return maRenderState
.m_aTransformation
;
366 virtual rendering::ViewState SAL_CALL
getCurrentViewState( ) throw (uno::RuntimeException
)
368 ::osl::MutexGuard
aGuard( m_aMutex
);
372 virtual rendering::RenderState SAL_CALL
getCurrentRenderState( sal_Bool bUseFillColor
) throw (uno::RuntimeException
)
374 ::osl::MutexGuard
aGuard( m_aMutex
);
376 return createFillingRenderState();
378 return createStrokingRenderState();
381 ///////////////////////////////////////////////////////////////////////////////////////////////
383 typedef o3tl::LazyUpdate
<
384 rendering::FontRequest
,
385 uno::Reference
< rendering::XCanvasFont
>,
386 o3tl::LAZYUPDATE_FUNCTOR_TAG
> SimpleFont
;
388 uno::Reference
<rendering::XCanvas
> mxCanvas
;
390 rendering::ViewState maViewState
;
391 SimpleRenderState maRenderState
;
394 namespace sdecl
= comphelper::service_decl
;
395 #if defined (__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ <= 3)
396 sdecl::class_
<SimpleCanvasImpl
, sdecl::with_args
<true> > serviceImpl
;
397 const sdecl::ServiceDecl
simpleCanvasDecl(
400 const sdecl::ServiceDecl
simpleCanvasDecl(
401 sdecl::class_
<SimpleCanvasImpl
, sdecl::with_args
<true> >(),
403 "com.sun.star.comp.rendering.SimpleCanvas",
407 // The C shared lib entry points
408 COMPHELPER_SERVICEDECL_EXPORTS1(simpleCanvasDecl
)