LibreOffice Module slideshow (master) 1
tools.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
23
24#include <math.h>
25
26#include <com/sun/star/beans/NamedValue.hpp>
27#include <com/sun/star/awt/Rectangle.hpp>
28#include <com/sun/star/animations/ValuePair.hpp>
29#include <com/sun/star/drawing/FillStyle.hpp>
30#include <com/sun/star/drawing/LineStyle.hpp>
31#include <com/sun/star/awt/FontSlant.hpp>
32
42
44
45#include <svtools/colorcfg.hxx>
46
47#include <unoview.hxx>
50#include <tools.hxx>
51
52#include <limits>
53
54
55using namespace ::com::sun::star;
56
57namespace slideshow::internal
58{
59 namespace
60 {
61 class NamedValueComparator
62 {
63 public:
64 explicit NamedValueComparator( const beans::NamedValue& rKey ) :
65 mrKey( rKey )
66 {
67 }
68
69 bool operator()( const beans::NamedValue& rValue ) const
70 {
71 return rValue.Name == mrKey.Name && rValue.Value == mrKey.Value;
72 }
73
74 private:
75 const beans::NamedValue& mrKey;
76 };
77
78 ::basegfx::B2DHomMatrix getAttributedShapeTransformation( const ::basegfx::B2DRectangle& rShapeBounds,
79 const ShapeAttributeLayerSharedPtr& pAttr )
80 {
81 ::basegfx::B2DHomMatrix aTransform;
82 const basegfx::B2DSize rSize(rShapeBounds.getRange().getX(), rShapeBounds.getRange().getY());
83
84 const double nShearX( pAttr->isShearXAngleValid() ?
85 pAttr->getShearXAngle() :
86 0.0 );
87 const double nShearY( pAttr->isShearYAngleValid() ?
88 pAttr->getShearYAngle() :
89 0.0 );
90 const double nRotation( pAttr->isRotationAngleValid() ?
91 basegfx::deg2rad(pAttr->getRotationAngle()) :
92 0.0 );
93
94 // scale, shear and rotation pivot point is the shape
95 // center - adapt origin accordingly
96 aTransform.translate( -0.5, -0.5 );
97
98 // ensure valid size (zero size will inevitably lead
99 // to a singular transformation matrix)
100 aTransform.scale( ::basegfx::pruneScaleValue(
101 rSize.getWidth() ),
102 ::basegfx::pruneScaleValue(
103 rSize.getHeight() ) );
104
105 const bool bNeedShearX( !::basegfx::fTools::equalZero(nShearX) );
106 const bool bNeedShearY( !::basegfx::fTools::equalZero(nShearY) );
107 const bool bNeedRotation( !::basegfx::fTools::equalZero(nRotation) );
108
109 if( bNeedRotation || bNeedShearX || bNeedShearY )
110 {
111 if( bNeedShearX )
112 aTransform.shearX( nShearX );
113
114 if( bNeedShearY )
115 aTransform.shearY( nShearY );
116
117 if( bNeedRotation )
118 aTransform.rotate( nRotation );
119 }
120
121 // move left, top corner back to position of the
122 // shape. Since we've already translated the
123 // center of the shape to the origin (the
124 // translate( -0.5, -0.5 ) above), translate to
125 // center of final shape position here.
126 aTransform.translate( rShapeBounds.getCenterX(),
127 rShapeBounds.getCenterY() );
128
129 return aTransform;
130 }
131 }
132
133 // Value extraction from Any
134 // =========================
135
137 bool extractValue( double& o_rValue,
138 const uno::Any& rSourceAny,
139 const ShapeSharedPtr& rShape,
140 const ::basegfx::B2DVector& rSlideBounds )
141 {
142 // try to extract numeric value (double, or smaller POD, like float or int)
143 if( rSourceAny >>= o_rValue)
144 {
145 // succeeded
146 return true;
147 }
148
149 // try to extract string
150 OUString aString;
151 if( !(rSourceAny >>= aString) )
152 return false; // nothing left to try
153
154 // parse the string into an ExpressionNode
155 try
156 {
157 // Parse string into ExpressionNode, eval node at time 0.0
159 aString,
160 calcRelativeShapeBounds(rSlideBounds,
161 rShape->getBounds()) ))(0.0);
162 }
163 catch( ParseError& )
164 {
165 return false;
166 }
167
168 return true;
169 }
170
172 bool extractValue( sal_Int32& o_rValue,
173 const uno::Any& rSourceAny,
174 const ShapeSharedPtr& /*rShape*/,
175 const ::basegfx::B2DVector& /*rSlideBounds*/ )
176 {
177 // try to extract numeric value (int, or smaller POD, like byte)
178 if( rSourceAny >>= o_rValue)
179 {
180 // succeeded
181 return true;
182 }
183
184 // okay, no plain int. Maybe one of the domain-specific enums?
185 drawing::FillStyle eFillStyle;
186 if( rSourceAny >>= eFillStyle )
187 {
188 o_rValue = sal::static_int_cast<sal_Int16>(eFillStyle);
189
190 // succeeded
191 return true;
192 }
193
194 drawing::LineStyle eLineStyle;
195 if( rSourceAny >>= eLineStyle )
196 {
197 o_rValue = sal::static_int_cast<sal_Int16>(eLineStyle);
198
199 // succeeded
200 return true;
201 }
202
203 awt::FontSlant eFontSlant;
204 if( rSourceAny >>= eFontSlant )
205 {
206 o_rValue = sal::static_int_cast<sal_Int16>(eFontSlant);
207
208 // succeeded
209 return true;
210 }
211
212 // nothing left to try. Failure
213 return false;
214 }
215
217 bool extractValue( sal_Int16& o_rValue,
218 const uno::Any& rSourceAny,
219 const ShapeSharedPtr& rShape,
220 const ::basegfx::B2DVector& rSlideBounds )
221 {
222 sal_Int32 aValue;
223 if( !extractValue(aValue,rSourceAny,rShape,rSlideBounds) )
224 return false;
225
226 if( std::numeric_limits<sal_Int16>::max() < aValue ||
227 std::numeric_limits<sal_Int16>::min() > aValue )
228 {
229 return false;
230 }
231
232 o_rValue = static_cast<sal_Int16>(aValue);
233
234 return true;
235 }
236
238 bool extractValue( RGBColor& o_rValue,
239 const uno::Any& rSourceAny,
240 const ShapeSharedPtr& /*rShape*/,
241 const ::basegfx::B2DVector& /*rSlideBounds*/ )
242 {
243 // try to extract numeric value (double, or smaller POD, like float or int)
244 {
245 double nTmp = 0;
246 if( rSourceAny >>= nTmp )
247 {
248 sal_uInt32 aIntColor( static_cast< sal_uInt32 >(nTmp) );
249
250 // TODO(F2): Handle color values correctly, here
251 o_rValue = unoColor2RGBColor( aIntColor );
252
253 // succeeded
254 return true;
255 }
256 }
257
258 // try double sequence
259 {
261 if( rSourceAny >>= aTmp )
262 {
263 ENSURE_OR_THROW( aTmp.getLength() == 3,
264 "extractValue(): inappropriate length for RGB color value" );
265
266 o_rValue = RGBColor( aTmp[0], aTmp[1], aTmp[2] );
267
268 // succeeded
269 return true;
270 }
271 }
272
273 // try sal_Int32 sequence
274 {
276 if( rSourceAny >>= aTmp )
277 {
278 ENSURE_OR_THROW( aTmp.getLength() == 3,
279 "extractValue(): inappropriate length for RGB color value" );
280
281 // truncate to byte
282 o_rValue = RGBColor( ::cppcanvas::makeColor(
283 static_cast<sal_uInt8>(aTmp[0]),
284 static_cast<sal_uInt8>(aTmp[1]),
285 static_cast<sal_uInt8>(aTmp[2]),
286 255 ) );
287
288 // succeeded
289 return true;
290 }
291 }
292
293 // try sal_Int8 sequence
294 {
296 if( rSourceAny >>= aTmp )
297 {
298 ENSURE_OR_THROW( aTmp.getLength() == 3,
299 "extractValue(): inappropriate length for RGB color value" );
300
301 o_rValue = RGBColor( ::cppcanvas::makeColor( aTmp[0], aTmp[1], aTmp[2], 255 ) );
302
303 // succeeded
304 return true;
305 }
306 }
307
308 // try to extract string
309 OUString aString;
310 if( !(rSourceAny >>= aString) )
311 return false; // nothing left to try
312
313 // TODO(F2): Provide symbolic color values here
314 o_rValue = RGBColor( 0.5, 0.5, 0.5 );
315
316 return true;
317 }
318
320 bool extractValue( HSLColor& o_rValue,
321 const uno::Any& rSourceAny,
322 const ShapeSharedPtr& /*rShape*/,
323 const ::basegfx::B2DVector& /*rSlideBounds*/ )
324 {
325 // try double sequence
326 {
328 if( rSourceAny >>= aTmp )
329 {
330 ENSURE_OR_THROW( aTmp.getLength() == 3,
331 "extractValue(): inappropriate length for HSL color value" );
332
333 o_rValue = HSLColor( aTmp[0], aTmp[1], aTmp[2] );
334
335 // succeeded
336 return true;
337 }
338 }
339
340 // try sal_Int8 sequence
341 {
343 if( rSourceAny >>= aTmp )
344 {
345 ENSURE_OR_THROW( aTmp.getLength() == 3,
346 "extractValue(): inappropriate length for HSL color value" );
347
348 o_rValue = HSLColor( aTmp[0]*360.0/255.0, aTmp[1]/255.0, aTmp[2]/255.0 );
349
350 // succeeded
351 return true;
352 }
353 }
354
355 return false; // nothing left to try
356 }
357
359 bool extractValue( OUString& o_rValue,
360 const uno::Any& rSourceAny,
361 const ShapeSharedPtr& /*rShape*/,
362 const ::basegfx::B2DVector& /*rSlideBounds*/ )
363 {
364 // try to extract string
365 return rSourceAny >>= o_rValue;
366 }
367
369 bool extractValue( bool& o_rValue,
370 const uno::Any& rSourceAny,
371 const ShapeSharedPtr& /*rShape*/,
372 const ::basegfx::B2DVector& /*rSlideBounds*/ )
373 {
374 bool bTmp;
375 // try to extract bool value
376 if( rSourceAny >>= bTmp )
377 {
378 o_rValue = bTmp;
379
380 // succeeded
381 return true;
382 }
383
384 // try to extract string
385 OUString aString;
386 if( !(rSourceAny >>= aString) )
387 return false; // nothing left to try
388
389 // we also take the strings "true" and "false",
390 // as well as "on" and "off" here
391 if( aString.equalsIgnoreAsciiCase("true") ||
392 aString.equalsIgnoreAsciiCase("on") )
393 {
394 o_rValue = true;
395 return true;
396 }
397 if( aString.equalsIgnoreAsciiCase("false") ||
398 aString.equalsIgnoreAsciiCase("off") )
399 {
400 o_rValue = false;
401 return true;
402 }
403
404 // ultimately failed.
405 return false;
406 }
407
410 const uno::Any& rSourceAny,
411 const ShapeSharedPtr& rShape,
412 const ::basegfx::B2DVector& rSlideBounds )
413 {
414 animations::ValuePair aPair;
415
416 if( !(rSourceAny >>= aPair) )
417 return false;
418
419 double nFirst;
420 if( !extractValue( nFirst, aPair.First, rShape, rSlideBounds ) )
421 return false;
422
423 double nSecond;
424 if( !extractValue( nSecond, aPair.Second, rShape, rSlideBounds ) )
425 return false;
426
427 o_rPair.setX( nFirst );
428 o_rPair.setY( nSecond );
429
430 return true;
431 }
432
434 const beans::NamedValue& rSearchKey )
435 {
436 return ::std::any_of( rSequence.begin(), rSequence.end(),
437 NamedValueComparator( rSearchKey ) );
438 }
439
441 const basegfx::B2DRange& rShapeBounds )
442 {
443 return basegfx::B2DRange( rShapeBounds.getMinX() / rPageSize.getX(),
444 rShapeBounds.getMinY() / rPageSize.getY(),
445 rShapeBounds.getMaxX() / rPageSize.getX(),
446 rShapeBounds.getMaxY() / rPageSize.getY() );
447 }
448
449 // TODO(F2): Currently, the positional attributes DO NOT mirror the XShape properties.
450 // First and foremost, this is because we must operate with the shape boundrect,
451 // not position and size (the conversion between logic rect, snap rect and boundrect
452 // are non-trivial for draw shapes, and I won't duplicate them here). Thus, shapes
453 // rotated on the page will still have 0.0 rotation angle, as the metafile
454 // representation fetched over the API is our default zero case.
455
456 ::basegfx::B2DHomMatrix getShapeTransformation( const ::basegfx::B2DRectangle& rShapeBounds,
457 const ShapeAttributeLayerSharedPtr& pAttr )
458 {
459 if( !pAttr )
460 {
462 rShapeBounds.getWidth(), rShapeBounds.getHeight(),
463 rShapeBounds.getMinX(), rShapeBounds.getMinY()));
464
465 return aTransform;
466 }
467 else
468 {
469 return getAttributedShapeTransformation( rShapeBounds,
470 pAttr );
471 }
472 }
473
474 ::basegfx::B2DHomMatrix getSpriteTransformation( const ::basegfx::B2DVector& rPixelSize,
475 const ::basegfx::B2DVector& rOrigSize,
476 const ShapeAttributeLayerSharedPtr& pAttr )
477 {
478 ::basegfx::B2DHomMatrix aTransform;
479
480 if( pAttr )
481 {
482 const double nShearX( pAttr->isShearXAngleValid() ?
483 pAttr->getShearXAngle() :
484 0.0 );
485 const double nShearY( pAttr->isShearYAngleValid() ?
486 pAttr->getShearYAngle() :
487 0.0 );
488 const double nRotation( pAttr->isRotationAngleValid() ?
489 basegfx::deg2rad(pAttr->getRotationAngle()) :
490 0.0 );
491
492 // scale, shear and rotation pivot point is the
493 // sprite's pixel center - adapt origin accordingly
494 aTransform.translate( -0.5*rPixelSize.getX(),
495 -0.5*rPixelSize.getY() );
496
497 const ::basegfx::B2DSize aSize(
498 pAttr->isWidthValid() ? pAttr->getWidth() : rOrigSize.getX(),
499 pAttr->isHeightValid() ? pAttr->getHeight() : rOrigSize.getY() );
500
501 // ensure valid size (zero size will inevitably lead
502 // to a singular transformation matrix).
503 aTransform.scale( ::basegfx::pruneScaleValue(
504 aSize.getWidth() /
505 ::basegfx::pruneScaleValue(
506 rOrigSize.getX() ) ),
507 ::basegfx::pruneScaleValue(
508 aSize.getHeight() /
509 ::basegfx::pruneScaleValue(
510 rOrigSize.getY() ) ) );
511
512 const bool bNeedShearX( !::basegfx::fTools::equalZero(nShearX) );
513 const bool bNeedShearY( !::basegfx::fTools::equalZero(nShearY) );
514 const bool bNeedRotation( !::basegfx::fTools::equalZero(nRotation) );
515
516 if( bNeedRotation || bNeedShearX || bNeedShearY )
517 {
518 if( bNeedShearX )
519 aTransform.shearX( nShearX );
520
521 if( bNeedShearY )
522 aTransform.shearY( nShearY );
523
524 if( bNeedRotation )
525 aTransform.rotate( nRotation );
526 }
527
528 // move left, top corner back to original position of
529 // the sprite (we've translated the center of the
530 // sprite to the origin above).
531 aTransform.translate( 0.5*rPixelSize.getX(),
532 0.5*rPixelSize.getY() );
533 }
534
535 // return identity transform for un-attributed
536 // shapes. This renders the sprite as-is, in its
537 // document-supplied size.
538 return aTransform;
539 }
540
541 ::basegfx::B2DRectangle getShapeUpdateArea( const ::basegfx::B2DRectangle& rUnitBounds,
542 const ::basegfx::B2DHomMatrix& rShapeTransform,
543 const ShapeAttributeLayerSharedPtr& pAttr )
544 {
545 ::basegfx::B2DHomMatrix aTransform;
546
547 if( pAttr &&
548 pAttr->isCharScaleValid() &&
549 fabs(pAttr->getCharScale()) > 1.0 )
550 {
551 // enlarge shape bounds. Have to consider the worst
552 // case here (the text fully fills the shape)
553
554 const double nCharScale( pAttr->getCharScale() );
555
556 // center of scaling is the middle of the shape
557 aTransform.translate( -0.5, -0.5 );
558 aTransform.scale( nCharScale, nCharScale );
559 aTransform.translate( 0.5, 0.5 );
560 }
561
562 aTransform *= rShapeTransform;
563
565
566 // apply shape transformation to unit rect
567 return ::canvas::tools::calcTransformedRectBounds(
568 aRes,
569 rUnitBounds,
570 aTransform );
571 }
572
573 ::basegfx::B2DRange getShapeUpdateArea( const ::basegfx::B2DRange& rUnitBounds,
574 const ::basegfx::B2DRange& rShapeBounds )
575 {
576 return ::basegfx::B2DRectangle(
577 basegfx::utils::lerp( rShapeBounds.getMinX(),
578 rShapeBounds.getMaxX(),
579 rUnitBounds.getMinX() ),
580 basegfx::utils::lerp( rShapeBounds.getMinY(),
581 rShapeBounds.getMaxY(),
582 rUnitBounds.getMinY() ),
583 basegfx::utils::lerp( rShapeBounds.getMinX(),
584 rShapeBounds.getMaxX(),
585 rUnitBounds.getMaxX() ),
586 basegfx::utils::lerp( rShapeBounds.getMinY(),
587 rShapeBounds.getMaxY(),
588 rUnitBounds.getMaxY() ) );
589 }
590
591 ::basegfx::B2DRectangle getShapePosSize( const ::basegfx::B2DRectangle& rOrigBounds,
592 const ShapeAttributeLayerSharedPtr& pAttr )
593 {
594 // an already empty shape bound need no further
595 // treatment. In fact, any changes applied below would
596 // actually remove the special empty state, thus, don't
597 // change!
598 if( !pAttr ||
599 rOrigBounds.isEmpty() )
600 {
601 return rOrigBounds;
602 }
603 else
604 {
605 // cannot use maBounds anymore, attributes might have been
606 // changed by now.
607 // Have to use absolute values here, as negative sizes
608 // (aka mirrored shapes) _still_ have the same bounds,
609 // only with mirrored content.
610 ::basegfx::B2DSize aSize;
611 aSize.setWidth( fabs( pAttr->isWidthValid() ?
612 pAttr->getWidth() :
613 rOrigBounds.getWidth() ) );
614 aSize.setHeight( fabs( pAttr->isHeightValid() ?
615 pAttr->getHeight() :
616 rOrigBounds.getHeight() ) );
617
619 aPos.setX( pAttr->isPosXValid() ?
620 pAttr->getPosX() :
621 rOrigBounds.getCenterX() );
622 aPos.setY( pAttr->isPosYValid() ?
623 pAttr->getPosY() :
624 rOrigBounds.getCenterY() );
625
626 // the positional attribute retrieved from the
627 // ShapeAttributeLayer actually denotes the _middle_
628 // of the shape (do it as the PPTs do...)
629 return ::basegfx::B2DRectangle(aPos - 0.5 * basegfx::B2DPoint(aSize),
630 aPos + 0.5 * basegfx::B2DPoint(aSize));
631 }
632 }
633
634 RGBColor unoColor2RGBColor( sal_Int32 nColor )
635 {
636 return RGBColor(
637 ::cppcanvas::makeColor(
638 // convert from API color to IntSRGBA color
639 // (0xAARRGGBB -> 0xRRGGBBAA)
640 static_cast< sal_uInt8 >( nColor >> 16U ),
641 static_cast< sal_uInt8 >( nColor >> 8U ),
642 static_cast< sal_uInt8 >( nColor ),
643 static_cast< sal_uInt8 >( nColor >> 24U ) ) );
644 }
645
647 {
648 return ::cppcanvas::makeColorARGB(
649 // convert from IntSRGBA color to API color
650 // (0xRRGGBBAA -> 0xAARRGGBB)
651 static_cast< sal_uInt8 >(0),
652 ::cppcanvas::getRed(aColor),
653 ::cppcanvas::getGreen(aColor),
654 ::cppcanvas::getBlue(aColor));
655 }
656
657 void fillRect( const ::cppcanvas::CanvasSharedPtr& rCanvas,
658 const ::basegfx::B2DRectangle& rRect,
659 ::cppcanvas::IntSRGBA aFillColor )
660 {
661 const ::basegfx::B2DPolygon aPoly(
662 ::basegfx::utils::createPolygonFromRect( rRect ));
663
666
667 if( pPolyPoly )
668 {
669 pPolyPoly->setRGBAFillColor( aFillColor );
670 pPolyPoly->draw();
671 }
672 }
673
674 void initSlideBackground( const ::cppcanvas::CanvasSharedPtr& rCanvas,
675 const ::basegfx::B2ISize& rSize )
676 {
677 ::cppcanvas::CanvasSharedPtr pCanvas( rCanvas->clone() );
678
679 // set transformation to identity (->device pixel)
680 pCanvas->setTransformation( ::basegfx::B2DHomMatrix() );
681
682 // #i42440# Fill the _full_ background in
683 // black. Since we had to extend the bitmap by one
684 // pixel, and the bitmap is initialized white,
685 // depending on the slide content a one pixel wide
686 // line will show to the bottom and the right.
687 fillRect( pCanvas,
688 ::basegfx::B2DRectangle( 0.0, 0.0,
689 rSize.getWidth(),
690 rSize.getHeight() ),
691 0x000000FFU );
692
693 // tdf#148884 in dark mode impress's auto text color assumes it will render against
694 // the DOCCOLOR by default, so leaving this as white gives white on white, this
695 // looks the simplest approach, propagate dark mode into slideshow mode instead
696 // of reformatting to render onto a white slideshow
697 svtools::ColorConfig aColorConfig;
698 Color aApplicationDocumentColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor;
699 cppcanvas::IntSRGBA nCanvasColor = cppcanvas::makeColor(aApplicationDocumentColor.GetRed(),
700 aApplicationDocumentColor.GetGreen(),
701 aApplicationDocumentColor.GetBlue(),
702 0xFF);
703
704 // fill the bounds rectangle in DOCCOLOR (typically white).
705 // Subtract one pixel from both width and height, because the slide
706 // size is chosen one pixel larger than given by the drawing layer.
707 // This is because shapes with line style, that have the size of
708 // the slide would otherwise be cut off. OTOH, every other slide
709 // background (solid fill, gradient, bitmap) render one pixel less,
710 // thus revealing ugly white pixel to the right and the bottom.
711 fillRect( pCanvas,
712 ::basegfx::B2DRectangle( 0.0, 0.0,
713 rSize.getWidth()-1,
714 rSize.getHeight()-1 ),
715 nCanvasColor );
716 }
717
719 {
721 uno::UNO_QUERY_THROW );
722 // read bound rect
723 awt::Rectangle aTmpRect;
724 if( !(xPropSet->getPropertyValue("BoundRect") >>= aTmpRect) )
725 {
726 ENSURE_OR_THROW( false,
727 "getAPIShapeBounds(): Could not get \"BoundRect\" property from shape" );
728 }
729
730 return ::basegfx::B2DRectangle( aTmpRect.X,
731 aTmpRect.Y,
732 aTmpRect.X+aTmpRect.Width,
733 aTmpRect.Y+aTmpRect.Height );
734 }
735
736/*
737 TODO(F1): When ZOrder someday becomes usable enable this
738
739 double getAPIShapePrio( const uno::Reference< drawing::XShape >& xShape )
740 {
741 uno::Reference< beans::XPropertySet > xPropSet( xShape,
742 uno::UNO_QUERY_THROW );
743 // read prio
744 sal_Int32 nPrio(0);
745 if( !(xPropSet->getPropertyValue(
746 OUString("ZOrder") ) >>= nPrio) )
747 {
748 ENSURE_OR_THROW( false,
749 "getAPIShapePrio(): Could not get \"ZOrder\" property from shape" );
750 }
751
752 // TODO(F2): Check and adapt the range of possible values here.
753 // Maybe we can also take the total number of shapes here
754 return nPrio / 65535.0;
755 }
756*/
757
759 const UnoViewSharedPtr& pView )
760 {
761 ENSURE_OR_THROW(pView, "getSlideSizePixel(): invalid view");
762
763 // determine transformed page bounds
764 const basegfx::B2DRange aRect( 0,0,
765 rSlideSize.getX(),
766 rSlideSize.getY() );
767 basegfx::B2DRange aTmpRect;
769 aRect,
770 pView->getTransformation() );
771
772 // #i42440# Returned slide size is one pixel too small, as
773 // rendering happens one pixel to the right and below the
774 // actual bound rect.
775 return basegfx::B2IVector(
776 basegfx::fround( aTmpRect.getRange().getX() ) + 1,
777 basegfx::fround( aTmpRect.getRange().getY() ) + 1 );
778 }
779}
780
781/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt8 GetBlue() const
sal_uInt8 GetRed() const
sal_uInt8 GetGreen() const
void shearX(double fSx)
void rotate(double fRadiant)
void translate(double fX, double fY)
void scale(double fX, double fY)
void shearY(double fSy)
B2DVector getRange() const
TYPE getMaxX() const
TYPE getMinX() const
TYPE getMinY() const
TYPE getMaxY() const
void setHeight(TYPE const &rHeight)
TYPE getWidth() const
void setWidth(TYPE const &rWidth)
TYPE getHeight() const
TYPE getX() const
void setY(TYPE fY)
TYPE getY() const
void setX(TYPE fX)
static PolyPolygonSharedPtr createPolyPolygon(const CanvasSharedPtr &, const ::basegfx::B2DPolygon &rPoly)
HSL color space class.
Definition: hslcolor.hxx:33
RGB color space class.
Definition: rgbcolor.hxx:35
static std::shared_ptr< ExpressionNode > const & parseSmilValue(const OUString &rSmilValue, const ::basegfx::B2DRectangle &rRelativeShapeBounds)
Parse a string containing a SMIL value.
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
#define ENSURE_OR_THROW(c, m)
ValueType lerp(const ValueType &rFrom, const ValueType &rTo, double t)
B2DHomMatrix createScaleTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fTranslateX, double fTranslateY)
B2IRange fround(const B2DRange &rRange)
constexpr double deg2rad(double v)
::basegfx::B2DRange & calcTransformedRectBounds(::basegfx::B2DRange &o_Rect, const ::basegfx::B2DRange &i_Rect, const ::basegfx::B2DHomMatrix &i_Transformation)
std::shared_ptr< PolyPolygon > PolyPolygonSharedPtr
sal_uInt32 IntSRGBA
IntSRGBA makeColor(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue, sal_uInt8 nAlpha)
std::shared_ptr< Canvas > CanvasSharedPtr
::basegfx::B2DRectangle getShapePosSize(const ::basegfx::B2DRectangle &rOrigBounds, const ShapeAttributeLayerSharedPtr &pAttr)
Definition: tools.cxx:591
sal_Int32 RGBAColor2UnoColor(::cppcanvas::IntSRGBA aColor)
Definition: tools.cxx:646
::basegfx::B2DRectangle getShapeUpdateArea(const ::basegfx::B2DRectangle &rUnitBounds, const ::basegfx::B2DHomMatrix &rShapeTransform, const ShapeAttributeLayerSharedPtr &pAttr)
Definition: tools.cxx:541
::std::shared_ptr< ShapeAttributeLayer > ShapeAttributeLayerSharedPtr
basegfx::B2IVector getSlideSizePixel(const basegfx::B2DVector &rSlideSize, const UnoViewSharedPtr &pView)
Definition: tools.cxx:758
::basegfx::B2DHomMatrix getShapeTransformation(const ::basegfx::B2DRectangle &rShapeBounds, const ShapeAttributeLayerSharedPtr &pAttr)
Definition: tools.cxx:456
bool findNamedValue(uno::Sequence< beans::NamedValue > const &rSequence, const beans::NamedValue &rSearchKey)
Definition: tools.cxx:433
::basegfx::B2DRectangle getAPIShapeBounds(const uno::Reference< drawing::XShape > &xShape)
Definition: tools.cxx:718
RGBColor unoColor2RGBColor(sal_Int32)
Convert a plain UNO API 32 bit int to RGBColor.
Definition: tools.cxx:634
void fillRect(const ::cppcanvas::CanvasSharedPtr &rCanvas, const ::basegfx::B2DRectangle &rRect, ::cppcanvas::IntSRGBA aFillColor)
Definition: tools.cxx:657
void initSlideBackground(const ::cppcanvas::CanvasSharedPtr &rCanvas, const ::basegfx::B2ISize &rSize)
Definition: tools.cxx:674
::std::shared_ptr< Shape > ShapeSharedPtr
std::shared_ptr< UnoView > UnoViewSharedPtr
bool extractValue(double &o_rValue, const uno::Any &rSourceAny, const ShapeSharedPtr &rShape, const ::basegfx::B2DVector &rSlideBounds)
extract unary double value from Any
Definition: tools.cxx:137
::basegfx::B2DHomMatrix getSpriteTransformation(const ::basegfx::B2DVector &rPixelSize, const ::basegfx::B2DVector &rOrigSize, const ShapeAttributeLayerSharedPtr &pAttr)
Definition: tools.cxx:474
basegfx::B2DRange calcRelativeShapeBounds(const basegfx::B2DVector &rPageSize, const basegfx::B2DRange &rShapeBounds)
Definition: tools.cxx:440
This exception is thrown, when the SMIL arithmetic expression parser failed to parse a string.
const beans::NamedValue & mrKey
Definition: tools.cxx:75
unsigned char sal_uInt8