tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / cppcanvas / source / mtfrenderer / polypolyaction.cxx
blob955727a313099d17b97990a21f270bf2795aa36f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/XCanvas.hpp>
23 #include <sal/types.h>
25 #include <basegfx/range/b2drectangle.hxx>
26 #include <basegfx/utils/canvastools.hxx>
27 #include <basegfx/polygon/b2dpolypolygon.hxx>
28 #include <basegfx/polygon/b2dpolypolygontools.hxx>
29 #include <basegfx/matrix/b2dhommatrix.hxx>
30 #include <canvas/canvastools.hxx>
31 #include <osl/diagnose.h>
32 #include <sal/log.hxx>
34 #include "cachedprimitivebase.hxx"
35 #include "polypolyaction.hxx"
36 #include <outdevstate.hxx>
37 #include <utility>
38 #include "mtftools.hxx"
41 using namespace ::com::sun::star;
43 namespace cppcanvas::internal
45 namespace
47 class PolyPolyAction : public CachedPrimitiveBase
49 public:
50 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
51 const CanvasSharedPtr&,
52 const OutDevState&,
53 bool bFill,
54 bool bStroke );
55 PolyPolyAction( const ::basegfx::B2DPolyPolygon&,
56 const CanvasSharedPtr&,
57 const OutDevState&,
58 bool bFill,
59 bool bStroke,
60 int nTransparency );
62 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
63 const Subset& rSubset ) const override;
65 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
66 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
67 const Subset& rSubset ) const override;
69 virtual sal_Int32 getActionCount() const override;
71 private:
72 using Action::render;
73 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
74 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
76 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
77 const ::basegfx::B2DRange maBounds;
78 const CanvasSharedPtr mpCanvas;
80 // stroke color is now implicit: the maState.DeviceColor member
81 rendering::RenderState maState;
83 uno::Sequence< double > maFillColor;
86 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
87 const CanvasSharedPtr& rCanvas,
88 const OutDevState& rState,
89 bool bFill,
90 bool bStroke ) :
91 CachedPrimitiveBase( rCanvas, false ),
92 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
93 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
94 mpCanvas( rCanvas )
96 tools::initRenderState(maState,rState);
98 if( bFill )
99 maFillColor = rState.fillColor;
101 if( bStroke )
102 maState.DeviceColor = rState.lineColor;
105 PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
106 const CanvasSharedPtr& rCanvas,
107 const OutDevState& rState,
108 bool bFill,
109 bool bStroke,
110 int nTransparency ) :
111 CachedPrimitiveBase( rCanvas, false ),
112 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
113 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
114 mpCanvas( rCanvas )
116 tools::initRenderState(maState,rState);
118 if( bFill )
120 maFillColor = rState.fillColor;
122 if( maFillColor.getLength() < 4 )
123 maFillColor.realloc( 4 );
125 // TODO(F1): Color management
126 // adapt fill color transparency
127 maFillColor.getArray()[3] = 1.0 - nTransparency / 100.0;
130 if( bStroke )
132 maState.DeviceColor = rState.lineColor;
134 if( maState.DeviceColor.getLength() < 4 )
135 maState.DeviceColor.realloc( 4 );
137 // TODO(F1): Color management
138 // adapt fill color transparency
139 maState.DeviceColor.getArray()[3] = 1.0 - nTransparency / 100.0;
143 bool PolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
144 const ::basegfx::B2DHomMatrix& rTransformation ) const
146 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
147 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
149 rendering::RenderState aLocalState( maState );
150 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
152 if( maFillColor.hasElements() )
154 // TODO(E3): Use DBO's finalizer here,
155 // fillPolyPolygon() might throw
156 const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor );
157 aLocalState.DeviceColor = maFillColor;
159 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly,
160 mpCanvas->getViewState(),
161 aLocalState );
163 aLocalState.DeviceColor = aTmpColor;
166 if( aLocalState.DeviceColor.hasElements() )
168 rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly,
169 mpCanvas->getViewState(),
170 aLocalState );
173 return true;
176 bool PolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
177 const Subset& rSubset ) const
179 // TODO(F1): Split up poly-polygon into polygons, or even
180 // line segments, when subsets are requested.
182 // polygon only contains a single action, fail if subset
183 // requests different range
184 if( rSubset.mnSubsetBegin != 0 ||
185 rSubset.mnSubsetEnd != 1 )
186 return false;
188 return CachedPrimitiveBase::render( rTransformation );
191 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
193 rendering::RenderState aLocalState( maState );
194 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
196 return tools::calcDevicePixelBounds(
197 maBounds,
198 mpCanvas->getViewState(),
199 aLocalState );
202 ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
203 const Subset& rSubset ) const
205 // TODO(F1): Split up poly-polygon into polygons, or even
206 // line segments, when subsets are requested.
208 // polygon only contains a single action, empty bounds
209 // if subset requests different range
210 if( rSubset.mnSubsetBegin != 0 ||
211 rSubset.mnSubsetEnd != 1 )
212 return ::basegfx::B2DRange();
214 return getBounds( rTransformation );
217 sal_Int32 PolyPolyAction::getActionCount() const
219 // TODO(F1): Split up poly-polygon into polygons, or even
220 // line segments, when subsets are requested.
221 return 1;
225 class TexturedPolyPolyAction : public CachedPrimitiveBase
227 public:
228 TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
229 const CanvasSharedPtr& rCanvas,
230 const OutDevState& rState,
231 const rendering::Texture& rTexture );
233 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
234 const Subset& rSubset ) const override;
236 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
237 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
238 const Subset& rSubset ) const override;
240 virtual sal_Int32 getActionCount() const override;
242 private:
243 using Action::render;
244 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
245 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
247 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
248 const ::basegfx::B2DRectangle maBounds;
249 const CanvasSharedPtr mpCanvas;
251 // stroke color is now implicit: the maState.DeviceColor member
252 rendering::RenderState maState;
253 const rendering::Texture maTexture;
256 TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
257 const CanvasSharedPtr& rCanvas,
258 const OutDevState& rState,
259 const rendering::Texture& rTexture ) :
260 CachedPrimitiveBase( rCanvas, true ),
261 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
262 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
263 mpCanvas( rCanvas ),
264 maTexture( rTexture )
266 tools::initRenderState(maState,rState);
269 bool TexturedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
270 const ::basegfx::B2DHomMatrix& rTransformation ) const
272 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
273 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
275 rendering::RenderState aLocalState( maState );
276 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
278 uno::Sequence< rendering::Texture > aSeq { maTexture };
280 rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly,
281 mpCanvas->getViewState(),
282 aLocalState,
283 aSeq );
284 return true;
287 bool TexturedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
288 const Subset& rSubset ) const
290 // TODO(F1): Split up poly-polygon into polygons, or even
291 // line segments, when subsets are requested.
293 // polygon only contains a single action, fail if subset
294 // requests different range
295 if( rSubset.mnSubsetBegin != 0 ||
296 rSubset.mnSubsetEnd != 1 )
297 return false;
299 return CachedPrimitiveBase::render( rTransformation );
302 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
304 rendering::RenderState aLocalState( maState );
305 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
307 return tools::calcDevicePixelBounds(
308 maBounds,
309 mpCanvas->getViewState(),
310 aLocalState );
313 ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
314 const Subset& rSubset ) const
316 // TODO(F1): Split up poly-polygon into polygons, or even
317 // line segments, when subsets are requested.
319 // polygon only contains a single action, empty bounds
320 // if subset requests different range
321 if( rSubset.mnSubsetBegin != 0 ||
322 rSubset.mnSubsetEnd != 1 )
323 return ::basegfx::B2DRange();
325 return getBounds( rTransformation );
328 sal_Int32 TexturedPolyPolyAction::getActionCount() const
330 // TODO(F1): Split up poly-polygon into polygons, or even
331 // line segments, when subsets are requested.
332 return 1;
336 class StrokedPolyPolyAction : public CachedPrimitiveBase
338 public:
339 StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
340 const CanvasSharedPtr& rCanvas,
341 const OutDevState& rState,
342 rendering::StrokeAttributes aStrokeAttributes );
344 virtual bool renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
345 const Subset& rSubset ) const override;
347 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const override;
348 virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
349 const Subset& rSubset ) const override;
351 virtual sal_Int32 getActionCount() const override;
353 private:
354 using Action::render;
355 virtual bool renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
356 const ::basegfx::B2DHomMatrix& rTransformation ) const override;
358 const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly;
359 const ::basegfx::B2DRectangle maBounds;
360 const CanvasSharedPtr mpCanvas;
361 rendering::RenderState maState;
362 const rendering::StrokeAttributes maStrokeAttributes;
365 StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly,
366 const CanvasSharedPtr& rCanvas,
367 const OutDevState& rState,
368 rendering::StrokeAttributes aStrokeAttributes ) :
369 CachedPrimitiveBase( rCanvas, false ),
370 mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ),
371 maBounds( ::basegfx::utils::getRange(rPolyPoly) ),
372 mpCanvas( rCanvas ),
373 maStrokeAttributes(std::move( aStrokeAttributes ))
375 tools::initRenderState(maState,rState);
376 maState.DeviceColor = rState.lineColor;
379 bool StrokedPolyPolyAction::renderPrimitive( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive,
380 const ::basegfx::B2DHomMatrix& rTransformation ) const
382 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction::renderPrimitive()" );
383 SAL_INFO( "cppcanvas.emf", "::cppcanvas::internal::PolyPolyAction: 0x" << std::hex << this );
385 rendering::RenderState aLocalState( maState );
386 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
388 rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly,
389 mpCanvas->getViewState(),
390 aLocalState,
391 maStrokeAttributes );
392 return true;
395 bool StrokedPolyPolyAction::renderSubset( const ::basegfx::B2DHomMatrix& rTransformation,
396 const Subset& rSubset ) const
398 // TODO(F1): Split up poly-polygon into polygons, or even
399 // line segments, when subsets are requested.
401 // polygon only contains a single action, fail if subset
402 // requests different range
403 if( rSubset.mnSubsetBegin != 0 ||
404 rSubset.mnSubsetEnd != 1 )
405 return false;
407 return CachedPrimitiveBase::render( rTransformation );
410 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const
412 rendering::RenderState aLocalState( maState );
413 ::canvas::tools::prependToRenderState(aLocalState, rTransformation);
415 return tools::calcDevicePixelBounds(
416 maBounds,
417 mpCanvas->getViewState(),
418 aLocalState );
421 ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation,
422 const Subset& rSubset ) const
424 // TODO(F1): Split up poly-polygon into polygons, or even
425 // line segments, when subsets are requested.
427 // polygon only contains a single action, empty bounds
428 // if subset requests different range
429 if( rSubset.mnSubsetBegin != 0 ||
430 rSubset.mnSubsetEnd != 1 )
431 return ::basegfx::B2DRange();
433 return getBounds( rTransformation );
436 sal_Int32 StrokedPolyPolyAction::getActionCount() const
438 // TODO(F1): Split up poly-polygon into polygons, or even
439 // line segments, when subsets are requested.
440 return 1;
444 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
445 const CanvasSharedPtr& rCanvas,
446 const OutDevState& rState )
448 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
449 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
450 return std::make_shared<PolyPolyAction>( rPoly, rCanvas, rState,
451 rState.isFillColorSet,
452 rState.isLineColorSet );
455 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
456 const CanvasSharedPtr& rCanvas,
457 const OutDevState& rState,
458 const rendering::Texture& rTexture )
460 return std::make_shared<TexturedPolyPolyAction>( rPoly, rCanvas, rState, rTexture );
463 std::shared_ptr<Action> PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
464 const CanvasSharedPtr& rCanvas,
465 const OutDevState& rState )
467 OSL_ENSURE( rState.isLineColorSet,
468 "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" );
470 return std::make_shared<PolyPolyAction>( rPoly, rCanvas, rState,
471 false,
472 rState.isLineColorSet );
475 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
476 const CanvasSharedPtr& rCanvas,
477 const OutDevState& rState,
478 const rendering::StrokeAttributes& rStrokeAttributes )
480 OSL_ENSURE( rState.isLineColorSet,
481 "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" );
482 return std::make_shared<StrokedPolyPolyAction>( rPoly, rCanvas, rState, rStrokeAttributes );
485 std::shared_ptr<Action> PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly,
486 const CanvasSharedPtr& rCanvas,
487 const OutDevState& rState,
488 int nTransparency )
490 OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet,
491 "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" );
492 return std::make_shared<PolyPolyAction>( rPoly, rCanvas, rState,
493 rState.isFillColorSet,
494 rState.isLineColorSet,
495 nTransparency );
500 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */