1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_drawinglayer.hxx" 30 31 #include <drawinglayer/primitive2d/borderlineprimitive2d.hxx> 32 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 33 #include <basegfx/polygon/b2dpolygon.hxx> 34 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 35 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 36 #include <numeric> 37 38 ////////////////////////////////////////////////////////////////////////////// 39 40 namespace drawinglayer 41 { 42 namespace primitive2d 43 { 44 Primitive2DSequence BorderLinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 45 { 46 Primitive2DSequence xRetval; 47 48 if(!getStart().equal(getEnd()) && (getCreateInside() || getCreateOutside())) 49 { 50 if(isInsideUsed()) 51 { 52 // get data and vectors 53 const double fWidth(getWidth()); 54 basegfx::B2DVector aVector(getEnd() - getStart()); 55 aVector.normalize(); 56 const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector)); 57 58 if(isOutsideUsed()) 59 { 60 // both used, double line definition. Create left and right offset 61 xRetval.realloc(getCreateInside() && getCreateOutside() ? 2 : 1); 62 sal_uInt32 nInsert(0); 63 64 if(getCreateInside()) 65 { 66 // create geometry for left 67 const basegfx::B2DVector aLeftOff(aPerpendicular * (0.5 * (getCorrectedLeftWidth() - fWidth))); 68 const basegfx::B2DPoint aTmpStart(getStart() + aLeftOff - (getExtendInnerStart() * aVector)); 69 const basegfx::B2DPoint aTmpEnd(getEnd() + aLeftOff + (getExtendInnerEnd() * aVector)); 70 basegfx::B2DPolygon aLeft; 71 72 if(leftIsHairline()) 73 { 74 // create hairline primitive 75 aLeft.append(aTmpStart); 76 aLeft.append(aTmpEnd); 77 78 xRetval[nInsert++] = Primitive2DReference(new PolygonHairlinePrimitive2D( 79 aLeft, 80 getRGBColor())); 81 } 82 else 83 { 84 // create filled polygon primitive. Already tried to create thick lines 85 // with the correct LineWidth, but this leads to problems when no AA 86 // is available and fat line special case reductions between 0.5 < x < 2.5 line widths 87 // are executed due to the FilledPolygon-do-not-paint-their-bottom-and-right-lines. 88 const basegfx::B2DVector aLineWidthOffset((getCorrectedLeftWidth() * 0.5) * aPerpendicular); 89 90 aLeft.append(aTmpStart + aLineWidthOffset); 91 aLeft.append(aTmpEnd + aLineWidthOffset); 92 aLeft.append(aTmpEnd - aLineWidthOffset); 93 aLeft.append(aTmpStart - aLineWidthOffset); 94 aLeft.setClosed(true); 95 96 xRetval[nInsert++] = Primitive2DReference(new PolyPolygonColorPrimitive2D( 97 basegfx::B2DPolyPolygon(aLeft), getRGBColor())); 98 } 99 } 100 101 if(getCreateOutside()) 102 { 103 // create geometry for right 104 const basegfx::B2DVector aRightOff(aPerpendicular * (0.5 * (fWidth - getCorrectedRightWidth()))); 105 const basegfx::B2DPoint aTmpStart(getStart() + aRightOff - (getExtendOuterStart() * aVector)); 106 const basegfx::B2DPoint aTmpEnd(getEnd() + aRightOff + (getExtendOuterEnd() * aVector)); 107 basegfx::B2DPolygon aRight; 108 109 if(rightIsHairline()) 110 { 111 // create hairline primitive 112 aRight.append(aTmpStart); 113 aRight.append(aTmpEnd); 114 115 xRetval[nInsert++] = Primitive2DReference(new PolygonHairlinePrimitive2D( 116 aRight, 117 getRGBColor())); 118 } 119 else 120 { 121 // create filled polygon primitive 122 const basegfx::B2DVector aLineWidthOffset((getCorrectedRightWidth() * 0.5) * aPerpendicular); 123 124 aRight.append(aTmpStart + aLineWidthOffset); 125 aRight.append(aTmpEnd + aLineWidthOffset); 126 aRight.append(aTmpEnd - aLineWidthOffset); 127 aRight.append(aTmpStart - aLineWidthOffset); 128 aRight.setClosed(true); 129 130 xRetval[nInsert++] = Primitive2DReference(new PolyPolygonColorPrimitive2D( 131 basegfx::B2DPolyPolygon(aRight), getRGBColor())); 132 } 133 } 134 } 135 else 136 { 137 // single line, create geometry 138 basegfx::B2DPolygon aPolygon; 139 const double fMaxExtStart(::std::max(getExtendInnerStart(), getExtendOuterStart())); 140 const double fMaxExtEnd(::std::max(getExtendInnerEnd(), getExtendOuterEnd())); 141 const basegfx::B2DPoint aTmpStart(getStart() - (fMaxExtStart * aVector)); 142 const basegfx::B2DPoint aTmpEnd(getEnd() + (fMaxExtEnd * aVector)); 143 xRetval.realloc(1); 144 145 if(leftIsHairline()) 146 { 147 // create hairline primitive 148 aPolygon.append(aTmpStart); 149 aPolygon.append(aTmpEnd); 150 151 xRetval[0] = Primitive2DReference(new PolygonHairlinePrimitive2D( 152 aPolygon, 153 getRGBColor())); 154 } 155 else 156 { 157 // create filled polygon primitive 158 const basegfx::B2DVector aLineWidthOffset((getCorrectedLeftWidth() * 0.5) * aPerpendicular); 159 160 aPolygon.append(aTmpStart + aLineWidthOffset); 161 aPolygon.append(aTmpEnd + aLineWidthOffset); 162 aPolygon.append(aTmpEnd - aLineWidthOffset); 163 aPolygon.append(aTmpStart - aLineWidthOffset); 164 aPolygon.setClosed(true); 165 166 xRetval[0] = Primitive2DReference(new PolyPolygonColorPrimitive2D( 167 basegfx::B2DPolyPolygon(aPolygon), getRGBColor())); 168 } 169 } 170 } 171 } 172 173 return xRetval; 174 } 175 176 BorderLinePrimitive2D::BorderLinePrimitive2D( 177 const basegfx::B2DPoint& rStart, 178 const basegfx::B2DPoint& rEnd, 179 double fLeftWidth, 180 double fDistance, 181 double fRightWidth, 182 double fExtendInnerStart, 183 double fExtendInnerEnd, 184 double fExtendOuterStart, 185 double fExtendOuterEnd, 186 bool bCreateInside, 187 bool bCreateOutside, 188 const basegfx::BColor& rRGBColor) 189 : BufferedDecompositionPrimitive2D(), 190 maStart(rStart), 191 maEnd(rEnd), 192 mfLeftWidth(fLeftWidth), 193 mfDistance(fDistance), 194 mfRightWidth(fRightWidth), 195 mfExtendInnerStart(fExtendInnerStart), 196 mfExtendInnerEnd(fExtendInnerEnd), 197 mfExtendOuterStart(fExtendOuterStart), 198 mfExtendOuterEnd(fExtendOuterEnd), 199 maRGBColor(rRGBColor), 200 mbCreateInside(bCreateInside), 201 mbCreateOutside(bCreateOutside) 202 { 203 } 204 205 bool BorderLinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 206 { 207 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 208 { 209 const BorderLinePrimitive2D& rCompare = (BorderLinePrimitive2D&)rPrimitive; 210 211 return (getStart() == rCompare.getStart() 212 && getEnd() == rCompare.getEnd() 213 && getLeftWidth() == rCompare.getLeftWidth() 214 && getDistance() == rCompare.getDistance() 215 && getRightWidth() == rCompare.getRightWidth() 216 && getExtendInnerStart() == rCompare.getExtendInnerStart() 217 && getExtendInnerEnd() == rCompare.getExtendInnerEnd() 218 && getExtendOuterStart() == rCompare.getExtendOuterStart() 219 && getExtendOuterEnd() == rCompare.getExtendOuterEnd() 220 && getCreateInside() == rCompare.getCreateInside() 221 && getCreateOutside() == rCompare.getCreateOutside() 222 && getRGBColor() == rCompare.getRGBColor()); 223 } 224 225 return false; 226 } 227 228 // provide unique ID 229 ImplPrimitrive2DIDBlock(BorderLinePrimitive2D, PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D) 230 231 } // end of namespace primitive2d 232 } // end of namespace drawinglayer 233 234 ////////////////////////////////////////////////////////////////////////////// 235 // eof 236