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