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 .
20 #include <sal/config.h>
22 #include <basegfx/matrix/b2dhommatrix.hxx>
23 #include <basegfx/matrix/b2dhommatrixtools.hxx>
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>
31 #include <comphelper/compbase.hxx>
32 #include <o3tl/lazy_update.hxx>
34 #include <canvas/canvastools.hxx>
39 using namespace ::com::sun::star
;
40 using namespace canvas
;
44 uno::Sequence
< double > color2Sequence( sal_Int32 nColor
)
46 // TODO(F3): Color management
47 uno::Sequence
< double > aRes
{
48 static_cast<sal_uInt8
>( (nColor
&0xFF000000U
) >> 24U ) / 255.0,
49 static_cast<sal_uInt8
>( (nColor
&0x00FF0000U
) >> 16U ) / 255.0,
50 static_cast<sal_uInt8
>( (nColor
&0x0000FF00U
) >> 8U ) / 255.0,
51 static_cast<sal_uInt8
>( (nColor
&0x000000FFU
) ) / 255.0
56 uno::Reference
< rendering::XPolyPolygon2D
> rect2Poly( uno::Reference
<rendering::XGraphicDevice
> const& xDevice
,
57 geometry::RealRectangle2D
const& rRect
)
59 uno::Sequence
< geometry::RealPoint2D
> rectSequence
{
60 geometry::RealPoint2D( rRect
.X1
, rRect
.Y1
),
61 geometry::RealPoint2D( rRect
.X2
, rRect
.Y1
),
62 geometry::RealPoint2D( rRect
.X2
, rRect
.Y2
),
63 geometry::RealPoint2D( rRect
.X1
, rRect
.Y2
)
65 uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> > sequenceSequence
{ rectSequence
};
66 uno::Reference
< rendering::XPolyPolygon2D
> xRes
=
67 xDevice
->createCompatibleLinePolyPolygon( sequenceSequence
);
69 xRes
->setClosed( 0, true );
73 struct SimpleRenderState
75 o3tl::LazyUpdate
<sal_Int32
,
76 uno::Sequence
<double>,
77 decltype(&color2Sequence
)> m_aPenColor
;
78 o3tl::LazyUpdate
<sal_Int32
,
79 uno::Sequence
<double>,
80 decltype(&color2Sequence
)> m_aFillColor
;
81 o3tl::LazyUpdate
<geometry::RealRectangle2D
,
82 uno::Reference
< rendering::XPolyPolygon2D
>,
83 std::function
<uno::Reference
<rendering::XPolyPolygon2D
> (geometry::RealRectangle2D
)> > m_aRectClip
;
84 geometry::AffineMatrix2D m_aTransformation
;
86 explicit SimpleRenderState( uno::Reference
<rendering::XGraphicDevice
> const& xDevice
) :
87 m_aPenColor( &color2Sequence
),
88 m_aFillColor( &color2Sequence
),
89 m_aRectClip( [&xDevice
](geometry::RealRectangle2D
const& rRect
) { return rect2Poly(xDevice
, rRect
); } )
91 tools::setIdentityAffineMatrix2D( m_aTransformation
);
96 typedef ::comphelper::WeakComponentImplHelper
< css::rendering::XSimpleCanvas
,
97 css::lang::XServiceName
> SimpleCanvasBase
;
99 class SimpleCanvasImpl
: public SimpleCanvasBase
102 bool isStrokingEnabled() const
104 return maRenderState
.m_aPenColor
.getInValue() % 0x100 != 0;
107 rendering::RenderState
createStrokingRenderState() const
109 return rendering::RenderState(maRenderState
.m_aTransformation
,
110 *maRenderState
.m_aRectClip
,
111 *maRenderState
.m_aPenColor
,
112 rendering::CompositeOperation::OVER
);
115 bool isFillingEnabled() const
117 return maRenderState
.m_aFillColor
.getInValue() % 0x100 != 0;
120 rendering::RenderState
createFillingRenderState() const
122 return rendering::RenderState(maRenderState
.m_aTransformation
,
123 *maRenderState
.m_aRectClip
,
124 *maRenderState
.m_aFillColor
,
125 rendering::CompositeOperation::OVER
);
128 static uno::Reference
<rendering::XCanvas
> grabCanvas( uno::Sequence
<uno::Any
> const& rArgs
)
130 uno::Reference
<rendering::XCanvas
> xRet
;
132 // can't do much without an XCanvas, can't we?
133 if( !rArgs
.hasElements() )
134 throw lang::IllegalArgumentException();
136 xRet
.set( rArgs
[0], uno::UNO_QUERY
);
138 // can't do much without an XCanvas, can't we?
140 throw lang::IllegalArgumentException();
146 SimpleCanvasImpl( const uno::Sequence
< uno::Any
>& aArguments
,
147 const uno::Reference
< uno::XComponentContext
>& ) :
148 mxCanvas( grabCanvas(aArguments
) ),
149 maFont([this](rendering::FontRequest
const& rFontRequest
) {
150 return mxCanvas
->createFont(rFontRequest
,
151 uno::Sequence
< beans::PropertyValue
>(),
152 geometry::Matrix2D()); } ),
153 maRenderState( mxCanvas
->getDevice() )
155 tools::initViewState(maViewState
);
161 virtual OUString SAL_CALL
getServiceName( ) override
163 return "com.sun.star.rendering.SimpleCanvas";
167 virtual void SAL_CALL
selectFont( const OUString
& sFontName
,
170 sal_Bool italic
) override
172 std::unique_lock
aGuard( m_aMutex
);
174 maFont
->FontDescription
.FamilyName
= sFontName
;
175 maFont
->CellSize
= size
;
176 maFont
->FontDescription
.FontDescription
.Weight
=
177 bold
? rendering::PanoseWeight::BOLD
: rendering::PanoseWeight::MEDIUM
;
178 maFont
->FontDescription
.FontDescription
.Letterform
=
179 italic
? rendering::PanoseLetterForm::OBLIQUE_CONTACT
: rendering::PanoseLetterForm::ANYTHING
;
182 virtual void SAL_CALL
setPenColor( ::sal_Int32 nsRgbaColor
) override
184 std::unique_lock
aGuard( m_aMutex
);
185 *(maRenderState
.m_aPenColor
) = nsRgbaColor
;
188 virtual void SAL_CALL
setFillColor( ::sal_Int32 nsRgbaColor
) override
190 std::unique_lock
aGuard( m_aMutex
);
191 *(maRenderState
.m_aFillColor
) = nsRgbaColor
;
194 virtual void SAL_CALL
setRectClip( const geometry::RealRectangle2D
& aRect
) override
196 std::unique_lock
aGuard( m_aMutex
);
197 *(maRenderState
.m_aRectClip
) = aRect
;
200 virtual void SAL_CALL
setTransformation( const geometry::AffineMatrix2D
& aTransform
) override
202 std::unique_lock
aGuard( m_aMutex
);
203 maRenderState
.m_aTransformation
= aTransform
;
206 virtual void SAL_CALL
drawPixel( const geometry::RealPoint2D
& aPoint
) override
208 std::unique_lock
aGuard( m_aMutex
);
209 mxCanvas
->drawPoint(aPoint
,
211 createFillingRenderState());
214 virtual void SAL_CALL
drawLine( const geometry::RealPoint2D
& aStartPoint
,
215 const geometry::RealPoint2D
& aEndPoint
) override
217 std::unique_lock
aGuard( m_aMutex
);
218 mxCanvas
->drawLine(aStartPoint
,
221 createStrokingRenderState());
224 virtual void SAL_CALL
drawRect( const geometry::RealRectangle2D
& aRect
) override
226 std::unique_lock
aGuard( m_aMutex
);
227 uno::Reference
< rendering::XPolyPolygon2D
> xPoly(
228 rect2Poly( mxCanvas
->getDevice(),
231 if( isFillingEnabled() )
232 mxCanvas
->drawPolyPolygon(xPoly
,
234 createFillingRenderState());
235 if( isStrokingEnabled() )
236 mxCanvas
->drawPolyPolygon(xPoly
,
238 createStrokingRenderState());
241 virtual void SAL_CALL
drawPolyPolygon( const uno::Reference
< rendering::XPolyPolygon2D
>& xPolyPolygon
) override
243 std::unique_lock
aGuard( m_aMutex
);
245 if( isFillingEnabled() )
246 mxCanvas
->drawPolyPolygon(xPolyPolygon
,
248 createFillingRenderState());
249 if( isStrokingEnabled() )
250 mxCanvas
->drawPolyPolygon(xPolyPolygon
,
252 createStrokingRenderState());
255 virtual void SAL_CALL
drawText( const rendering::StringContext
& aText
,
256 const geometry::RealPoint2D
& aOutPos
,
257 ::sal_Int8 nTextDirection
) override
259 std::unique_lock
aGuard( m_aMutex
);
260 const basegfx::B2DHomMatrix
offsetTransform(basegfx::utils::createTranslateB2DHomMatrix(aOutPos
.X
,aOutPos
.Y
));
261 rendering::RenderState
aRenderState( createStrokingRenderState() );
262 tools::appendToRenderState(aRenderState
, offsetTransform
);
264 mxCanvas
->drawText(aText
,
265 maFont
.getOutValue(),
271 virtual void SAL_CALL
drawBitmap( const uno::Reference
< rendering::XBitmap
>& xBitmap
,
272 const geometry::RealPoint2D
& aLeftTop
) override
274 std::unique_lock
aGuard( m_aMutex
);
275 const basegfx::B2DHomMatrix
offsetTransform(basegfx::utils::createTranslateB2DHomMatrix(aLeftTop
.X
,aLeftTop
.Y
));
276 rendering::RenderState
aRenderState( createStrokingRenderState() );
277 tools::appendToRenderState(aRenderState
, offsetTransform
);
279 mxCanvas
->drawBitmap(xBitmap
,maViewState
,aRenderState
);
282 virtual uno::Reference
< rendering::XGraphicDevice
> SAL_CALL
getDevice( ) override
284 std::unique_lock
aGuard( m_aMutex
);
285 return mxCanvas
->getDevice();
288 virtual uno::Reference
< rendering::XCanvas
> SAL_CALL
getCanvas( ) override
290 std::unique_lock
aGuard( m_aMutex
);
294 virtual rendering::FontMetrics SAL_CALL
getFontMetrics( ) override
296 std::unique_lock
aGuard( m_aMutex
);
297 return maFont
.getOutValue()->getFontMetrics();
300 virtual uno::Reference
< rendering::XCanvasFont
> SAL_CALL
getCurrentFont( ) override
302 std::unique_lock
aGuard( m_aMutex
);
303 return maFont
.getOutValue();
306 virtual ::sal_Int32 SAL_CALL
getCurrentPenColor( ) override
308 std::unique_lock
aGuard( m_aMutex
);
309 return maRenderState
.m_aPenColor
.getInValue();
312 virtual ::sal_Int32 SAL_CALL
getCurrentFillColor( ) override
314 std::unique_lock
aGuard( m_aMutex
);
315 return maRenderState
.m_aFillColor
.getInValue();
318 virtual geometry::RealRectangle2D SAL_CALL
getCurrentClipRect( ) override
320 std::unique_lock
aGuard( m_aMutex
);
321 return maRenderState
.m_aRectClip
.getInValue();
324 virtual geometry::AffineMatrix2D SAL_CALL
getCurrentTransformation( ) override
326 std::unique_lock
aGuard( m_aMutex
);
327 return maRenderState
.m_aTransformation
;
330 virtual rendering::ViewState SAL_CALL
getCurrentViewState( ) override
332 std::unique_lock
aGuard( m_aMutex
);
336 virtual rendering::RenderState SAL_CALL
getCurrentRenderState( sal_Bool bUseFillColor
) override
338 std::unique_lock
aGuard( m_aMutex
);
340 return createFillingRenderState();
342 return createStrokingRenderState();
346 typedef o3tl::LazyUpdate
<
347 rendering::FontRequest
,
348 uno::Reference
< rendering::XCanvasFont
>,
349 std::function
<uno::Reference
<rendering::XCanvasFont
> (rendering::FontRequest
)> > SimpleFont
;
351 uno::Reference
<rendering::XCanvas
> mxCanvas
;
353 rendering::ViewState maViewState
;
354 SimpleRenderState maRenderState
;
359 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
360 com_sun_star_comp_rendering_SimpleCanvas(
361 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& args
)
363 return cppu::acquire(new SimpleCanvasImpl(args
, context
));
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */