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 <svx/sdr/overlay/overlayobject.hxx>
21 #include <svx/sdr/overlay/overlaymanager.hxx>
22 #include <basegfx/matrix/b2dhommatrix.hxx>
23 #include <basegfx/vector/b2dvector.hxx>
24 #include <vcl/outdev.hxx>
25 #include <basegfx/polygon/b2dpolygon.hxx>
26 #include <basegfx/polygon/b2dpolypolygon.hxx>
27 #include <basegfx/polygon/b2dpolygontools.hxx>
28 #include <basegfx/polygon/b2dpolypolygontools.hxx>
29 #include <basegfx/matrix/b2dhommatrixtools.hxx>
30 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
31 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
32 
33 namespace sdr
34 {
35     namespace overlay
36     {
objectChange()37         void OverlayObject::objectChange()
38         {
39             const basegfx::B2DRange aPreviousRange(maBaseRange);
40             maBaseRange.reset();
41             resetPrimitive2DSequence();
42 //            setPrimitive2DSequence(drawinglayer::primitive2d::Primitive2DContainer());
43 
44             if(getOverlayManager() && !aPreviousRange.isEmpty())
45             {
46                 getOverlayManager()->invalidateRange(aPreviousRange);
47             }
48 
49             const basegfx::B2DRange& rCurrentRange = getBaseRange();
50 
51             if(getOverlayManager() && rCurrentRange != aPreviousRange && !rCurrentRange.isEmpty())
52             {
53                 getOverlayManager()->invalidateRange(rCurrentRange);
54             }
55         }
56 
57         // OverlayObject implementations.
createOverlayObjectPrimitive2DSequence()58         drawinglayer::primitive2d::Primitive2DContainer OverlayObject::createOverlayObjectPrimitive2DSequence()
59         {
60             // Default implementation has to assert a missing implementation. It cannot
61             // be useful to have overlay object derivations which have no visualisation
62             // at all
63             OSL_FAIL("OverlayObject derivation without visualisation definition (missing createOverlayObjectPrimitive2DSequence implementation) (!)");
64             return drawinglayer::primitive2d::Primitive2DContainer();
65         }
66 
impCheckBlinkTimeValueRange(sal_uInt64 nBlinkTime)67         sal_uInt32 OverlayObject::impCheckBlinkTimeValueRange(sal_uInt64 nBlinkTime)
68         {
69             if(nBlinkTime < 25)
70             {
71                 nBlinkTime = 25;
72             }
73             else if(nBlinkTime > 10000)
74             {
75                 nBlinkTime = 10000;
76             }
77 
78             return nBlinkTime;
79         }
80 
allowAntiAliase(bool bNew)81         void OverlayObject::allowAntiAliase(bool bNew)
82         {
83             if(bNew != mbAllowsAntiAliase)
84             {
85                 // remember new value
86                 mbAllowsAntiAliase = bNew;
87 
88                 // register change (after change)
89                 objectChange();
90             }
91         }
92 
OverlayObject(Color aBaseColor)93         OverlayObject::OverlayObject(Color aBaseColor)
94         :   Event(),
95             mpOverlayManager(nullptr),
96             maPrimitive2DSequence(),
97             maOffset(0.0, 0.0),
98             maBaseColor(aBaseColor),
99             mbIsVisible(true),
100             mbIsHittable(true),
101             mbAllowsAnimation(false),
102             mbAllowsAntiAliase(true)
103         {
104         }
105 
~OverlayObject()106         OverlayObject::~OverlayObject()
107         {
108             OSL_ENSURE(nullptr == getOverlayManager(), "OverlayObject is destructed which is still registered at OverlayManager (!)");
109         }
110 
getOverlayObjectPrimitive2DSequence() const111         drawinglayer::primitive2d::Primitive2DContainer OverlayObject::getOverlayObjectPrimitive2DSequence() const
112         {
113             if(getPrimitive2DSequence().empty())
114             {
115                 // no existing sequence; create one
116                 const_cast< OverlayObject* >(this)->maPrimitive2DSequence = const_cast< OverlayObject* >(this)->createOverlayObjectPrimitive2DSequence();
117 
118                 if(!getOffset().equalZero())
119                 {
120                     // embed to offset transformation
121                     const basegfx::B2DHomMatrix aTranslateGridOffset(
122                         basegfx::utils::createTranslateB2DHomMatrix(
123                             getOffset()));
124                     const drawinglayer::primitive2d::Primitive2DReference aEmbed(
125                         new drawinglayer::primitive2d::TransformPrimitive2D(
126                             aTranslateGridOffset,
127                             maPrimitive2DSequence));
128 
129                     const_cast< OverlayObject* >(this)->maPrimitive2DSequence = drawinglayer::primitive2d::Primitive2DContainer { aEmbed };
130                 }
131             }
132 
133             return getPrimitive2DSequence();
134         }
135 
getBaseRange() const136         const basegfx::B2DRange& OverlayObject::getBaseRange() const
137         {
138             if(getOverlayManager() && maBaseRange.isEmpty())
139             {
140                 const drawinglayer::primitive2d::Primitive2DContainer& rSequence = getOverlayObjectPrimitive2DSequence();
141 
142                 if(!rSequence.empty())
143                 {
144                     const drawinglayer::geometry::ViewInformation2D aViewInformation2D(getOverlayManager()->getCurrentViewInformation2D());
145 
146                     const_cast< sdr::overlay::OverlayObject* >(this)->maBaseRange =
147                         rSequence.getB2DRange(aViewInformation2D);
148                 }
149             }
150 
151             return maBaseRange;
152         }
153 
setVisible(bool bNew)154         void OverlayObject::setVisible(bool bNew)
155         {
156             if(bNew != mbIsVisible)
157             {
158                 // remember new value
159                 mbIsVisible = bNew;
160 
161                 // register change (after change)
162                 objectChange();
163             }
164         }
165 
setHittable(bool bNew)166         void OverlayObject::setHittable(bool bNew)
167         {
168             if(bNew != mbIsHittable)
169             {
170                 // remember new value
171                 mbIsHittable = bNew;
172 
173                 // register change (after change)
174                 objectChange();
175             }
176         }
177 
setBaseColor(Color aNew)178         void OverlayObject::setBaseColor(Color aNew)
179         {
180             if(aNew != maBaseColor)
181             {
182                 // remember new value
183                 maBaseColor = aNew;
184 
185                 // register change (after change)
186                 objectChange();
187             }
188         }
189 
setOffset(const basegfx::B2DVector & rOffset)190         void OverlayObject::setOffset(const basegfx::B2DVector& rOffset)
191         {
192             if(rOffset != maOffset)
193             {
194                 // remember new value
195                 maOffset = rOffset;
196 
197                 // register change (after change)
198                 objectChange();
199             }
200         }
201 
Trigger(sal_uInt32)202         void OverlayObject::Trigger(sal_uInt32 /*nTime*/)
203         {
204             // default does not register again
205         }
206 
stripeDefinitionHasChanged()207         void OverlayObject::stripeDefinitionHasChanged()
208         {
209             // default does not need to do anything
210         }
211     } // end of namespace overlay
212 } // end of namespace sdr
213 
214 
215 namespace sdr
216 {
217     namespace overlay
218     {
OverlayObjectWithBasePosition(const basegfx::B2DPoint & rBasePos,Color aBaseColor)219         OverlayObjectWithBasePosition::OverlayObjectWithBasePosition(const basegfx::B2DPoint& rBasePos, Color aBaseColor)
220         :   OverlayObject(aBaseColor),
221             maBasePosition(rBasePos)
222         {
223         }
224 
~OverlayObjectWithBasePosition()225         OverlayObjectWithBasePosition::~OverlayObjectWithBasePosition()
226         {
227         }
228 
setBasePosition(const basegfx::B2DPoint & rNew)229         void OverlayObjectWithBasePosition::setBasePosition(const basegfx::B2DPoint& rNew)
230         {
231             if(rNew != maBasePosition)
232             {
233                 // remember new value
234                 maBasePosition = rNew;
235 
236                 // register change (after change)
237                 objectChange();
238             }
239         }
240     } // end of namespace overlay
241 } // end of namespace sdr
242 
243 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
244