LibreOffice Module svx (master)  1
sdrdecompositiontools.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 
40 #include <svx/svdotext.hxx>
52 
53 
54 using namespace com::sun::star;
55 
56 
58 {
59 namespace
60 {
61 // See also: SdrTextObj::AdjustRectToTextDistance
62 basegfx::B2DRange getTextAnchorRange(const attribute::SdrTextAttribute& rText,
63  const basegfx::B2DRange& rSnapRange)
64 {
65  // Take vertical text orientation into account when deciding
66  // which dimension is its width, and which is its height
67  const OutlinerParaObject& rOutlinerParaObj = rText.getOutlinerParaObject();
68  const bool bVerticalWriting(rOutlinerParaObj.IsEffectivelyVertical());
69  const double fWidthForText = bVerticalWriting ? rSnapRange.getHeight() : rSnapRange.getWidth();
70  // create a range describing the wanted text position and size (aTextAnchorRange). This
71  // means to use the text distance values here
72  // If the margin is larger than the entire width of the text area, then limit the
73  // margin.
74  const double fTextLeftDistance
75  = std::min(static_cast<double>(rText.getTextLeftDistance()), fWidthForText);
76  const double nTextRightDistance
77  = std::min(static_cast<double>(rText.getTextRightDistance()), fWidthForText);
78  double fDistanceForTextL, fDistanceForTextT, fDistanceForTextR, fDistanceForTextB;
79  if (!bVerticalWriting)
80  {
81  fDistanceForTextL = fTextLeftDistance;
82  fDistanceForTextT = rText.getTextUpperDistance();
83  fDistanceForTextR = nTextRightDistance;
84  fDistanceForTextB = rText.getTextLowerDistance();
85  }
86  else if (rOutlinerParaObj.IsTopToBottom())
87  {
88  fDistanceForTextL = rText.getTextLowerDistance();
89  fDistanceForTextT = fTextLeftDistance;
90  fDistanceForTextR = rText.getTextUpperDistance();
91  fDistanceForTextB = nTextRightDistance;
92  }
93  else
94  {
95  fDistanceForTextL = rText.getTextUpperDistance();
96  fDistanceForTextT = nTextRightDistance;
97  fDistanceForTextR = rText.getTextLowerDistance();
98  fDistanceForTextB = fTextLeftDistance;
99  }
100  const basegfx::B2DPoint aTopLeft(rSnapRange.getMinX() + fDistanceForTextL,
101  rSnapRange.getMinY() + fDistanceForTextT);
102  const basegfx::B2DPoint aBottomRight(rSnapRange.getMaxX() - fDistanceForTextR,
103  rSnapRange.getMaxY() - fDistanceForTextB);
104  basegfx::B2DRange aAnchorRange;
105  aAnchorRange.expand(aTopLeft);
106  aAnchorRange.expand(aBottomRight);
107 
108  // If the shape has no width, then don't attempt to break the text into multiple
109  // lines, not a single character would satisfy a zero width requirement.
110  // SdrTextObj::impDecomposeBlockTextPrimitive() uses the same constant to
111  // effectively set no limits.
112  if (!bVerticalWriting && aAnchorRange.getWidth() == 0)
113  {
114  aAnchorRange.expand(basegfx::B2DPoint(aTopLeft.getX() - 1000000, aTopLeft.getY()));
115  aAnchorRange.expand(basegfx::B2DPoint(aBottomRight.getX() + 1000000, aBottomRight.getY()));
116  }
117  else if (bVerticalWriting && aAnchorRange.getHeight() == 0)
118  {
119  aAnchorRange.expand(basegfx::B2DPoint(aTopLeft.getX(), aTopLeft.getY() - 1000000));
120  aAnchorRange.expand(basegfx::B2DPoint(aBottomRight.getX(), aBottomRight.getY() + 1000000));
121  }
122  return aAnchorRange;
123 }
124 };
125 
126  class TransparencePrimitive2D;
127 
129  const basegfx::B2DPolyPolygon& rPolyPolygon,
130  const attribute::SdrFillAttribute& rFill,
131  const attribute::FillGradientAttribute& rFillGradient)
132  {
133  // when we have no given definition range, use the range of the given geometry
134  // also for definition (simplest case)
135  const basegfx::B2DRange aRange(basegfx::utils::getRange(rPolyPolygon));
136 
138  rPolyPolygon,
139  aRange,
140  rFill,
141  rFillGradient);
142  }
143 
145  const basegfx::B2DPolyPolygon& rPolyPolygon,
146  const basegfx::B2DRange& rDefinitionRange,
147  const attribute::SdrFillAttribute& rFill,
148  const attribute::FillGradientAttribute& rFillGradient)
149  {
151  {
152  return Primitive2DReference();
153  }
154 
155  // prepare fully scaled polygon
156  rtl::Reference<BasePrimitive2D> pNewFillPrimitive;
157 
158  if(!rFill.getGradient().isDefault())
159  {
160  pNewFillPrimitive = new PolyPolygonGradientPrimitive2D(
161  rPolyPolygon,
162  rDefinitionRange,
163  rFill.getGradient());
164  }
165  else if(!rFill.getHatch().isDefault())
166  {
167  pNewFillPrimitive = new PolyPolygonHatchPrimitive2D(
168  rPolyPolygon,
169  rDefinitionRange,
170  rFill.getColor(),
171  rFill.getHatch());
172  }
173  else if(!rFill.getFillGraphic().isDefault())
174  {
175  pNewFillPrimitive = new PolyPolygonGraphicPrimitive2D(
176  rPolyPolygon,
177  rDefinitionRange,
178  rFill.getFillGraphic().createFillGraphicAttribute(rDefinitionRange));
179  }
180  else
181  {
182  pNewFillPrimitive = new PolyPolygonColorPrimitive2D(
183  rPolyPolygon,
184  rFill.getColor());
185  }
186 
187  if(0.0 != rFill.getTransparence())
188  {
189  // create simpleTransparencePrimitive, add created fill primitive
190  const Primitive2DContainer aContent { pNewFillPrimitive };
192  }
193  else if(!rFillGradient.isDefault())
194  {
195  // create sequence with created fill primitive
196  const Primitive2DContainer aContent { pNewFillPrimitive };
197 
198  // create FillGradientPrimitive2D for transparence and add to new sequence
199  // fillGradientPrimitive is enough here (compared to PolyPolygonGradientPrimitive2D) since float transparence will be masked anyways
200  const basegfx::B2DRange aRange(basegfx::utils::getRange(rPolyPolygon));
201  const Primitive2DReference xRefB(
203  aRange,
204  rDefinitionRange,
205  rFillGradient));
206  const Primitive2DContainer aAlpha { xRefB };
207 
208  // create TransparencePrimitive2D using alpha and content
209  return Primitive2DReference(new TransparencePrimitive2D(aContent, aAlpha));
210  }
211  else
212  {
213  // add to decomposition
214  return Primitive2DReference(pNewFillPrimitive);
215  }
216  }
217 
219  const basegfx::B2DPolygon& rPolygon,
220  const attribute::SdrLineAttribute& rLine,
222  {
223  // create line and stroke attribute
224  const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin(), rLine.getCap());
225  const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen());
226  rtl::Reference<BasePrimitive2D> pNewLinePrimitive;
227 
228  if(!rPolygon.isClosed() && !rStroke.isDefault())
229  {
231  attribute::LineStartEndAttribute aEnd(rStroke.getEndWidth(), rStroke.getEndPolyPolygon(), rStroke.isEndCentered());
232 
233  // create data
234  pNewLinePrimitive = new PolygonStrokeArrowPrimitive2D(rPolygon, aLineAttribute, aStrokeAttribute, aStart, aEnd);
235  }
236  else
237  {
238  // create data
239  pNewLinePrimitive = new PolygonStrokePrimitive2D(rPolygon, aLineAttribute, aStrokeAttribute);
240  }
241 
242  if(0.0 != rLine.getTransparence())
243  {
244  // create simpleTransparencePrimitive, add created fill primitive
245  const Primitive2DContainer aContent { pNewLinePrimitive };
247  }
248  else
249  {
250  // add to decomposition
251  return Primitive2DReference(pNewLinePrimitive);
252  }
253  }
254 
256  const basegfx::B2DPolyPolygon& rUnitPolyPolygon,
257  const basegfx::B2DHomMatrix& rObjectTransform,
258  const attribute::SdrTextAttribute& rText,
259  const attribute::SdrLineAttribute& rStroke,
260  bool bCellText,
261  bool bWordWrap)
262  {
263  basegfx::B2DHomMatrix aAnchorTransform(rObjectTransform);
265 
266  if(rText.isContour())
267  {
268  // contour text
269  if(!rStroke.isDefault() && 0.0 != rStroke.getWidth())
270  {
271  // take line width into account and shrink contour polygon accordingly
272  // decompose to get scale
273  basegfx::B2DVector aScale, aTranslate;
274  double fRotate, fShearX;
275  rObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
276 
277  // scale outline to object's size to allow growing with value relative to that size
278  // and also to keep aspect ratio
279  basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon);
280  aScaledUnitPolyPolygon.transform(basegfx::utils::createScaleB2DHomMatrix(
281  fabs(aScale.getX()), fabs(aScale.getY())));
282 
283  // grow the polygon. To shrink, use negative value (half width)
284  aScaledUnitPolyPolygon = basegfx::utils::growInNormalDirection(aScaledUnitPolyPolygon, -(rStroke.getWidth() * 0.5));
285 
286  // scale back to unit polygon
287  aScaledUnitPolyPolygon.transform(basegfx::utils::createScaleB2DHomMatrix(
288  0.0 != aScale.getX() ? 1.0 / aScale.getX() : 1.0,
289  0.0 != aScale.getY() ? 1.0 / aScale.getY() : 1.0));
290 
291  // create with unit polygon
292  pNew = new SdrContourTextPrimitive2D(
293  &rText.getSdrText(),
294  rText.getOutlinerParaObject(),
295  aScaledUnitPolyPolygon,
296  rObjectTransform);
297  }
298  else
299  {
300  // create with unit polygon
301  pNew = new SdrContourTextPrimitive2D(
302  &rText.getSdrText(),
303  rText.getOutlinerParaObject(),
304  rUnitPolyPolygon,
305  rObjectTransform);
306  }
307  }
308  else if(!rText.getSdrFormTextAttribute().isDefault())
309  {
310  // text on path, use scaled polygon
311  basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon);
312  aScaledPolyPolygon.transform(rObjectTransform);
313  pNew = new SdrPathTextPrimitive2D(
314  &rText.getSdrText(),
315  rText.getOutlinerParaObject(),
316  aScaledPolyPolygon,
317  rText.getSdrFormTextAttribute());
318  }
319  else
320  {
321  // rObjectTransform is the whole SdrObject transformation from unit rectangle
322  // to its size and position. Decompose to allow working with single values.
323  basegfx::B2DVector aScale, aTranslate;
324  double fRotate, fShearX;
325  rObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
326 
327  // extract mirroring
328  const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
329  const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
330  aScale = basegfx::absolute(aScale);
331 
332  // Get the real size, since polygon outline and scale
333  // from the object transformation may vary (e.g. ellipse segments)
334  basegfx::B2DHomMatrix aJustScaleTransform;
335  aJustScaleTransform.set(0, 0, aScale.getX());
336  aJustScaleTransform.set(1, 1, aScale.getY());
337  basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon);
338  aScaledUnitPolyPolygon.transform(aJustScaleTransform);
339  const basegfx::B2DRange aTextAnchorRange
340  = getTextAnchorRange(rText, basegfx::utils::getRange(aScaledUnitPolyPolygon));
341 
342  // now create a transformation from this basic range (aTextAnchorRange)
343  // #i121494# if we have no scale use at least 1.0 to have a carrier e.g. for
344  // mirror values, else these will get lost
346  basegfx::fTools::equalZero(aTextAnchorRange.getWidth()) ? 1.0 : aTextAnchorRange.getWidth(),
347  basegfx::fTools::equalZero(aTextAnchorRange.getHeight()) ? 1.0 : aTextAnchorRange.getHeight(),
348  aTextAnchorRange.getMinX(), aTextAnchorRange.getMinY());
349 
350  // apply mirroring
351  aAnchorTransform.scale(bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0);
352 
353  // apply object's other transforms
354  aAnchorTransform = basegfx::utils::createShearXRotateTranslateB2DHomMatrix(fShearX, fRotate, aTranslate)
355  * aAnchorTransform;
356 
357  if(rText.isFitToSize())
358  {
359  // stretched text in range
360  pNew = new SdrStretchTextPrimitive2D(
361  &rText.getSdrText(),
362  rText.getOutlinerParaObject(),
363  aAnchorTransform,
364  rText.isFixedCellHeight());
365  }
366  else if(rText.isAutoFit())
367  {
368  // isotropically scaled text in range
369  pNew = new SdrAutoFitTextPrimitive2D(
370  &rText.getSdrText(),
371  rText.getOutlinerParaObject(),
372  aAnchorTransform,
373  bWordWrap);
374  }
375  else if( rText.isChainable() && !rText.isInEditMode() )
376  {
377  pNew = new SdrChainedTextPrimitive2D(
378  &rText.getSdrText(),
379  rText.getOutlinerParaObject(),
380  aAnchorTransform );
381  }
382  else // text in range
383  {
384  // build new primitive
385  pNew = new SdrBlockTextPrimitive2D(
386  &rText.getSdrText(),
387  rText.getOutlinerParaObject(),
388  aAnchorTransform,
389  rText.getSdrTextHorzAdjust(),
390  rText.getSdrTextVertAdjust(),
391  rText.isFixedCellHeight(),
392  rText.isScroll(),
393  bCellText,
394  bWordWrap);
395  }
396  }
397 
398  OSL_ENSURE(pNew != nullptr, "createTextPrimitive: no text primitive created (!)");
399 
400  if(rText.isBlink())
401  {
402  // prepare animation and primitive list
404  rText.getBlinkTextTiming(aAnimationList);
405 
406  if(0.0 != aAnimationList.getDuration())
407  {
408  // create content sequence
409  const Primitive2DReference xRefA(pNew);
410  const Primitive2DContainer aContent { xRefA };
411 
412  // create and add animated switch primitive
413  return Primitive2DReference(new AnimatedBlinkPrimitive2D(aAnimationList, aContent));
414  }
415  else
416  {
417  // add to decomposition
418  return Primitive2DReference(pNew);
419  }
420  }
421 
422  if(rText.isScroll())
423  {
424  // suppress scroll when FontWork
425  if(rText.getSdrFormTextAttribute().isDefault())
426  {
427  // get scroll direction
428  const SdrTextAniDirection eDirection(rText.getSdrText().GetObject().GetTextAniDirection());
429  const bool bHorizontal(SdrTextAniDirection::Left == eDirection || SdrTextAniDirection::Right == eDirection);
430 
431  // decompose to get separated values for the scroll box
432  basegfx::B2DVector aScale, aTranslate;
433  double fRotate, fShearX;
434  aAnchorTransform.decompose(aScale, aTranslate, fRotate, fShearX);
435 
436  // build transform from scaled only to full AnchorTransform and inverse
438  fShearX, fRotate, aTranslate));
439  basegfx::B2DHomMatrix aISRT(aSRT);
440  aISRT.invert();
441 
442  // bring the primitive back to scaled only and get scaled range, create new clone for this
443  rtl::Reference<SdrTextPrimitive2D> pNew2 = pNew->createTransformedClone(aISRT);
444  OSL_ENSURE(pNew2, "createTextPrimitive: Could not create transformed clone of text primitive (!)");
445  pNew = pNew2.get();
446 
447  // create neutral geometry::ViewInformation2D for local range and decompose calls. This is okay
448  // since the decompose is view-independent
449  const uno::Sequence< beans::PropertyValue > xViewParameters;
450  geometry::ViewInformation2D aViewInformation2D(xViewParameters);
451 
452  // get range
453  const basegfx::B2DRange aScaledRange(pNew->getB2DRange(aViewInformation2D));
454 
455  // create left outside and right outside transformations. Also take care
456  // of the clip rectangle
457  basegfx::B2DHomMatrix aLeft, aRight;
458  basegfx::B2DPoint aClipTopLeft(0.0, 0.0);
459  basegfx::B2DPoint aClipBottomRight(aScale.getX(), aScale.getY());
460 
461  if(bHorizontal)
462  {
463  aClipTopLeft.setY(aScaledRange.getMinY());
464  aClipBottomRight.setY(aScaledRange.getMaxY());
465  aLeft.translate(-aScaledRange.getMaxX(), 0.0);
466  aRight.translate(aScale.getX() - aScaledRange.getMinX(), 0.0);
467  }
468  else
469  {
470  aClipTopLeft.setX(aScaledRange.getMinX());
471  aClipBottomRight.setX(aScaledRange.getMaxX());
472  aLeft.translate(0.0, -aScaledRange.getMaxY());
473  aRight.translate(0.0, aScale.getY() - aScaledRange.getMinY());
474  }
475 
476  aLeft *= aSRT;
477  aRight *= aSRT;
478 
479  // prepare animation list
481 
482  if(bHorizontal)
483  {
484  rText.getScrollTextTiming(aAnimationList, aScale.getX(), aScaledRange.getWidth());
485  }
486  else
487  {
488  rText.getScrollTextTiming(aAnimationList, aScale.getY(), aScaledRange.getHeight());
489  }
490 
491  if(0.0 != aAnimationList.getDuration())
492  {
493  // create a new Primitive2DContainer containing the animated text in its scaled only state.
494  // use the decomposition to force to simple text primitives, those will no longer
495  // need the outliner for formatting (alternatively it is also possible to just add
496  // pNew to aNewPrimitiveSequence)
497  Primitive2DContainer aAnimSequence;
498  pNew->get2DDecomposition(aAnimSequence, aViewInformation2D);
499  pNew.clear();
500 
501  // create a new animatedInterpolatePrimitive and add it
502  std::vector< basegfx::B2DHomMatrix > aMatrixStack;
503  aMatrixStack.push_back(aLeft);
504  aMatrixStack.push_back(aRight);
505  const Primitive2DReference xRefA(new AnimatedInterpolatePrimitive2D(aMatrixStack, aAnimationList, aAnimSequence));
506  const Primitive2DContainer aContent { xRefA };
507 
508  // scrolling needs an encapsulating clipping primitive
509  const basegfx::B2DRange aClipRange(aClipTopLeft, aClipBottomRight);
511  aClipPolygon.transform(aSRT);
512  return Primitive2DReference(new MaskPrimitive2D(basegfx::B2DPolyPolygon(aClipPolygon), aContent));
513  }
514  else
515  {
516  // add to decomposition
517  return Primitive2DReference(pNew);
518  }
519  }
520  }
521 
522  if(rText.isInEditMode())
523  {
524  // #i97628#
525  // encapsulate with TextHierarchyEditPrimitive2D to allow renderers
526  // to suppress actively edited content if needed
527  const Primitive2DReference xRefA(pNew);
528  const Primitive2DContainer aContent { xRefA };
529 
530  // create and add TextHierarchyEditPrimitive2D primitive
532  }
533  else
534  {
535  // add to decomposition
536  return pNew;
537  }
538  }
539 
541  const Primitive2DContainer& rContent,
542  const attribute::SdrShadowAttribute& rShadow,
543  const basegfx::B2DHomMatrix& rObjectMatrix,
544  const Primitive2DContainer* pContentForShadow)
545  {
546  if(!rContent.empty())
547  {
548  Primitive2DContainer aRetval(2);
549  basegfx::B2DHomMatrix aShadowOffset;
550 
551  {
552  if(rShadow.getSize().getX() != 100000)
553  {
554  basegfx::B2DTuple aScale;
555  basegfx::B2DTuple aTranslate;
556  double fRotate = 0;
557  double fShearX = 0;
558  rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
559  // Scale the shadow
560  double nTranslateX = aTranslate.getX();
561  double nTranslateY = aTranslate.getY();
562 
563  // The origin for scaling is the top left corner by default. A negative
564  // shadow offset changes the origin.
565  if (rShadow.getOffset().getX() < 0)
566  nTranslateX += aScale.getX();
567  if (rShadow.getOffset().getY() < 0)
568  nTranslateY += aScale.getY();
569 
570  aShadowOffset.translate(-nTranslateX, -nTranslateY);
571  aShadowOffset.scale(rShadow.getSize().getX() * 0.00001, rShadow.getSize().getY() * 0.00001);
572  aShadowOffset.translate(nTranslateX, nTranslateY);
573  }
574 
575  aShadowOffset.translate(rShadow.getOffset().getX(), rShadow.getOffset().getY());
576  }
577 
578  // create shadow primitive and add content
579  aRetval[0] = Primitive2DReference(
580  new ShadowPrimitive2D(
581  aShadowOffset,
582  rShadow.getColor(),
583  rShadow.getBlur(),
584  (pContentForShadow ? *pContentForShadow : rContent)));
585 
586  if(0.0 != rShadow.getTransparence())
587  {
588  // create SimpleTransparencePrimitive2D
589  const Primitive2DContainer aTempContent { aRetval[0] };
590 
591  aRetval[0] = Primitive2DReference(
593  aTempContent,
594  rShadow.getTransparence()));
595  }
596 
597  aRetval[1] = Primitive2DReference(new GroupPrimitive2D(rContent));
598  return aRetval;
599  }
600  else
601  {
602  return rContent;
603  }
604  }
605 
607  const Primitive2DContainer& rContent,
608  const attribute::SdrGlowAttribute& rGlow)
609  {
610  if(rContent.empty())
611  return rContent;
612  Primitive2DContainer aRetval(2);
613  aRetval[0] = Primitive2DReference(
614  new GlowPrimitive2D(rGlow.getColor(), rGlow.getRadius(), rContent));
615  aRetval[1] = Primitive2DReference(new GroupPrimitive2D(rContent));
616  return aRetval;
617  }
618 
620  sal_Int32 nRadius)
621  {
622  if (rContent.empty() || !nRadius)
623  return rContent;
624  Primitive2DContainer aRetval(1);
625  aRetval[0] = Primitive2DReference(new SoftEdgePrimitive2D(nRadius, rContent));
626  return aRetval;
627  }
628 
629 } // end of namespace
630 
631 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double getY() const
B2DPolygon growInNormalDirection(const B2DPolygon &rCandidate, double fValue)
const FillGradientAttribute & getGradient() const
void expand(const B2DTuple &rTuple)
Primitive2DContainer createEmbeddedGlowPrimitive(const Primitive2DContainer &rContent, const attribute::SdrGlowAttribute &rGlow)
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
double getHeight() const
css::drawing::LineCap getCap() const
bool moreOrEqual(const T &rfValA, const T &rfValB)
B2DTuple absolute(const B2DTuple &rTup)
bool equalZero(const T &rfVal)
const basegfx::BColor & getColor() const
const basegfx::BColor & getColor() const
bool IsTopToBottom() const
double getMaxX() const
void setX(double fX)
const basegfx::B2DPolyPolygon & getStartPolyPolygon() const
Primitive2DContainer createEmbeddedShadowPrimitive(const Primitive2DContainer &rContent, const attribute::SdrShadowAttribute &rShadow, const basegfx::B2DHomMatrix &rObjectMatrix, const Primitive2DContainer *pContentForShadow)
double getWidth() const
B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY)
basegfx::B2DLineJoin getJoin() const
B2DHomMatrix createScaleTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fTranslateX, double fTranslateY)
const FillHatchAttribute & getHatch() const
Primitive2DReference createPolyPolygonFillPrimitive(const basegfx::B2DPolyPolygon &rPolyPolygon, const basegfx::B2DRange &rDefinitionRange, const attribute::SdrFillAttribute &rFill, const attribute::FillGradientAttribute &rFillGradient)
SdrTextHorzAdjust getSdrTextHorzAdjust() const
double getMaxY() const
bool isClosed() const
const OutlinerParaObject & getOutlinerParaObject() const
FillGraphicAttribute createFillGraphicAttribute(const basegfx::B2DRange &rRange) const
const basegfx::B2DPolyPolygon & getEndPolyPolygon() const
void getScrollTextTiming(drawinglayer::animation::AnimationEntryList &rAnimList, double fFrameLength, double fTextLength) const
virtual double getDuration() const override
bool decompose(B2DTuple &rScale, B2DTuple &rTranslate, double &rRotate, double &rShearX) const
SdrTextObj & GetObject() const
Definition: svdtext.hxx:63
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
const basegfx::B2DVector & getOffset() const
const ::std::vector< double > & getDotDashArray() const
const basegfx::BColor & getColor() const
void scale(double fX, double fY)
void transform(const basegfx::B2DHomMatrix &rMatrix)
Primitive2DReference createTextPrimitive(const basegfx::B2DPolyPolygon &rUnitPolyPolygon, const basegfx::B2DHomMatrix &rObjectTransform, const attribute::SdrTextAttribute &rText, const attribute::SdrLineAttribute &rStroke, bool bCellText, bool bWordWrap)
B2DRange getRange(const B2DPolygon &rCandidate)
void transform(const basegfx::B2DHomMatrix &rMatrix)
void setY(double fY)
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
bool IsEffectivelyVertical() const
double getMinY() const
void getBlinkTextTiming(drawinglayer::animation::AnimationEntryList &rAnimList) const
bool less(const T &rfValA, const T &rfValB)
Primitive2DContainer createEmbeddedSoftEdgePrimitive(const Primitive2DContainer &rContent, sal_Int32 nRadius)
SdrTextAniDirection GetTextAniDirection() const
Definition: svdotext.cxx:1760
void translate(double fX, double fY)
SdrTextAniDirection
Definition: sdtaditm.hxx:29
const SdrFormTextAttribute & getSdrFormTextAttribute() const
double getX() const
double getMinX() const
const SdrFillGraphicAttribute & getFillGraphic() const
SdrTextVertAdjust getSdrTextVertAdjust() const
const basegfx::B2DVector & getSize() const
B2DHomMatrix createShearXRotateTranslateB2DHomMatrix(double fShearX, double fRadiant, double fTranslateX, double fTranslateY)
Primitive2DReference createPolygonLinePrimitive(const basegfx::B2DPolygon &rPolygon, const attribute::SdrLineAttribute &rLine, const attribute::SdrLineStartEndAttribute &rStroke)