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/attribute/strokeattribute.hxx> 32 #include <numeric> 33 34 ////////////////////////////////////////////////////////////////////////////// 35 36 namespace drawinglayer 37 { 38 namespace attribute 39 { 40 class ImpStrokeAttribute 41 { 42 public: 43 // refcounter 44 sal_uInt32 mnRefCount; 45 46 // data definitions 47 ::std::vector< double > maDotDashArray; // array of double which defines the dot-dash pattern 48 double mfFullDotDashLen; // sum of maDotDashArray (for convenience) 49 50 ImpStrokeAttribute( 51 const ::std::vector< double >& rDotDashArray, 52 double fFullDotDashLen) 53 : mnRefCount(0), 54 maDotDashArray(rDotDashArray), 55 mfFullDotDashLen(fFullDotDashLen) 56 { 57 } 58 59 // data read access 60 const ::std::vector< double >& getDotDashArray() const { return maDotDashArray; } 61 double getFullDotDashLen() const 62 { 63 if(0.0 == mfFullDotDashLen && maDotDashArray.size()) 64 { 65 // calculate length on demand 66 const double fAccumulated(::std::accumulate(maDotDashArray.begin(), maDotDashArray.end(), 0.0)); 67 const_cast< ImpStrokeAttribute* >(this)->mfFullDotDashLen = fAccumulated; 68 } 69 70 return mfFullDotDashLen; 71 } 72 73 bool operator==(const ImpStrokeAttribute& rCandidate) const 74 { 75 return (getDotDashArray() == rCandidate.getDotDashArray() 76 && getFullDotDashLen() == rCandidate.getFullDotDashLen()); 77 } 78 79 static ImpStrokeAttribute* get_global_default() 80 { 81 static ImpStrokeAttribute* pDefault = 0; 82 83 if(!pDefault) 84 { 85 pDefault = new ImpStrokeAttribute( 86 std::vector< double >(), 87 0.0); 88 89 // never delete; start with RefCount 1, not 0 90 pDefault->mnRefCount++; 91 } 92 93 return pDefault; 94 } 95 }; 96 97 StrokeAttribute::StrokeAttribute( 98 const ::std::vector< double >& rDotDashArray, 99 double fFullDotDashLen) 100 : mpStrokeAttribute(new ImpStrokeAttribute( 101 rDotDashArray, fFullDotDashLen)) 102 { 103 } 104 105 StrokeAttribute::StrokeAttribute() 106 : mpStrokeAttribute(ImpStrokeAttribute::get_global_default()) 107 { 108 mpStrokeAttribute->mnRefCount++; 109 } 110 111 StrokeAttribute::StrokeAttribute(const StrokeAttribute& rCandidate) 112 : mpStrokeAttribute(rCandidate.mpStrokeAttribute) 113 { 114 mpStrokeAttribute->mnRefCount++; 115 } 116 117 StrokeAttribute::~StrokeAttribute() 118 { 119 if(mpStrokeAttribute->mnRefCount) 120 { 121 mpStrokeAttribute->mnRefCount--; 122 } 123 else 124 { 125 delete mpStrokeAttribute; 126 } 127 } 128 129 bool StrokeAttribute::isDefault() const 130 { 131 return mpStrokeAttribute == ImpStrokeAttribute::get_global_default(); 132 } 133 134 StrokeAttribute& StrokeAttribute::operator=(const StrokeAttribute& rCandidate) 135 { 136 if(rCandidate.mpStrokeAttribute != mpStrokeAttribute) 137 { 138 if(mpStrokeAttribute->mnRefCount) 139 { 140 mpStrokeAttribute->mnRefCount--; 141 } 142 else 143 { 144 delete mpStrokeAttribute; 145 } 146 147 mpStrokeAttribute = rCandidate.mpStrokeAttribute; 148 mpStrokeAttribute->mnRefCount++; 149 } 150 151 return *this; 152 } 153 154 bool StrokeAttribute::operator==(const StrokeAttribute& rCandidate) const 155 { 156 if(rCandidate.mpStrokeAttribute == mpStrokeAttribute) 157 { 158 return true; 159 } 160 161 if(rCandidate.isDefault() != isDefault()) 162 { 163 return false; 164 } 165 166 return (*rCandidate.mpStrokeAttribute == *mpStrokeAttribute); 167 } 168 169 const ::std::vector< double >& StrokeAttribute::getDotDashArray() const 170 { 171 return mpStrokeAttribute->getDotDashArray(); 172 } 173 174 double StrokeAttribute::getFullDotDashLen() const 175 { 176 return mpStrokeAttribute->getFullDotDashLen(); 177 } 178 } // end of namespace attribute 179 } // end of namespace drawinglayer 180 181 ////////////////////////////////////////////////////////////////////////////// 182 // eof 183