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 
21 #include <sdr/attribute/sdrtextattribute.hxx>
22 #include <sdr/attribute/sdrformtextattribute.hxx>
23 #include <svx/svdotext.hxx>
24 #include <editeng/outlobj.hxx>
25 #include <svx/sdr/properties/properties.hxx>
26 #include <rtl/instance.hxx>
27 
28 
29 namespace drawinglayer::attribute
30 {
31         class ImpSdrTextAttribute
32         {
33         public:
34             // all-text attributes. The SdrText itself and a copy
35             // of the OPO
36             const SdrText*                      mpSdrText;
37             std::shared_ptr<OutlinerParaObject> mxOutlinerParaObject;
38 
39             // Set when it's a FormText; contains all FormText attributes
40             SdrFormTextAttribute                maSdrFormTextAttribute;
41 
42             // text distances
43             sal_Int32                           maTextLeftDistance;
44             sal_Int32                           maTextUpperDistance;
45             sal_Int32                           maTextRightDistance;
46             sal_Int32                           maTextLowerDistance;
47 
48             // #i101556# use versioning from text attributes to detect changes
49             sal_uInt32                          maPropertiesVersion;
50 
51             // text alignments
52             SdrTextHorzAdjust                   maSdrTextHorzAdjust;
53             SdrTextVertAdjust                   maSdrTextVertAdjust;
54 
55             bool                                mbContour : 1;
56             bool                                mbFitToSize : 1;
57             bool                                mbAutoFit : 1;
58             bool                                mbHideContour : 1;
59             bool                                mbBlink : 1;
60             bool                                mbScroll : 1;
61             bool                                mbInEditMode : 1;
62             bool                                mbFixedCellHeight : 1;
63             bool                                mbWrongSpell : 1;
64 
65             bool                                mbChainable : 1;
66 
67 
68         public:
ImpSdrTextAttribute(const SdrText * pSdrText,const OutlinerParaObject & rOutlinerParaObject,XFormTextStyle eFormTextStyle,sal_Int32 aTextLeftDistance,sal_Int32 aTextUpperDistance,sal_Int32 aTextRightDistance,sal_Int32 aTextLowerDistance,SdrTextHorzAdjust aSdrTextHorzAdjust,SdrTextVertAdjust aSdrTextVertAdjust,bool bContour,bool bFitToSize,bool bAutoFit,bool bHideContour,bool bBlink,bool bScroll,bool bInEditMode,bool bFixedCellHeight,bool bWrongSpell,bool bChainable)69             ImpSdrTextAttribute(
70                 const SdrText* pSdrText,
71                 const OutlinerParaObject& rOutlinerParaObject,
72                 XFormTextStyle eFormTextStyle,
73                 sal_Int32 aTextLeftDistance,
74                 sal_Int32 aTextUpperDistance,
75                 sal_Int32 aTextRightDistance,
76                 sal_Int32 aTextLowerDistance,
77                 SdrTextHorzAdjust aSdrTextHorzAdjust,
78                 SdrTextVertAdjust aSdrTextVertAdjust,
79                 bool bContour,
80                 bool bFitToSize,
81                 bool bAutoFit,
82                 bool bHideContour,
83                 bool bBlink,
84                 bool bScroll,
85                 bool bInEditMode,
86                 bool bFixedCellHeight,
87                 bool bWrongSpell,
88                 bool bChainable)
89             :   mpSdrText(pSdrText),
90                 mxOutlinerParaObject(std::make_shared<OutlinerParaObject>(rOutlinerParaObject)),
91                 maSdrFormTextAttribute(),
92                 maTextLeftDistance(aTextLeftDistance),
93                 maTextUpperDistance(aTextUpperDistance),
94                 maTextRightDistance(aTextRightDistance),
95                 maTextLowerDistance(aTextLowerDistance),
96                 maPropertiesVersion(0),
97                 maSdrTextHorzAdjust(aSdrTextHorzAdjust),
98                 maSdrTextVertAdjust(aSdrTextVertAdjust),
99                 mbContour(bContour),
100                 mbFitToSize(bFitToSize),
101                 mbAutoFit(bAutoFit),
102                 mbHideContour(bHideContour),
103                 mbBlink(bBlink),
104                 mbScroll(bScroll),
105                 mbInEditMode(bInEditMode),
106                 mbFixedCellHeight(bFixedCellHeight),
107                 mbWrongSpell(bWrongSpell),
108                 mbChainable(bChainable)
109             {
110                 if(!pSdrText)
111                     return;
112 
113                 if(XFormTextStyle::NONE != eFormTextStyle)
114                 {
115                     // text on path. Create FormText attribute
116                     const SfxItemSet& rSet = pSdrText->GetItemSet();
117                     maSdrFormTextAttribute = SdrFormTextAttribute(rSet);
118                 }
119 
120                 // #i101556# init with version number to detect changes of single text
121                 // attribute and/or style sheets in primitive data without having to
122                 // copy that data locally (which would be better from principle)
123                 maPropertiesVersion = pSdrText->GetObject().GetProperties().getVersion();
124             }
125 
ImpSdrTextAttribute()126             ImpSdrTextAttribute()
127             :   mpSdrText(nullptr),
128                 maSdrFormTextAttribute(),
129                 maTextLeftDistance(0),
130                 maTextUpperDistance(0),
131                 maTextRightDistance(0),
132                 maTextLowerDistance(0),
133                 maPropertiesVersion(0),
134                 maSdrTextHorzAdjust(SDRTEXTHORZADJUST_LEFT),
135                 maSdrTextVertAdjust(SDRTEXTVERTADJUST_TOP),
136                 mbContour(false),
137                 mbFitToSize(false),
138                 mbAutoFit(false),
139                 mbHideContour(false),
140                 mbBlink(false),
141                 mbScroll(false),
142                 mbInEditMode(false),
143                 mbFixedCellHeight(false),
144                 mbWrongSpell(false),
145                 mbChainable(false)
146             {
147             }
148 
149             // data read access
getSdrText() const150             const SdrText& getSdrText() const
151             {
152                 assert(mpSdrText && "Access to text of default version of ImpSdrTextAttribute (!)");
153                 return *mpSdrText;
154             }
155 
getOutlinerParaObject() const156             const OutlinerParaObject& getOutlinerParaObject() const
157             {
158                 assert(mxOutlinerParaObject && "Access to OutlinerParaObject of default version of ImpSdrTextAttribute (!)");
159                 return *mxOutlinerParaObject;
160             }
161 
isContour() const162             bool isContour() const { return mbContour; }
isFitToSize() const163             bool isFitToSize() const { return mbFitToSize; }
isAutoFit() const164             bool isAutoFit() const { return mbAutoFit; }
isHideContour() const165             bool isHideContour() const { return mbHideContour; }
isBlink() const166             bool isBlink() const { return mbBlink; }
isScroll() const167             bool isScroll() const { return mbScroll; }
isInEditMode() const168             bool isInEditMode() const { return mbInEditMode; }
isFixedCellHeight() const169             bool isFixedCellHeight() const { return mbFixedCellHeight; }
isChainable() const170             bool isChainable() const { return mbChainable; }
getSdrFormTextAttribute() const171             const SdrFormTextAttribute& getSdrFormTextAttribute() const { return maSdrFormTextAttribute; }
getTextLeftDistance() const172             sal_Int32 getTextLeftDistance() const { return maTextLeftDistance; }
getTextUpperDistance() const173             sal_Int32 getTextUpperDistance() const { return maTextUpperDistance; }
getTextRightDistance() const174             sal_Int32 getTextRightDistance() const { return maTextRightDistance; }
getTextLowerDistance() const175             sal_Int32 getTextLowerDistance() const { return maTextLowerDistance; }
getSdrTextHorzAdjust() const176             SdrTextHorzAdjust getSdrTextHorzAdjust() const { return maSdrTextHorzAdjust; }
getSdrTextVertAdjust() const177             SdrTextVertAdjust getSdrTextVertAdjust() const { return maSdrTextVertAdjust; }
178 
179             // compare operator
operator ==(const ImpSdrTextAttribute & rCandidate) const180             bool operator==(const ImpSdrTextAttribute& rCandidate) const
181             {
182                 if (mxOutlinerParaObject.get() != rCandidate.mxOutlinerParaObject.get())
183                 {
184                     if (mxOutlinerParaObject && rCandidate.mxOutlinerParaObject)
185                     {
186                         // compares OPO and it's contents, but traditionally not the RedLining
187                         // which is not seen as model, but as temporary information
188                         if(!(getOutlinerParaObject() == rCandidate.getOutlinerParaObject()))
189                         {
190                             return false;
191                         }
192 
193                         // #i102062# for primitive visualisation, the WrongList (SpellChecking)
194                         // is important, too, so use isWrongListEqual since there is no WrongList
195                         // comparison in the regular OutlinerParaObject compare (since it's
196                         // not-persistent data)
197                         if(!(getOutlinerParaObject().isWrongListEqual(rCandidate.getOutlinerParaObject())))
198                         {
199                             return false;
200                         }
201                     }
202                     else
203                     {
204                         // only one is zero; not equal
205                         return false;
206                     }
207                 }
208 
209                 return (
210                        getSdrFormTextAttribute() == rCandidate.getSdrFormTextAttribute()
211                     && getTextLeftDistance() == rCandidate.getTextLeftDistance()
212                     && getTextUpperDistance() == rCandidate.getTextUpperDistance()
213                     && getTextRightDistance() == rCandidate.getTextRightDistance()
214                     && getTextLowerDistance() == rCandidate.getTextLowerDistance()
215                     && maPropertiesVersion == rCandidate.maPropertiesVersion
216 
217                     && getSdrTextHorzAdjust() == rCandidate.getSdrTextHorzAdjust()
218                     && getSdrTextVertAdjust() == rCandidate.getSdrTextVertAdjust()
219 
220                     && isContour() == rCandidate.isContour()
221                     && isFitToSize() == rCandidate.isFitToSize()
222                     && isAutoFit() == rCandidate.isAutoFit()
223                     && isHideContour() == rCandidate.isHideContour()
224                     && isBlink() == rCandidate.isBlink()
225                     && isScroll() == rCandidate.isScroll()
226                     && isInEditMode() == rCandidate.isInEditMode()
227                     && isFixedCellHeight() == rCandidate.isFixedCellHeight()
228                     && mbWrongSpell == rCandidate.mbWrongSpell );
229             }
230         };
231 
232         namespace
233         {
234             struct theGlobalDefault :
235                 public rtl::Static< SdrTextAttribute::ImplType, theGlobalDefault > {};
236         }
237 
SdrTextAttribute(const SdrText & rSdrText,const OutlinerParaObject & rOutlinerParaObject,XFormTextStyle eFormTextStyle,sal_Int32 aTextLeftDistance,sal_Int32 aTextUpperDistance,sal_Int32 aTextRightDistance,sal_Int32 aTextLowerDistance,SdrTextHorzAdjust aSdrTextHorzAdjust,SdrTextVertAdjust aSdrTextVertAdjust,bool bContour,bool bFitToSize,bool bAutoFit,bool bHideContour,bool bBlink,bool bScroll,bool bInEditMode,bool bFixedCellHeight,bool bWrongSpell,bool bChainable)238         SdrTextAttribute::SdrTextAttribute(
239             const SdrText& rSdrText,
240             const OutlinerParaObject& rOutlinerParaObject,
241             XFormTextStyle eFormTextStyle,
242             sal_Int32 aTextLeftDistance,
243             sal_Int32 aTextUpperDistance,
244             sal_Int32 aTextRightDistance,
245             sal_Int32 aTextLowerDistance,
246             SdrTextHorzAdjust aSdrTextHorzAdjust,
247             SdrTextVertAdjust aSdrTextVertAdjust,
248             bool bContour,
249             bool bFitToSize,
250             bool bAutoFit,
251             bool bHideContour,
252             bool bBlink,
253             bool bScroll,
254             bool bInEditMode,
255             bool bFixedCellHeight,
256             bool bWrongSpell,
257             bool bChainable)
258         :   mpSdrTextAttribute(
259                 ImpSdrTextAttribute(
260                     &rSdrText, rOutlinerParaObject, eFormTextStyle, aTextLeftDistance,
261                     aTextUpperDistance, aTextRightDistance, aTextLowerDistance,
262                     aSdrTextHorzAdjust, aSdrTextVertAdjust, bContour, bFitToSize, bAutoFit,
263                     bHideContour, bBlink, bScroll, bInEditMode, bFixedCellHeight, bWrongSpell,
264                     bChainable))
265         {
266         }
267 
SdrTextAttribute()268         SdrTextAttribute::SdrTextAttribute()
269             :   mpSdrTextAttribute(theGlobalDefault::get())
270         {
271         }
272 
SdrTextAttribute(const SdrTextAttribute & rCandidate)273         SdrTextAttribute::SdrTextAttribute(const SdrTextAttribute& rCandidate)
274         :   mpSdrTextAttribute(rCandidate.mpSdrTextAttribute)
275         {
276         }
277 
SdrTextAttribute(SdrTextAttribute && rCandidate)278         SdrTextAttribute::SdrTextAttribute(SdrTextAttribute&& rCandidate) noexcept
279         :   mpSdrTextAttribute(std::move(rCandidate.mpSdrTextAttribute))
280         {
281         }
282 
~SdrTextAttribute()283         SdrTextAttribute::~SdrTextAttribute()
284         {
285         }
286 
isDefault() const287         bool SdrTextAttribute::isDefault() const
288         {
289             return mpSdrTextAttribute.same_object(theGlobalDefault::get());
290         }
291 
operator =(const SdrTextAttribute & rCandidate)292         SdrTextAttribute& SdrTextAttribute::operator=(const SdrTextAttribute& rCandidate)
293         {
294             mpSdrTextAttribute = rCandidate.mpSdrTextAttribute;
295             return *this;
296         }
297 
operator =(SdrTextAttribute && rCandidate)298         SdrTextAttribute& SdrTextAttribute::operator=(SdrTextAttribute&& rCandidate) noexcept
299         {
300             mpSdrTextAttribute = std::move(rCandidate.mpSdrTextAttribute);
301             return *this;
302         }
303 
operator ==(const SdrTextAttribute & rCandidate) const304         bool SdrTextAttribute::operator==(const SdrTextAttribute& rCandidate) const
305         {
306             // tdf#87509 default attr is always != non-default attr, even with same values
307             if(rCandidate.isDefault() != isDefault())
308                 return false;
309 
310             return rCandidate.mpSdrTextAttribute == mpSdrTextAttribute;
311         }
312 
getSdrText() const313         const SdrText& SdrTextAttribute::getSdrText() const
314         {
315             return mpSdrTextAttribute->getSdrText();
316         }
317 
getOutlinerParaObject() const318         const OutlinerParaObject& SdrTextAttribute::getOutlinerParaObject() const
319         {
320             return mpSdrTextAttribute->getOutlinerParaObject();
321         }
322 
isContour() const323         bool SdrTextAttribute::isContour() const
324         {
325             return mpSdrTextAttribute->isContour();
326         }
327 
isFitToSize() const328         bool SdrTextAttribute::isFitToSize() const
329         {
330             return mpSdrTextAttribute->isFitToSize();
331         }
332 
isAutoFit() const333         bool SdrTextAttribute::isAutoFit() const
334         {
335             return mpSdrTextAttribute->isAutoFit();
336         }
337 
isHideContour() const338         bool SdrTextAttribute::isHideContour() const
339         {
340             return mpSdrTextAttribute->isHideContour();
341         }
342 
isBlink() const343         bool SdrTextAttribute::isBlink() const
344         {
345             return mpSdrTextAttribute->isBlink();
346         }
347 
isScroll() const348         bool SdrTextAttribute::isScroll() const
349         {
350             return mpSdrTextAttribute->isScroll();
351         }
352 
isInEditMode() const353         bool SdrTextAttribute::isInEditMode() const
354         {
355             return mpSdrTextAttribute->isInEditMode();
356         }
357 
isChainable() const358         bool SdrTextAttribute::isChainable() const
359         {
360             return mpSdrTextAttribute->isChainable();
361         }
362 
363 
isFixedCellHeight() const364         bool SdrTextAttribute::isFixedCellHeight() const
365         {
366             return mpSdrTextAttribute->isFixedCellHeight();
367         }
368 
getSdrFormTextAttribute() const369         const SdrFormTextAttribute& SdrTextAttribute::getSdrFormTextAttribute() const
370         {
371             return mpSdrTextAttribute->getSdrFormTextAttribute();
372         }
373 
getTextLeftDistance() const374         sal_Int32 SdrTextAttribute::getTextLeftDistance() const
375         {
376             return mpSdrTextAttribute->getTextLeftDistance();
377         }
378 
getTextUpperDistance() const379         sal_Int32 SdrTextAttribute::getTextUpperDistance() const
380         {
381             return mpSdrTextAttribute->getTextUpperDistance();
382         }
383 
getTextRightDistance() const384         sal_Int32 SdrTextAttribute::getTextRightDistance() const
385         {
386             return mpSdrTextAttribute->getTextRightDistance();
387         }
388 
getTextLowerDistance() const389         sal_Int32 SdrTextAttribute::getTextLowerDistance() const
390         {
391             return mpSdrTextAttribute->getTextLowerDistance();
392         }
393 
getSdrTextHorzAdjust() const394         SdrTextHorzAdjust SdrTextAttribute::getSdrTextHorzAdjust() const
395         {
396             return mpSdrTextAttribute->getSdrTextHorzAdjust();
397         }
398 
getSdrTextVertAdjust() const399         SdrTextVertAdjust SdrTextAttribute::getSdrTextVertAdjust() const
400         {
401             return mpSdrTextAttribute->getSdrTextVertAdjust();
402         }
403 
getBlinkTextTiming(drawinglayer::animation::AnimationEntryList & rAnimList) const404         void SdrTextAttribute::getBlinkTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList) const
405         {
406             if(isBlink())
407             {
408                 getSdrText().GetObject().impGetBlinkTextTiming(rAnimList);
409             }
410         }
411 
getScrollTextTiming(drawinglayer::animation::AnimationEntryList & rAnimList,double fFrameLength,double fTextLength) const412         void SdrTextAttribute::getScrollTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList, double fFrameLength, double fTextLength) const
413         {
414             if(isScroll())
415             {
416                 getSdrText().GetObject().impGetScrollTextTiming(rAnimList, fFrameLength, fTextLength);
417             }
418         }
419 
420 } // end of namespace
421 
422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
423