Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <svx/sdr/primitive2d/sdrdecompositiontools.hxx>
30 : : #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
31 : : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
32 : : #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
33 : : #include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
34 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
35 : : #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
36 : : #include <drawinglayer/attribute/strokeattribute.hxx>
37 : : #include <drawinglayer/attribute/linestartendattribute.hxx>
38 : : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
39 : : #include <drawinglayer/attribute/sdrfillbitmapattribute.hxx>
40 : : #include <basegfx/matrix/b2dhommatrix.hxx>
41 : : #include <drawinglayer/primitive2d/shadowprimitive2d.hxx>
42 : : #include <svx/sdr/attribute/sdrtextattribute.hxx>
43 : : #include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx>
44 : : #include <svx/svdotext.hxx>
45 : : #include <basegfx/polygon/b2dpolygontools.hxx>
46 : : #include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
47 : : #include <drawinglayer/animation/animationtiming.hxx>
48 : : #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
49 : : #include <basegfx/tools/canvastools.hxx>
50 : : #include <drawinglayer/geometry/viewinformation2d.hxx>
51 : : #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx>
52 : : #include <drawinglayer/attribute/sdrfillattribute.hxx>
53 : : #include <drawinglayer/attribute/sdrlineattribute.hxx>
54 : : #include <drawinglayer/attribute/sdrlinestartendattribute.hxx>
55 : : #include <drawinglayer/attribute/sdrshadowattribute.hxx>
56 : :
57 : : //////////////////////////////////////////////////////////////////////////////
58 : :
59 : : using namespace com::sun::star;
60 : :
61 : : //////////////////////////////////////////////////////////////////////////////
62 : :
63 : : namespace drawinglayer
64 : : {
65 : : namespace primitive2d
66 : : {
67 : 14200 : Primitive2DReference createPolyPolygonFillPrimitive(
68 : : const basegfx::B2DPolyPolygon& rUnitPolyPolygon,
69 : : const basegfx::B2DHomMatrix& rObjectTransform,
70 : : const attribute::SdrFillAttribute& rFill,
71 : : const attribute::FillGradientAttribute& rFillGradient)
72 : : {
73 : : // prepare fully scaled polygon
74 [ + - ]: 14200 : basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon);
75 [ + - ]: 14200 : aScaledPolyPolygon.transform(rObjectTransform);
76 : 14200 : BasePrimitive2D* pNewFillPrimitive = 0;
77 : :
78 [ + - ][ + - ]: 14200 : if(!rFill.getGradient().isDefault())
[ + + ]
79 : : {
80 [ + - ][ + - ]: 209 : pNewFillPrimitive = new PolyPolygonGradientPrimitive2D(aScaledPolyPolygon, rFill.getGradient());
81 : : }
82 [ + - ][ + - ]: 13991 : else if(!rFill.getHatch().isDefault())
[ + + ]
83 : : {
84 [ + - ][ + - ]: 1266 : pNewFillPrimitive = new PolyPolygonHatchPrimitive2D(aScaledPolyPolygon, rFill.getColor(), rFill.getHatch());
[ + - ]
85 : : }
86 [ + - ][ + - ]: 12725 : else if(!rFill.getBitmap().isDefault())
[ + + ]
87 : : {
88 [ + - ]: 262 : const basegfx::B2DRange aRange(basegfx::tools::getRange(aScaledPolyPolygon));
89 [ + - ][ + - ]: 262 : pNewFillPrimitive = new PolyPolygonBitmapPrimitive2D(aScaledPolyPolygon, rFill.getBitmap().getFillBitmapAttribute(aRange));
[ + - ][ + - ]
90 : : }
91 : : else
92 : : {
93 [ + - ][ + - ]: 12463 : pNewFillPrimitive = new PolyPolygonColorPrimitive2D(aScaledPolyPolygon, rFill.getColor());
94 : : }
95 : :
96 [ + - ][ + + ]: 14200 : if(0.0 != rFill.getTransparence())
97 : : {
98 : : // create simpleTransparencePrimitive, add created fill primitive
99 [ + - ][ + - ]: 201 : const Primitive2DReference xRefA(pNewFillPrimitive);
100 [ + - ]: 201 : const Primitive2DSequence aContent(&xRefA, 1L);
101 [ + - ][ + - ]: 201 : return Primitive2DReference(new UnifiedTransparencePrimitive2D(aContent, rFill.getTransparence()));
[ + - ][ + - ]
[ + - ]
102 : : }
103 [ + - ][ + + ]: 13999 : else if(!rFillGradient.isDefault())
104 : : {
105 : : // create sequence with created fill primitive
106 [ + - ][ + - ]: 2355 : const Primitive2DReference xRefA(pNewFillPrimitive);
107 [ + - ]: 2355 : const Primitive2DSequence aContent(&xRefA, 1L);
108 : :
109 : : // create FillGradientPrimitive2D for transparence and add to new sequence
110 : : // fillGradientPrimitive is enough here (compared to PolyPolygonGradientPrimitive2D) since float transparence will be masked anyways
111 [ + - ]: 2355 : const basegfx::B2DRange aRange(basegfx::tools::getRange(aScaledPolyPolygon));
112 [ + - ][ + - ]: 2355 : const Primitive2DReference xRefB(new FillGradientPrimitive2D(aRange, rFillGradient));
[ + - ]
113 [ + - ]: 2355 : const Primitive2DSequence aAlpha(&xRefB, 1L);
114 : :
115 : : // create TransparencePrimitive2D using alpha and content
116 [ + - ][ + - ]: 2355 : return Primitive2DReference(new TransparencePrimitive2D(aContent, aAlpha));
[ + - ][ + - ]
[ + - ]
117 : : }
118 : : else
119 : : {
120 : : // add to decomposition
121 [ + - ][ + - ]: 11644 : return Primitive2DReference(pNewFillPrimitive);
122 [ + - ]: 14200 : }
123 : : }
124 : :
125 : 24279 : Primitive2DReference createPolygonLinePrimitive(
126 : : const basegfx::B2DPolygon& rUnitPolygon,
127 : : const basegfx::B2DHomMatrix& rObjectTransform,
128 : : const attribute::SdrLineAttribute& rLine,
129 : : const attribute::SdrLineStartEndAttribute& rStroke)
130 : : {
131 : : // prepare fully scaled polygon
132 [ + - ]: 24279 : basegfx::B2DPolygon aScaledPolygon(rUnitPolygon);
133 [ + - ]: 24279 : aScaledPolygon.transform(rObjectTransform);
134 : :
135 : : // create line and stroke attribute
136 [ + - ][ + - ]: 24279 : const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin());
[ + - ][ + - ]
137 [ + - ][ + - ]: 24279 : const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen());
[ + - ]
138 : 24279 : BasePrimitive2D* pNewLinePrimitive = 0L;
139 : :
140 [ + - ][ + + ]: 24279 : if(!rUnitPolygon.isClosed() && !rStroke.isDefault())
[ + - ][ + + ]
[ + + ]
141 : : {
142 [ + - ][ + - ]: 8 : attribute::LineStartEndAttribute aStart(rStroke.getStartWidth(), rStroke.getStartPolyPolygon(), rStroke.isStartCentered());
[ + - ][ + - ]
143 [ + - ][ + - ]: 8 : attribute::LineStartEndAttribute aEnd(rStroke.getEndWidth(), rStroke.getEndPolyPolygon(), rStroke.isEndCentered());
[ + - ][ + - ]
144 : :
145 : : // create data
146 [ + - ][ + - ]: 8 : pNewLinePrimitive = new PolygonStrokeArrowPrimitive2D(aScaledPolygon, aLineAttribute, aStrokeAttribute, aStart, aEnd);
[ + - ]
147 : : }
148 : : else
149 : : {
150 : : // create data
151 [ + - ]: 24271 : pNewLinePrimitive = new PolygonStrokePrimitive2D(aScaledPolygon, aLineAttribute, aStrokeAttribute);
152 : : }
153 : :
154 [ + - ][ + + ]: 24279 : if(0.0 != rLine.getTransparence())
155 : : {
156 : : // create simpleTransparencePrimitive, add created fill primitive
157 [ + - ][ + - ]: 15 : const Primitive2DReference xRefA(pNewLinePrimitive);
158 [ + - ]: 15 : const Primitive2DSequence aContent(&xRefA, 1L);
159 [ + - ][ + - ]: 15 : return Primitive2DReference(new UnifiedTransparencePrimitive2D(aContent, rLine.getTransparence()));
[ + - ][ + - ]
[ + - ]
160 : : }
161 : : else
162 : : {
163 : : // add to decomposition
164 [ + - ][ + - ]: 24264 : return Primitive2DReference(pNewLinePrimitive);
165 [ + - ][ + - ]: 24279 : }
[ + - ]
166 : : }
167 : :
168 : 13465 : Primitive2DReference createTextPrimitive(
169 : : const basegfx::B2DPolyPolygon& rUnitPolyPolygon,
170 : : const basegfx::B2DHomMatrix& rObjectTransform,
171 : : const attribute::SdrTextAttribute& rText,
172 : : const attribute::SdrLineAttribute& rStroke,
173 : : bool bCellText,
174 : : bool bWordWrap,
175 : : bool bClipOnBounds)
176 : : {
177 [ + - ]: 13465 : basegfx::B2DHomMatrix aAnchorTransform(rObjectTransform);
178 : 13465 : SdrTextPrimitive2D* pNew = 0;
179 : :
180 [ + - ][ - + ]: 13465 : if(rText.isContour())
181 : : {
182 : : // contour text
183 [ # # ][ # # ]: 0 : if(!rStroke.isDefault() && 0.0 != rStroke.getWidth())
[ # # ][ # # ]
[ # # ]
184 : : {
185 : : // take line width into account and shrink contour polygon accordingly
186 : : // decompose to get scale
187 : 0 : basegfx::B2DVector aScale, aTranslate;
188 : : double fRotate, fShearX;
189 [ # # ]: 0 : rObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
190 : :
191 : : // scale outline to object's size to allow growing with value relative to that size
192 : : // and also to keep aspect ratio
193 [ # # ]: 0 : basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon);
194 : : aScaledUnitPolyPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(
195 [ # # ][ # # ]: 0 : fabs(aScale.getX()), fabs(aScale.getY())));
[ # # ]
196 : :
197 : : // grow the polygon. To shrink, use negative value (half width)
198 [ # # ][ # # ]: 0 : aScaledUnitPolyPolygon = basegfx::tools::growInNormalDirection(aScaledUnitPolyPolygon, -(rStroke.getWidth() * 0.5));
[ # # ][ # # ]
199 : :
200 : : // scale back to unit polygon
201 : : aScaledUnitPolyPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(
202 : 0 : 0.0 != aScale.getX() ? 1.0 / aScale.getX() : 1.0,
203 [ # # ][ # # ]: 0 : 0.0 != aScale.getY() ? 1.0 / aScale.getY() : 1.0));
[ # # ][ # # ]
[ # # ]
204 : :
205 : : // create with unit polygon
206 : : pNew = new SdrContourTextPrimitive2D(
207 : : &rText.getSdrText(),
208 : : rText.getOutlinerParaObject(),
209 : : aScaledUnitPolyPolygon,
210 [ # # ][ # # ]: 0 : rObjectTransform);
[ # # ][ # # ]
211 : : }
212 : : else
213 : : {
214 : : // create with unit polygon
215 : : pNew = new SdrContourTextPrimitive2D(
216 : : &rText.getSdrText(),
217 : : rText.getOutlinerParaObject(),
218 : : rUnitPolyPolygon,
219 [ # # ][ # # ]: 0 : rObjectTransform);
[ # # ]
220 : : }
221 : : }
222 [ + - ][ + - ]: 13465 : else if(!rText.getSdrFormTextAttribute().isDefault())
[ - + ]
223 : : {
224 : : // text on path, use scaled polygon
225 [ # # ]: 0 : basegfx::B2DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon);
226 [ # # ]: 0 : aScaledPolyPolygon.transform(rObjectTransform);
227 : : pNew = new SdrPathTextPrimitive2D(
228 : : &rText.getSdrText(),
229 : : rText.getOutlinerParaObject(),
230 : : aScaledPolyPolygon,
231 [ # # ][ # # ]: 0 : rText.getSdrFormTextAttribute());
[ # # ][ # # ]
[ # # ]
232 : : }
233 : : else
234 : : {
235 : : // rObjectTransform is the whole SdrObject transformation from unit rectangle
236 : : // to it's size and position. Decompose to allow working with single values.
237 : 13465 : basegfx::B2DVector aScale, aTranslate;
238 : : double fRotate, fShearX;
239 [ + - ]: 13465 : rObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX);
240 : :
241 : : // extract mirroring
242 : 13465 : const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
243 : 13465 : const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
244 [ + - ]: 13465 : aScale = basegfx::absolute(aScale);
245 : :
246 : : // Get the real size, since polygon ountline and scale
247 : : // from the object transformation may vary (e.g. ellipse segments)
248 [ + - ]: 13465 : basegfx::B2DHomMatrix aJustScaleTransform;
249 [ + - ]: 13465 : aJustScaleTransform.set(0, 0, aScale.getX());
250 [ + - ]: 13465 : aJustScaleTransform.set(1, 1, aScale.getY());
251 [ + - ]: 13465 : basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon);
252 [ + - ]: 13465 : aScaledUnitPolyPolygon.transform(aJustScaleTransform);
253 [ + - ]: 13465 : const basegfx::B2DRange aSnapRange(basegfx::tools::getRange(aScaledUnitPolyPolygon));
254 : :
255 : : // create a range describing the wanted text position and size (aTextAnchorRange). This
256 : : // means to use the text distance values here
257 [ + - ][ + - ]: 13465 : const basegfx::B2DPoint aTopLeft(aSnapRange.getMinX() + rText.getTextLeftDistance(), aSnapRange.getMinY() + rText.getTextUpperDistance());
[ + - ][ + - ]
258 [ + - ][ + - ]: 13465 : const basegfx::B2DPoint aBottomRight(aSnapRange.getMaxX() - rText.getTextRightDistance(), aSnapRange.getMaxY() - rText.getTextLowerDistance());
[ + - ][ + - ]
259 [ + - ]: 13465 : basegfx::B2DRange aTextAnchorRange;
260 [ + - ]: 13465 : aTextAnchorRange.expand(aTopLeft);
261 [ + - ]: 13465 : aTextAnchorRange.expand(aBottomRight);
262 : :
263 : : // now create a transformation from this basic range (aTextAnchorRange)
264 : : aAnchorTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
265 : : aTextAnchorRange.getWidth(), aTextAnchorRange.getHeight(),
266 [ + - ][ + - ]: 13465 : aTextAnchorRange.getMinX(), aTextAnchorRange.getMinY());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
267 : :
268 : : // apply mirroring
269 [ - + ][ - + ]: 13465 : aAnchorTransform.scale(bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0);
[ + - ]
270 : :
271 : : // apply object's other transforms
272 : : aAnchorTransform = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(fShearX, fRotate, aTranslate)
273 [ + - ][ + - ]: 13465 : * aAnchorTransform;
[ + - ][ + - ]
[ + - ]
274 : :
275 [ + - ][ - + ]: 13465 : if(rText.isFitToSize())
276 : : {
277 : : // streched text in range
278 : : pNew = new SdrStretchTextPrimitive2D(
279 : : &rText.getSdrText(),
280 : : rText.getOutlinerParaObject(),
281 : : aAnchorTransform,
282 [ # # ][ # # ]: 0 : rText.isFixedCellHeight());
[ # # ][ # # ]
283 : : }
284 [ + - ][ + + ]: 13465 : else if(rText.isAutoFit())
285 : : {
286 : : // isotrophically scaled text in range
287 [ + - ][ + - ]: 29 : pNew = new SdrAutoFitTextPrimitive2D(&rText.getSdrText(), rText.getOutlinerParaObject(), aAnchorTransform, bWordWrap);
[ + - ]
288 : : }
289 : : else // text in range
290 : : {
291 : : // build new primitive
292 : : pNew = new SdrBlockTextPrimitive2D(
293 : : &rText.getSdrText(),
294 : : rText.getOutlinerParaObject(),
295 : : aAnchorTransform,
296 : : rText.getSdrTextHorzAdjust(),
297 : : rText.getSdrTextVertAdjust(),
298 [ + - ]: 13436 : rText.isFixedCellHeight(),
299 [ + - ]: 13436 : rText.isScroll(),
300 : : bCellText,
301 : : bWordWrap,
302 [ + - ][ + - ]: 26872 : bClipOnBounds);
[ + - ][ + - ]
[ + - ]
303 [ + - ][ + - ]: 13465 : }
304 : : }
305 : :
306 : : OSL_ENSURE(pNew != 0, "createTextPrimitive: no text primitive created (!)");
307 : :
308 [ + - ][ - + ]: 13465 : if(rText.isBlink())
309 : : {
310 : : // prepare animation and primitive list
311 [ # # ]: 0 : drawinglayer::animation::AnimationEntryList aAnimationList;
312 [ # # ]: 0 : rText.getBlinkTextTiming(aAnimationList);
313 : :
314 [ # # ][ # # ]: 0 : if(0.0 != aAnimationList.getDuration())
315 : : {
316 : : // create content sequence
317 [ # # ][ # # ]: 0 : const Primitive2DReference xRefA(pNew);
318 [ # # ]: 0 : const Primitive2DSequence aContent(&xRefA, 1L);
319 : :
320 : : // create and add animated switch primitive
321 [ # # ][ # # ]: 0 : return Primitive2DReference(new AnimatedBlinkPrimitive2D(aAnimationList, aContent, true));
[ # # ][ # # ]
322 : : }
323 : : else
324 : : {
325 : : // add to decomposition
326 [ # # ][ # # ]: 0 : return Primitive2DReference(pNew);
327 [ # # ]: 0 : }
328 : : }
329 : :
330 [ + - ][ - + ]: 13465 : if(rText.isScroll())
331 : : {
332 : : // suppress scroll when FontWork
333 [ # # ][ # # ]: 0 : if(rText.getSdrFormTextAttribute().isDefault())
[ # # ]
334 : : {
335 : : // get scroll direction
336 [ # # ][ # # ]: 0 : const SdrTextAniDirection eDirection(rText.getSdrText().GetObject().GetTextAniDirection());
337 [ # # ][ # # ]: 0 : const bool bHorizontal(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection);
338 : :
339 : : // decompose to get separated values for the scroll box
340 : 0 : basegfx::B2DVector aScale, aTranslate;
341 : : double fRotate, fShearX;
342 [ # # ]: 0 : aAnchorTransform.decompose(aScale, aTranslate, fRotate, fShearX);
343 : :
344 : : // build transform from scaled only to full AnchorTransform and inverse
345 : : const basegfx::B2DHomMatrix aSRT(basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
346 [ # # ]: 0 : fShearX, fRotate, aTranslate));
347 [ # # ]: 0 : basegfx::B2DHomMatrix aISRT(aSRT);
348 [ # # ]: 0 : aISRT.invert();
349 : :
350 : : // bring the primitive back to scaled only and get scaled range, create new clone for this
351 [ # # ]: 0 : SdrTextPrimitive2D* pNew2 = pNew->createTransformedClone(aISRT);
352 : : OSL_ENSURE(pNew2, "createTextPrimitive: Could not create transformed clone of text primitive (!)");
353 [ # # ][ # # ]: 0 : delete pNew;
354 : 0 : pNew = pNew2;
355 : :
356 : : // create neutral geometry::ViewInformation2D for local range and decompose calls. This is okay
357 : : // since the decompose is view-independent
358 [ # # ]: 0 : const uno::Sequence< beans::PropertyValue > xViewParameters;
359 [ # # ]: 0 : geometry::ViewInformation2D aViewInformation2D(xViewParameters);
360 : :
361 : : // get range
362 [ # # ]: 0 : const basegfx::B2DRange aScaledRange(pNew->getB2DRange(aViewInformation2D));
363 : :
364 : : // create left outside and right outside transformations. Also take care
365 : : // of the clip rectangle
366 [ # # ][ # # ]: 0 : basegfx::B2DHomMatrix aLeft, aRight;
367 : 0 : basegfx::B2DPoint aClipTopLeft(0.0, 0.0);
368 : 0 : basegfx::B2DPoint aClipBottomRight(aScale.getX(), aScale.getY());
369 : :
370 [ # # ]: 0 : if(bHorizontal)
371 : : {
372 [ # # ]: 0 : aClipTopLeft.setY(aScaledRange.getMinY());
373 [ # # ]: 0 : aClipBottomRight.setY(aScaledRange.getMaxY());
374 [ # # ][ # # ]: 0 : aLeft.translate(-aScaledRange.getMaxX(), 0.0);
375 [ # # ][ # # ]: 0 : aRight.translate(aScale.getX() - aScaledRange.getMinX(), 0.0);
376 : : }
377 : : else
378 : : {
379 [ # # ]: 0 : aClipTopLeft.setX(aScaledRange.getMinX());
380 [ # # ]: 0 : aClipBottomRight.setX(aScaledRange.getMaxX());
381 [ # # ][ # # ]: 0 : aLeft.translate(0.0, -aScaledRange.getMaxY());
382 [ # # ][ # # ]: 0 : aRight.translate(0.0, aScale.getY() - aScaledRange.getMinY());
383 : : }
384 : :
385 [ # # ]: 0 : aLeft *= aSRT;
386 [ # # ]: 0 : aRight *= aSRT;
387 : :
388 : : // prepare animation list
389 [ # # ]: 0 : drawinglayer::animation::AnimationEntryList aAnimationList;
390 : :
391 [ # # ]: 0 : if(bHorizontal)
392 : : {
393 [ # # ][ # # ]: 0 : rText.getScrollTextTiming(aAnimationList, aScale.getX(), aScaledRange.getWidth());
394 : : }
395 : : else
396 : : {
397 [ # # ][ # # ]: 0 : rText.getScrollTextTiming(aAnimationList, aScale.getY(), aScaledRange.getHeight());
398 : : }
399 : :
400 [ # # ][ # # ]: 0 : if(0.0 != aAnimationList.getDuration())
401 : : {
402 : : // create a new Primitive2DSequence containing the animated text in it's scaled only state.
403 : : // use the decomposition to force to simple text primitives, those will no longer
404 : : // need the outliner for formatting (alternatively it is also possible to just add
405 : : // pNew to aNewPrimitiveSequence)
406 [ # # ]: 0 : Primitive2DSequence aAnimSequence(pNew->get2DDecomposition(aViewInformation2D));
407 [ # # ][ # # ]: 0 : delete pNew;
408 : :
409 : : // create a new animatedInterpolatePrimitive and add it
410 [ # # ]: 0 : std::vector< basegfx::B2DHomMatrix > aMatrixStack;
411 [ # # ]: 0 : aMatrixStack.push_back(aLeft);
412 [ # # ]: 0 : aMatrixStack.push_back(aRight);
413 [ # # ][ # # ]: 0 : const Primitive2DReference xRefA(new AnimatedInterpolatePrimitive2D(aMatrixStack, aAnimationList, aAnimSequence, true));
[ # # ]
414 [ # # ]: 0 : const Primitive2DSequence aContent(&xRefA, 1L);
415 : :
416 : : // scrolling needs an encapsulating clipping primitive
417 [ # # ]: 0 : const basegfx::B2DRange aClipRange(aClipTopLeft, aClipBottomRight);
418 [ # # ]: 0 : basegfx::B2DPolygon aClipPolygon(basegfx::tools::createPolygonFromRect(aClipRange));
419 [ # # ]: 0 : aClipPolygon.transform(aSRT);
420 [ # # ][ # # ]: 0 : return Primitive2DReference(new MaskPrimitive2D(basegfx::B2DPolyPolygon(aClipPolygon), aContent));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
421 : : }
422 : : else
423 : : {
424 : : // add to decomposition
425 [ # # ][ # # ]: 0 : return Primitive2DReference(pNew);
426 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
427 : : }
428 : : }
429 : :
430 [ + - ][ - + ]: 13465 : if(rText.isInEditMode())
431 : : {
432 : : // #i97628#
433 : : // encapsulate with TextHierarchyEditPrimitive2D to allow renderers
434 : : // to suppress actively edited content if needed
435 [ # # ][ # # ]: 0 : const Primitive2DReference xRefA(pNew);
436 [ # # ]: 0 : const Primitive2DSequence aContent(&xRefA, 1L);
437 : :
438 : : // create and add TextHierarchyEditPrimitive2D primitive
439 [ # # ][ # # ]: 0 : return Primitive2DReference(new TextHierarchyEditPrimitive2D(aContent));
[ # # ][ # # ]
440 : : }
441 : : else
442 : : {
443 : : // add to decomposition
444 [ + - ][ + - ]: 13465 : return Primitive2DReference(pNew);
445 [ + - ]: 13465 : }
446 : : }
447 : :
448 : 0 : Primitive2DSequence createEmbeddedShadowPrimitive(
449 : : const Primitive2DSequence& rContent,
450 : : const attribute::SdrShadowAttribute& rShadow)
451 : : {
452 [ # # ]: 0 : if(rContent.hasElements())
453 : : {
454 [ # # ]: 0 : Primitive2DSequence aRetval(2);
455 [ # # ]: 0 : basegfx::B2DHomMatrix aShadowOffset;
456 : :
457 : : // prepare shadow offset
458 [ # # ][ # # ]: 0 : aShadowOffset.set(0, 2, rShadow.getOffset().getX());
459 [ # # ][ # # ]: 0 : aShadowOffset.set(1, 2, rShadow.getOffset().getY());
460 : :
461 : : // create shadow primitive and add content
462 [ # # ]: 0 : aRetval[0] = Primitive2DReference(
463 : : new ShadowPrimitive2D(
464 : : aShadowOffset,
465 : : rShadow.getColor(),
466 [ # # ][ # # ]: 0 : rContent));
[ # # ][ # # ]
[ # # ]
467 : :
468 [ # # ][ # # ]: 0 : if(0.0 != rShadow.getTransparence())
469 : : {
470 : : // create SimpleTransparencePrimitive2D
471 [ # # ][ # # ]: 0 : const Primitive2DSequence aTempContent(&aRetval[0], 1);
472 : :
473 [ # # ]: 0 : aRetval[0] = Primitive2DReference(
474 : : new UnifiedTransparencePrimitive2D(
475 : : aTempContent,
476 [ # # ][ # # ]: 0 : rShadow.getTransparence()));
[ # # ][ # # ]
[ # # ][ # # ]
477 : : }
478 : :
479 [ # # ][ # # ]: 0 : aRetval[1] = Primitive2DReference(new GroupPrimitive2D(rContent));
[ # # ][ # # ]
[ # # ]
480 [ # # ][ # # ]: 0 : return aRetval;
[ # # ]
481 : : }
482 : : else
483 : : {
484 : 0 : return rContent;
485 : : }
486 : : }
487 : : } // end of namespace primitive2d
488 : : } // end of namespace drawinglayer
489 : :
490 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|