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