xref: /AOO41X/main/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx (revision 464702f4578bd67db020a330afd07883930c5e07)
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_drawinglayer.hxx"
26 
27 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx>
28 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
29 #include <basegfx/polygon/b2dpolygon.hxx>
30 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
31 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
32 #include <numeric>
33 
34 //////////////////////////////////////////////////////////////////////////////
35 
36 namespace drawinglayer
37 {
38     namespace primitive2d
39     {
create2DDecomposition(const geometry::ViewInformation2D &) const40         Primitive2DSequence BorderLinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
41         {
42             Primitive2DSequence xRetval;
43 
44             if(!getStart().equal(getEnd()) && (getCreateInside() || getCreateOutside()))
45             {
46                 if(isInsideUsed())
47                 {
48                     // get data and vectors
49                     const double fWidth(getWidth());
50                     basegfx::B2DVector aVector(getEnd() - getStart());
51                     aVector.normalize();
52                     const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
53 
54                     if(isOutsideUsed())
55                     {
56                         // both used, double line definition. Create left and right offset
57                         xRetval.realloc(getCreateInside() && getCreateOutside() ? 2 : 1);
58                         sal_uInt32 nInsert(0);
59 
60                         if(getCreateInside())
61                         {
62                             // create geometry for left
63                             const basegfx::B2DVector aLeftOff(aPerpendicular * (0.5 * (getCorrectedLeftWidth() - fWidth)));
64                             const basegfx::B2DPoint aTmpStart(getStart() + aLeftOff - (getExtendInnerStart() * aVector));
65                             const basegfx::B2DPoint aTmpEnd(getEnd() + aLeftOff + (getExtendInnerEnd() * aVector));
66                             basegfx::B2DPolygon aLeft;
67 
68                             if(leftIsHairline())
69                             {
70                                 // create hairline primitive
71                                 aLeft.append(aTmpStart);
72                                 aLeft.append(aTmpEnd);
73 
74                                 xRetval[nInsert++] = Primitive2DReference(new PolygonHairlinePrimitive2D(
75                                     aLeft,
76                                     getRGBColor()));
77                             }
78                             else
79                             {
80                                 // create filled polygon primitive. Already tried to create thick lines
81                                 // with the correct LineWidth, but this leads to problems when no AA
82                                 // is available and fat line special case reductions between 0.5 < x < 2.5 line widths
83                                 // are executed due to the FilledPolygon-do-not-paint-their-bottom-and-right-lines.
84                                 const basegfx::B2DVector aLineWidthOffset((getCorrectedLeftWidth() * 0.5) * aPerpendicular);
85 
86                                 aLeft.append(aTmpStart + aLineWidthOffset);
87                                 aLeft.append(aTmpEnd + aLineWidthOffset);
88                                 aLeft.append(aTmpEnd - aLineWidthOffset);
89                                 aLeft.append(aTmpStart - aLineWidthOffset);
90                                 aLeft.setClosed(true);
91 
92                                 xRetval[nInsert++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
93                                     basegfx::B2DPolyPolygon(aLeft), getRGBColor()));
94                             }
95                         }
96 
97                         if(getCreateOutside())
98                         {
99                             // create geometry for right
100                             const basegfx::B2DVector aRightOff(aPerpendicular * (0.5 * (fWidth - getCorrectedRightWidth())));
101                             const basegfx::B2DPoint aTmpStart(getStart() + aRightOff - (getExtendOuterStart() * aVector));
102                             const basegfx::B2DPoint aTmpEnd(getEnd() + aRightOff + (getExtendOuterEnd() * aVector));
103                             basegfx::B2DPolygon aRight;
104 
105                             if(rightIsHairline())
106                             {
107                                 // create hairline primitive
108                                 aRight.append(aTmpStart);
109                                 aRight.append(aTmpEnd);
110 
111                                 xRetval[nInsert++] = Primitive2DReference(new PolygonHairlinePrimitive2D(
112                                     aRight,
113                                     getRGBColor()));
114                             }
115                             else
116                             {
117                                 // create filled polygon primitive
118                                 const basegfx::B2DVector aLineWidthOffset((getCorrectedRightWidth() * 0.5) * aPerpendicular);
119 
120                                 aRight.append(aTmpStart + aLineWidthOffset);
121                                 aRight.append(aTmpEnd + aLineWidthOffset);
122                                 aRight.append(aTmpEnd - aLineWidthOffset);
123                                 aRight.append(aTmpStart - aLineWidthOffset);
124                                 aRight.setClosed(true);
125 
126                                 xRetval[nInsert++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
127                                     basegfx::B2DPolyPolygon(aRight), getRGBColor()));
128                             }
129                         }
130                     }
131                     else
132                     {
133                         // single line, create geometry
134                         basegfx::B2DPolygon aPolygon;
135                         const double fMaxExtStart(::std::max(getExtendInnerStart(), getExtendOuterStart()));
136                         const double fMaxExtEnd(::std::max(getExtendInnerEnd(), getExtendOuterEnd()));
137                         const basegfx::B2DPoint aTmpStart(getStart() - (fMaxExtStart * aVector));
138                         const basegfx::B2DPoint aTmpEnd(getEnd() + (fMaxExtEnd * aVector));
139                         xRetval.realloc(1);
140 
141                         if(leftIsHairline())
142                         {
143                             // create hairline primitive
144                             aPolygon.append(aTmpStart);
145                             aPolygon.append(aTmpEnd);
146 
147                             xRetval[0] = Primitive2DReference(new PolygonHairlinePrimitive2D(
148                                 aPolygon,
149                                 getRGBColor()));
150                         }
151                         else
152                         {
153                             // create filled polygon primitive
154                             const basegfx::B2DVector aLineWidthOffset((getCorrectedLeftWidth() * 0.5) * aPerpendicular);
155 
156                             aPolygon.append(aTmpStart + aLineWidthOffset);
157                             aPolygon.append(aTmpEnd + aLineWidthOffset);
158                             aPolygon.append(aTmpEnd - aLineWidthOffset);
159                             aPolygon.append(aTmpStart - aLineWidthOffset);
160                             aPolygon.setClosed(true);
161 
162                             xRetval[0] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
163                                 basegfx::B2DPolyPolygon(aPolygon), getRGBColor()));
164                         }
165                     }
166                 }
167             }
168 
169             return xRetval;
170         }
171 
BorderLinePrimitive2D(const basegfx::B2DPoint & rStart,const basegfx::B2DPoint & rEnd,double fLeftWidth,double fDistance,double fRightWidth,double fExtendInnerStart,double fExtendInnerEnd,double fExtendOuterStart,double fExtendOuterEnd,bool bCreateInside,bool bCreateOutside,const basegfx::BColor & rRGBColor)172         BorderLinePrimitive2D::BorderLinePrimitive2D(
173             const basegfx::B2DPoint& rStart,
174             const basegfx::B2DPoint& rEnd,
175             double fLeftWidth,
176             double fDistance,
177             double fRightWidth,
178             double fExtendInnerStart,
179             double fExtendInnerEnd,
180             double fExtendOuterStart,
181             double fExtendOuterEnd,
182             bool bCreateInside,
183             bool bCreateOutside,
184             const basegfx::BColor& rRGBColor)
185         :   BufferedDecompositionPrimitive2D(),
186             maStart(rStart),
187             maEnd(rEnd),
188             mfLeftWidth(fLeftWidth),
189             mfDistance(fDistance),
190             mfRightWidth(fRightWidth),
191             mfExtendInnerStart(fExtendInnerStart),
192             mfExtendInnerEnd(fExtendInnerEnd),
193             mfExtendOuterStart(fExtendOuterStart),
194             mfExtendOuterEnd(fExtendOuterEnd),
195             maRGBColor(rRGBColor),
196             mbCreateInside(bCreateInside),
197             mbCreateOutside(bCreateOutside)
198         {
199         }
200 
operator ==(const BasePrimitive2D & rPrimitive) const201         bool BorderLinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
202         {
203             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
204             {
205                 const BorderLinePrimitive2D& rCompare = (BorderLinePrimitive2D&)rPrimitive;
206 
207                 return (getStart() == rCompare.getStart()
208                     && getEnd() == rCompare.getEnd()
209                     && getLeftWidth() == rCompare.getLeftWidth()
210                     && getDistance() == rCompare.getDistance()
211                     && getRightWidth() == rCompare.getRightWidth()
212                     && getExtendInnerStart() == rCompare.getExtendInnerStart()
213                     && getExtendInnerEnd() == rCompare.getExtendInnerEnd()
214                     && getExtendOuterStart() == rCompare.getExtendOuterStart()
215                     && getExtendOuterEnd() == rCompare.getExtendOuterEnd()
216                     && getCreateInside() == rCompare.getCreateInside()
217                     && getCreateOutside() == rCompare.getCreateOutside()
218                     && getRGBColor() == rCompare.getRGBColor());
219             }
220 
221             return false;
222         }
223 
224         // provide unique ID
225         ImplPrimitrive2DIDBlock(BorderLinePrimitive2D, PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D)
226 
227     } // end of namespace primitive2d
228 } // end of namespace drawinglayer
229 
230 //////////////////////////////////////////////////////////////////////////////
231 // eof
232