Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sdr/primitive2d/sdrtextprimitive2d.hxx>
21 : #include <svx/svdotext.hxx>
22 : #include <basegfx/color/bcolor.hxx>
23 : #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
24 : #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx>
25 : #include <editeng/outlobj.hxx>
26 : #include <editeng/editobj.hxx>
27 : #include <editeng/flditem.hxx>
28 : #include <drawinglayer/geometry/viewinformation2d.hxx>
29 : #include <svx/unoapi.hxx>
30 : #include <svx/svdpage.hxx>
31 : #include <svx/svdmodel.hxx>
32 : #include <svx/svdoutl.hxx>
33 : #include <com/sun/star/beans/XPropertySet.hpp>
34 :
35 :
36 :
37 : using namespace com::sun::star;
38 :
39 :
40 :
41 : namespace
42 : {
43 406 : sal_Int16 getPageNumber(const uno::Reference< drawing::XDrawPage >& rxDrawPage)
44 : {
45 406 : sal_Int16 nRetval(0);
46 406 : uno::Reference< beans::XPropertySet > xSet(rxDrawPage, uno::UNO_QUERY);
47 :
48 406 : if (xSet.is())
49 : {
50 : try
51 : {
52 4 : const uno::Any aNumber(xSet->getPropertyValue("Number"));
53 4 : aNumber >>= nRetval;
54 : }
55 0 : catch(const uno::Exception&)
56 : {
57 : OSL_ASSERT(false);
58 : }
59 : }
60 :
61 406 : return nRetval;
62 : }
63 :
64 0 : sal_Int16 getPageCount(const uno::Reference< drawing::XDrawPage >& rxDrawPage)
65 : {
66 0 : sal_Int16 nRetval(0);
67 0 : SdrPage* pPage = GetSdrPageFromXDrawPage(rxDrawPage);
68 :
69 0 : if(pPage && pPage->GetModel())
70 : {
71 0 : if( (pPage->GetPageNum() == 0) && !pPage->IsMasterPage() )
72 : {
73 : // handout page!
74 0 : return pPage->GetModel()->getHandoutPageCount();
75 : }
76 : else
77 : {
78 0 : const sal_uInt16 nPageCount(pPage->GetModel()->GetPageCount());
79 0 : nRetval = ((sal_Int16)nPageCount - 1) / 2;
80 : }
81 : }
82 :
83 0 : return nRetval;
84 : }
85 : } // end of anonymous namespace
86 :
87 :
88 :
89 : namespace drawinglayer
90 : {
91 : namespace primitive2d
92 : {
93 : // support for XTEXT_PAINTSHAPE_BEGIN/XTEXT_PAINTSHAPE_END Metafile comments
94 : // for slideshow. This uses TextHierarchyBlockPrimitive2D to mark a text block.
95 : // ATM there is only one text block per SdrObject, this may get more in the future
96 17483 : Primitive2DSequence SdrTextPrimitive2D::encapsulateWithTextHierarchyBlockPrimitive2D(const Primitive2DSequence& rCandidate)
97 : {
98 17483 : Primitive2DReference xReference(new TextHierarchyBlockPrimitive2D(rCandidate));
99 17483 : Primitive2DSequence xRetval(&xReference, 1);
100 :
101 17483 : return xRetval;
102 : }
103 :
104 17213 : SdrTextPrimitive2D::SdrTextPrimitive2D(
105 : const SdrText* pSdrText,
106 : const OutlinerParaObject& rOutlinerParaObject)
107 : : BufferedDecompositionPrimitive2D(),
108 : mrSdrText(const_cast< SdrText* >(pSdrText)),
109 : maOutlinerParaObject(rOutlinerParaObject),
110 : mxLastVisualizingPage(),
111 : mnLastPageNumber(0),
112 : mnLastPageCount(0),
113 : maLastTextBackgroundColor(),
114 : mbContainsPageField(false),
115 : mbContainsPageCountField(false),
116 17213 : mbContainsOtherFields(false)
117 : {
118 17213 : const EditTextObject& rETO = maOutlinerParaObject.GetTextObject();
119 :
120 17213 : mbContainsPageField = rETO.HasField(SvxPageField::StaticClassId());
121 17213 : mbContainsPageCountField = rETO.HasField(SvxPagesField::StaticClassId());
122 17213 : mbContainsOtherFields = rETO.HasField(SvxHeaderField::StaticClassId())
123 16954 : || rETO.HasField(SvxFooterField::StaticClassId())
124 16532 : || rETO.HasField(SvxDateTimeField::StaticClassId())
125 33323 : || rETO.HasField(SvxAuthorField::StaticClassId());
126 17213 : }
127 :
128 0 : bool SdrTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
129 : {
130 0 : if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
131 : {
132 0 : const SdrTextPrimitive2D& rCompare = static_cast<const SdrTextPrimitive2D&>(rPrimitive);
133 :
134 : return (
135 :
136 : // compare OPO and content, but not WrongList
137 0 : getOutlinerParaObject() == rCompare.getOutlinerParaObject()
138 :
139 : // also compare WrongList (not-persistent data, but visualized)
140 0 : && getOutlinerParaObject().isWrongListEqual(rCompare.getOutlinerParaObject()));
141 : }
142 :
143 0 : return false;
144 : }
145 :
146 107295 : Primitive2DSequence SdrTextPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
147 : {
148 107295 : uno::Reference< drawing::XDrawPage > xCurrentlyVisualizingPage;
149 107295 : bool bCurrentlyVisualizingPageIsSet(false);
150 107295 : Color aNewTextBackgroundColor;
151 107295 : bool bNewTextBackgroundColorIsSet(false);
152 107295 : sal_Int16 nCurrentlyValidPageNumber(0);
153 107295 : sal_Int16 nCurrentlyValidPageCount(0);
154 :
155 107295 : if(getBuffered2DDecomposition().hasElements())
156 : {
157 90082 : bool bDoDelete(false);
158 :
159 : // check visualized page
160 90082 : if(mbContainsPageField || mbContainsPageCountField || mbContainsOtherFields)
161 : {
162 : // get visualized page and remember
163 778 : xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage();
164 778 : bCurrentlyVisualizingPageIsSet = true;
165 :
166 778 : if(xCurrentlyVisualizingPage != mxLastVisualizingPage)
167 : {
168 81 : bDoDelete = true;
169 : }
170 :
171 : // #i98870# check visualized PageNumber
172 778 : if(!bDoDelete && mbContainsPageField)
173 : {
174 3 : nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage);
175 :
176 3 : if(nCurrentlyValidPageNumber != mnLastPageNumber)
177 : {
178 0 : bDoDelete = true;
179 : }
180 : }
181 :
182 : // #i98870# check visualized PageCount, too
183 778 : if(!bDoDelete && mbContainsPageCountField)
184 : {
185 0 : nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage);
186 :
187 0 : if(nCurrentlyValidPageCount != mnLastPageCount)
188 : {
189 0 : bDoDelete = true;
190 : }
191 : }
192 : }
193 :
194 : // #i101443# check change of TextBackgroundolor
195 90082 : if(!bDoDelete && getSdrText() && getSdrText()->GetModel())
196 : {
197 85571 : SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0);
198 85571 : aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor();
199 85571 : bNewTextBackgroundColorIsSet = true;
200 :
201 85571 : if(aNewTextBackgroundColor != maLastTextBackgroundColor)
202 : {
203 189 : bDoDelete = true;
204 : }
205 : }
206 :
207 90082 : if(bDoDelete)
208 : {
209 270 : const_cast< SdrTextPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence());
210 : }
211 : }
212 :
213 107295 : if(!getBuffered2DDecomposition().hasElements())
214 : {
215 17483 : if(!bCurrentlyVisualizingPageIsSet && mbContainsPageField)
216 : {
217 402 : xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage();
218 : }
219 :
220 17483 : if(!nCurrentlyValidPageNumber && mbContainsPageField)
221 : {
222 403 : nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage);
223 : }
224 :
225 17483 : if(!nCurrentlyValidPageCount && mbContainsPageCountField)
226 : {
227 0 : nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage);
228 : }
229 :
230 17483 : if(!bNewTextBackgroundColorIsSet && getSdrText() && getSdrText()->GetModel())
231 : {
232 17294 : SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0);
233 17294 : aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor();
234 : }
235 :
236 17483 : const_cast< SdrTextPrimitive2D* >(this)->mxLastVisualizingPage = xCurrentlyVisualizingPage;
237 17483 : const_cast< SdrTextPrimitive2D* >(this)->mnLastPageNumber = nCurrentlyValidPageNumber;
238 17483 : const_cast< SdrTextPrimitive2D* >(this)->mnLastPageCount = nCurrentlyValidPageCount;
239 17483 : const_cast< SdrTextPrimitive2D* >(this)->maLastTextBackgroundColor = aNewTextBackgroundColor;
240 : }
241 :
242 : // call parent
243 107295 : return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
244 : }
245 : } // end of namespace primitive2d
246 : } // end of namespace drawinglayer
247 :
248 :
249 :
250 : namespace drawinglayer
251 : {
252 : namespace primitive2d
253 : {
254 0 : Primitive2DSequence SdrContourTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const
255 : {
256 0 : Primitive2DSequence aRetval;
257 0 : getSdrText()->GetObject().impDecomposeContourTextPrimitive(aRetval, *this, aViewInformation);
258 :
259 0 : return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval);
260 : }
261 :
262 0 : SdrContourTextPrimitive2D::SdrContourTextPrimitive2D(
263 : const SdrText* pSdrText,
264 : const OutlinerParaObject& rOutlinerParaObject,
265 : const basegfx::B2DPolyPolygon& rUnitPolyPolygon,
266 : const basegfx::B2DHomMatrix& rObjectTransform)
267 : : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject),
268 : maUnitPolyPolygon(rUnitPolyPolygon),
269 0 : maObjectTransform(rObjectTransform)
270 : {
271 0 : }
272 :
273 0 : bool SdrContourTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
274 : {
275 0 : if(SdrTextPrimitive2D::operator==(rPrimitive))
276 : {
277 0 : const SdrContourTextPrimitive2D& rCompare = static_cast<const SdrContourTextPrimitive2D&>(rPrimitive);
278 :
279 0 : return (getUnitPolyPolygon() == rCompare.getUnitPolyPolygon()
280 0 : && getObjectTransform() == rCompare.getObjectTransform());
281 : }
282 :
283 0 : return false;
284 : }
285 :
286 0 : SdrTextPrimitive2D* SdrContourTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const
287 : {
288 : return new SdrContourTextPrimitive2D(
289 0 : getSdrText(),
290 0 : getOutlinerParaObject(),
291 : getUnitPolyPolygon(),
292 0 : rTransform * getObjectTransform());
293 : }
294 :
295 : // provide unique ID
296 0 : ImplPrimitive2DIDBlock(SdrContourTextPrimitive2D, PRIMITIVE2D_ID_SDRCONTOURTEXTPRIMITIVE2D)
297 :
298 : } // end of namespace primitive2d
299 : } // end of namespace drawinglayer
300 :
301 :
302 :
303 : namespace drawinglayer
304 : {
305 : namespace primitive2d
306 : {
307 0 : Primitive2DSequence SdrPathTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const
308 : {
309 0 : Primitive2DSequence aRetval;
310 0 : getSdrText()->GetObject().impDecomposePathTextPrimitive(aRetval, *this, aViewInformation);
311 :
312 0 : return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval);
313 : }
314 :
315 0 : SdrPathTextPrimitive2D::SdrPathTextPrimitive2D(
316 : const SdrText* pSdrText,
317 : const OutlinerParaObject& rOutlinerParaObject,
318 : const basegfx::B2DPolyPolygon& rPathPolyPolygon,
319 : const attribute::SdrFormTextAttribute& rSdrFormTextAttribute)
320 : : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject),
321 : maPathPolyPolygon(rPathPolyPolygon),
322 0 : maSdrFormTextAttribute(rSdrFormTextAttribute)
323 : {
324 0 : }
325 :
326 0 : bool SdrPathTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
327 : {
328 0 : if(SdrTextPrimitive2D::operator==(rPrimitive))
329 : {
330 0 : const SdrPathTextPrimitive2D& rCompare = static_cast<const SdrPathTextPrimitive2D&>(rPrimitive);
331 :
332 0 : return (getPathPolyPolygon() == rCompare.getPathPolyPolygon()
333 0 : && getSdrFormTextAttribute() == rCompare.getSdrFormTextAttribute());
334 : }
335 :
336 0 : return false;
337 : }
338 :
339 0 : SdrTextPrimitive2D* SdrPathTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const
340 : {
341 0 : basegfx::B2DPolyPolygon aNewPolyPolygon(getPathPolyPolygon());
342 0 : aNewPolyPolygon.transform(rTransform);
343 :
344 : return new SdrPathTextPrimitive2D(
345 0 : getSdrText(),
346 0 : getOutlinerParaObject(),
347 : aNewPolyPolygon,
348 0 : getSdrFormTextAttribute());
349 : }
350 :
351 : // provide unique ID
352 0 : ImplPrimitive2DIDBlock(SdrPathTextPrimitive2D, PRIMITIVE2D_ID_SDRPATHTEXTPRIMITIVE2D)
353 :
354 : } // end of namespace primitive2d
355 : } // end of namespace drawinglayer
356 :
357 :
358 :
359 : namespace drawinglayer
360 : {
361 : namespace primitive2d
362 : {
363 17412 : Primitive2DSequence SdrBlockTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const
364 : {
365 17412 : Primitive2DSequence aRetval;
366 17412 : getSdrText()->GetObject().impDecomposeBlockTextPrimitive(aRetval, *this, aViewInformation);
367 :
368 17412 : return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval);
369 : }
370 :
371 17145 : SdrBlockTextPrimitive2D::SdrBlockTextPrimitive2D(
372 : const SdrText* pSdrText,
373 : const OutlinerParaObject& rOutlinerParaObject,
374 : const basegfx::B2DHomMatrix& rTextRangeTransform,
375 : SdrTextHorzAdjust aSdrTextHorzAdjust,
376 : SdrTextVertAdjust aSdrTextVertAdjust,
377 : bool bFixedCellHeight,
378 : bool bUnlimitedPage,
379 : bool bCellText,
380 : bool bWordWrap,
381 : bool bClipOnBounds)
382 : : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject),
383 : maTextRangeTransform(rTextRangeTransform),
384 : maSdrTextHorzAdjust(aSdrTextHorzAdjust),
385 : maSdrTextVertAdjust(aSdrTextVertAdjust),
386 : mbFixedCellHeight(bFixedCellHeight),
387 : mbUnlimitedPage(bUnlimitedPage),
388 : mbCellText(bCellText),
389 : mbWordWrap(bWordWrap),
390 17145 : mbClipOnBounds(bClipOnBounds)
391 : {
392 17145 : }
393 :
394 0 : bool SdrBlockTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
395 : {
396 0 : if(SdrTextPrimitive2D::operator==(rPrimitive))
397 : {
398 0 : const SdrBlockTextPrimitive2D& rCompare = static_cast<const SdrBlockTextPrimitive2D&>(rPrimitive);
399 :
400 0 : return (getTextRangeTransform() == rCompare.getTextRangeTransform()
401 0 : && getSdrTextHorzAdjust() == rCompare.getSdrTextHorzAdjust()
402 0 : && getSdrTextVertAdjust() == rCompare.getSdrTextVertAdjust()
403 0 : && isFixedCellHeight() == rCompare.isFixedCellHeight()
404 0 : && getUnlimitedPage() == rCompare.getUnlimitedPage()
405 0 : && getCellText() == rCompare.getCellText()
406 0 : && getWordWrap() == rCompare.getWordWrap()
407 0 : && getClipOnBounds() == rCompare.getClipOnBounds());
408 : }
409 :
410 0 : return false;
411 : }
412 :
413 13 : SdrTextPrimitive2D* SdrBlockTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const
414 : {
415 : return new SdrBlockTextPrimitive2D(
416 13 : getSdrText(),
417 13 : getOutlinerParaObject(),
418 26 : rTransform * getTextRangeTransform(),
419 : getSdrTextHorzAdjust(),
420 : getSdrTextVertAdjust(),
421 13 : isFixedCellHeight(),
422 13 : getUnlimitedPage(),
423 13 : getCellText(),
424 13 : getWordWrap(),
425 104 : getClipOnBounds());
426 : }
427 :
428 : // provide unique ID
429 20281 : ImplPrimitive2DIDBlock(SdrBlockTextPrimitive2D, PRIMITIVE2D_ID_SDRBLOCKTEXTPRIMITIVE2D)
430 :
431 : } // end of namespace primitive2d
432 : } // end of namespace drawinglayer
433 :
434 :
435 :
436 : namespace drawinglayer
437 : {
438 : namespace primitive2d
439 : {
440 71 : Primitive2DSequence SdrAutoFitTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const
441 : {
442 71 : Primitive2DSequence aRetval;
443 71 : getSdrText()->GetObject().impDecomposeAutoFitTextPrimitive(aRetval, *this, aViewInformation);
444 :
445 71 : return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval);
446 : }
447 :
448 68 : SdrAutoFitTextPrimitive2D::SdrAutoFitTextPrimitive2D(
449 : const SdrText* pSdrText,
450 : const OutlinerParaObject& rParaObj,
451 : const ::basegfx::B2DHomMatrix& rTextRangeTransform,
452 : bool bWordWrap)
453 : : SdrTextPrimitive2D(pSdrText, rParaObj),
454 : maTextRangeTransform(rTextRangeTransform),
455 68 : mbWordWrap(bWordWrap)
456 : {
457 68 : }
458 :
459 0 : bool SdrAutoFitTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
460 : {
461 0 : if(SdrTextPrimitive2D::operator==(rPrimitive))
462 : {
463 0 : const SdrBlockTextPrimitive2D& rCompare = static_cast<const SdrBlockTextPrimitive2D&>(rPrimitive);
464 :
465 0 : return (getTextRangeTransform() == rCompare.getTextRangeTransform()
466 0 : && getWordWrap() == rCompare.getWordWrap());
467 : }
468 :
469 0 : return false;
470 : }
471 :
472 0 : SdrTextPrimitive2D* SdrAutoFitTextPrimitive2D::createTransformedClone(const ::basegfx::B2DHomMatrix& rTransform) const
473 : {
474 0 : return new SdrAutoFitTextPrimitive2D(getSdrText(), getOutlinerParaObject(), rTransform * getTextRangeTransform(), getWordWrap());
475 : }
476 :
477 : // provide unique ID
478 8 : ImplPrimitive2DIDBlock(SdrAutoFitTextPrimitive2D, PRIMITIVE2D_ID_SDRAUTOFITTEXTPRIMITIVE2D)
479 :
480 : } // end of namespace primitive2d
481 : } // end of namespace drawinglayer
482 :
483 :
484 :
485 : namespace drawinglayer
486 : {
487 : namespace primitive2d
488 : {
489 0 : Primitive2DSequence SdrStretchTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const
490 : {
491 0 : Primitive2DSequence aRetval;
492 0 : getSdrText()->GetObject().impDecomposeStretchTextPrimitive(aRetval, *this, aViewInformation);
493 :
494 0 : return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval);
495 : }
496 :
497 0 : SdrStretchTextPrimitive2D::SdrStretchTextPrimitive2D(
498 : const SdrText* pSdrText,
499 : const OutlinerParaObject& rOutlinerParaObject,
500 : const basegfx::B2DHomMatrix& rTextRangeTransform,
501 : bool bFixedCellHeight)
502 : : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject),
503 : maTextRangeTransform(rTextRangeTransform),
504 0 : mbFixedCellHeight(bFixedCellHeight)
505 : {
506 0 : }
507 :
508 0 : bool SdrStretchTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
509 : {
510 0 : if(SdrTextPrimitive2D::operator==(rPrimitive))
511 : {
512 0 : const SdrStretchTextPrimitive2D& rCompare = static_cast<const SdrStretchTextPrimitive2D&>(rPrimitive);
513 :
514 0 : return (getTextRangeTransform() == rCompare.getTextRangeTransform()
515 0 : && isFixedCellHeight() == rCompare.isFixedCellHeight());
516 : }
517 :
518 0 : return false;
519 : }
520 :
521 0 : SdrTextPrimitive2D* SdrStretchTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const
522 : {
523 : return new SdrStretchTextPrimitive2D(
524 0 : getSdrText(),
525 0 : getOutlinerParaObject(),
526 0 : rTransform * getTextRangeTransform(),
527 0 : isFixedCellHeight());
528 : }
529 :
530 : // provide unique ID
531 0 : ImplPrimitive2DIDBlock(SdrStretchTextPrimitive2D, PRIMITIVE2D_ID_SDRSTRETCHTEXTPRIMITIVE2D)
532 :
533 : } // end of namespace primitive2d
534 435 : } // end of namespace drawinglayer
535 :
536 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|