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