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