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