xref: /AOO41X/main/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx (revision 4bf7a51aae81eefaa1c594b1f2d068b2a05bd3a8)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include <svx/sdr/contact/viewcontactofsdrpathobj.hxx>
28 #include <svx/svdopath.hxx>
29 #include <svx/sdr/primitive2d/sdrattributecreator.hxx>
30 #include <basegfx/polygon/b2dpolypolygontools.hxx>
31 #include <svx/sdr/primitive2d/sdrpathprimitive2d.hxx>
32 #include <basegfx/matrix/b2dhommatrixtools.hxx>
33 
34 //////////////////////////////////////////////////////////////////////////////
35 
36 namespace sdr
37 {
38     namespace contact
39     {
ViewContactOfSdrPathObj(SdrPathObj & rPathObj)40         ViewContactOfSdrPathObj::ViewContactOfSdrPathObj(SdrPathObj& rPathObj)
41         :   ViewContactOfTextObj(rPathObj)
42         {
43         }
44 
~ViewContactOfSdrPathObj()45         ViewContactOfSdrPathObj::~ViewContactOfSdrPathObj()
46         {
47         }
48 
createViewIndependentPrimitive2DSequence() const49         drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrPathObj::createViewIndependentPrimitive2DSequence() const
50         {
51             const SfxItemSet& rItemSet = GetPathObj().GetMergedItemSet();
52             const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute(
53                 drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute(
54                     rItemSet,
55                     GetPathObj().getText(0),
56                     false));
57             basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly());
58             sal_uInt32 nPolyCount(aUnitPolyPolygon.count());
59             sal_uInt32 nPointCount(0);
60 
61             for(sal_uInt32 a(0); a < nPolyCount; a++)
62             {
63                 nPointCount += aUnitPolyPolygon.getB2DPolygon(a).count();
64             }
65 
66             if(!nPointCount)
67             {
68                 OSL_ENSURE(false, "PolyPolygon object without geometry detected, this should not be created (!)");
69                 basegfx::B2DPolygon aFallbackLine;
70                 aFallbackLine.append(basegfx::B2DPoint(0.0, 0.0));
71                 aFallbackLine.append(basegfx::B2DPoint(1000.0, 1000.0));
72                 aUnitPolyPolygon = basegfx::B2DPolyPolygon(aFallbackLine);
73 
74                 nPolyCount = 1;
75             }
76 
77             // prepare object transformation and unit polygon (direct model data)
78             basegfx::B2DHomMatrix aObjectMatrix;
79             const bool bIsLine(
80                 !aUnitPolyPolygon.areControlPointsUsed()
81                 && 1 == nPolyCount
82                 && 2 == aUnitPolyPolygon.getB2DPolygon(0).count());
83 
84             if(bIsLine)
85             {
86                 // special handling for single line mode (2 points)
87                 const basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0));
88                 const basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0));
89                 const basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1));
90                 const basegfx::B2DVector aLine(aEnd - aStart);
91 
92                 // #i102548# create new unit polygon for line (horizontal)
93                 basegfx::B2DPolygon aNewPolygon;
94                 aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0));
95                 aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0));
96                 aUnitPolyPolygon.setB2DPolygon(0, aNewPolygon);
97 
98                 // #i102548# fill objectMatrix with rotation and offset (no shear for lines)
99                 aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
100                     aLine.getLength(), 1.0,
101                     0.0,
102                     atan2(aLine.getY(), aLine.getX()),
103                     aStart.getX(), aStart.getY());
104             }
105             else
106             {
107                 // #i102548# create unscaled, unsheared, unrotated and untranslated polygon
108                 // (unit polygon) by creating the object matrix and back-transforming the polygon
109                 const basegfx::B2DRange aObjectRange(basegfx::tools::getRange(aUnitPolyPolygon));
110                 const GeoStat& rGeoStat(GetPathObj().GetGeoStat());
111                 const double fWidth(aObjectRange.getWidth());
112                 const double fHeight(aObjectRange.getHeight());
113                 const double fScaleX(basegfx::fTools::equalZero(fWidth) ? 1.0 : fWidth);
114                 const double fScaleY(basegfx::fTools::equalZero(fHeight) ? 1.0 : fHeight);
115 
116                 aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
117                     fScaleX, fScaleY,
118                     rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0,
119                     rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0,
120                     aObjectRange.getMinX(), aObjectRange.getMinY());
121 
122                 // ceate unit polygon from object's absolute path
123                 basegfx::B2DHomMatrix aInverse(aObjectMatrix);
124                 aInverse.invert();
125                 aUnitPolyPolygon.transform(aInverse);
126             }
127 
128             // create primitive. Always create primitives to allow the decomposition of
129             // SdrPathPrimitive2D to create needed invisible elements for HitTest and/or BoundRect
130             const drawinglayer::primitive2d::Primitive2DReference xReference(
131                 new drawinglayer::primitive2d::SdrPathPrimitive2D(
132                     aObjectMatrix,
133                     aAttribute,
134                     aUnitPolyPolygon));
135 
136             return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
137         }
138     } // end of namespace contact
139 } // end of namespace sdr
140 
141 //////////////////////////////////////////////////////////////////////////////
142 // eof
143