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/attribute/sdrfillgraphicattribute.hxx> 28 #include <drawinglayer/attribute/fillgraphicattribute.hxx> 29 #include <vcl/graph.hxx> 30 31 ////////////////////////////////////////////////////////////////////////////// 32 33 namespace drawinglayer 34 { 35 namespace attribute 36 { 37 class ImpSdrFillGraphicAttribute 38 { 39 public: 40 // refcounter 41 sal_uInt32 mnRefCount; 42 43 // data definitions 44 Graphic maFillGraphic; 45 basegfx::B2DVector maSize; 46 basegfx::B2DVector maOffset; 47 basegfx::B2DVector maOffsetPosition; 48 basegfx::B2DVector maRectPoint; 49 50 // bitfield 51 unsigned mbTiling : 1; 52 unsigned mbStretch : 1; 53 unsigned mbLogSize : 1; 54 55 ImpSdrFillGraphicAttribute( 56 const Graphic& rFillGraphic, 57 const basegfx::B2DVector& rSize, 58 const basegfx::B2DVector& rOffset, 59 const basegfx::B2DVector& rOffsetPosition, 60 const basegfx::B2DVector& rRectPoint, 61 bool bTiling, 62 bool bStretch, 63 bool bLogSize) 64 : mnRefCount(0), 65 maFillGraphic(rFillGraphic), 66 maSize(rSize), 67 maOffset(rOffset), 68 maOffsetPosition(rOffsetPosition), 69 maRectPoint(rRectPoint), 70 mbTiling(bTiling), 71 mbStretch(bStretch), 72 mbLogSize(bLogSize) 73 { 74 } 75 76 // data read access 77 const Graphic& getFillGraphic() const { return maFillGraphic; } 78 const basegfx::B2DVector& getSize() const { return maSize; } 79 const basegfx::B2DVector& getOffset() const { return maOffset; } 80 const basegfx::B2DVector& getOffsetPosition() const { return maOffsetPosition; } 81 const basegfx::B2DVector& getRectPoint() const { return maRectPoint; } 82 bool getTiling() const { return mbTiling; } 83 bool getStretch() const { return mbStretch; } 84 bool getLogSize() const { return mbLogSize; } 85 86 bool operator==(const ImpSdrFillGraphicAttribute& rCandidate) const 87 { 88 return (getFillGraphic() == rCandidate.getFillGraphic() 89 && getSize() == rCandidate.getSize() 90 && getOffset() == rCandidate.getOffset() 91 && getOffsetPosition() == rCandidate.getOffsetPosition() 92 && getRectPoint() == rCandidate.getRectPoint() 93 && getTiling() == rCandidate.getTiling() 94 && getStretch() == rCandidate.getStretch() 95 && getLogSize() == rCandidate.getLogSize()); 96 } 97 98 static ImpSdrFillGraphicAttribute* get_global_default() 99 { 100 static ImpSdrFillGraphicAttribute* pDefault = 0; 101 102 if(!pDefault) 103 { 104 pDefault = new ImpSdrFillGraphicAttribute( 105 Graphic(), 106 basegfx::B2DVector(), 107 basegfx::B2DVector(), 108 basegfx::B2DVector(), 109 basegfx::B2DVector(), 110 false, 111 false, 112 false); 113 114 // never delete; start with RefCount 1, not 0 115 pDefault->mnRefCount++; 116 } 117 118 return pDefault; 119 } 120 }; 121 122 SdrFillGraphicAttribute::SdrFillGraphicAttribute( 123 const Graphic& rFillGraphic, 124 const basegfx::B2DVector& rSize, 125 const basegfx::B2DVector& rOffset, 126 const basegfx::B2DVector& rOffsetPosition, 127 const basegfx::B2DVector& rRectPoint, 128 bool bTiling, 129 bool bStretch, 130 bool bLogSize) 131 : mpSdrFillGraphicAttribute( 132 new ImpSdrFillGraphicAttribute( 133 rFillGraphic, 134 rSize, 135 rOffset, 136 rOffsetPosition, 137 rRectPoint, 138 bTiling, 139 bStretch, 140 bLogSize)) 141 { 142 } 143 144 SdrFillGraphicAttribute::SdrFillGraphicAttribute() 145 : mpSdrFillGraphicAttribute(ImpSdrFillGraphicAttribute::get_global_default()) 146 { 147 mpSdrFillGraphicAttribute->mnRefCount++; 148 } 149 150 SdrFillGraphicAttribute::SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate) 151 : mpSdrFillGraphicAttribute(rCandidate.mpSdrFillGraphicAttribute) 152 { 153 mpSdrFillGraphicAttribute->mnRefCount++; 154 } 155 156 SdrFillGraphicAttribute::~SdrFillGraphicAttribute() 157 { 158 if(mpSdrFillGraphicAttribute->mnRefCount) 159 { 160 mpSdrFillGraphicAttribute->mnRefCount--; 161 } 162 else 163 { 164 delete mpSdrFillGraphicAttribute; 165 } 166 } 167 168 bool SdrFillGraphicAttribute::isDefault() const 169 { 170 return mpSdrFillGraphicAttribute == ImpSdrFillGraphicAttribute::get_global_default(); 171 } 172 173 SdrFillGraphicAttribute& SdrFillGraphicAttribute::operator=(const SdrFillGraphicAttribute& rCandidate) 174 { 175 if(rCandidate.mpSdrFillGraphicAttribute != mpSdrFillGraphicAttribute) 176 { 177 if(mpSdrFillGraphicAttribute->mnRefCount) 178 { 179 mpSdrFillGraphicAttribute->mnRefCount--; 180 } 181 else 182 { 183 delete mpSdrFillGraphicAttribute; 184 } 185 186 mpSdrFillGraphicAttribute = rCandidate.mpSdrFillGraphicAttribute; 187 mpSdrFillGraphicAttribute->mnRefCount++; 188 } 189 190 return *this; 191 } 192 193 bool SdrFillGraphicAttribute::operator==(const SdrFillGraphicAttribute& rCandidate) const 194 { 195 if(rCandidate.mpSdrFillGraphicAttribute == mpSdrFillGraphicAttribute) 196 { 197 return true; 198 } 199 200 if(rCandidate.isDefault() != isDefault()) 201 { 202 return false; 203 } 204 205 return (*rCandidate.mpSdrFillGraphicAttribute == *mpSdrFillGraphicAttribute); 206 } 207 208 const Graphic& SdrFillGraphicAttribute::getFillGraphic() const 209 { 210 return mpSdrFillGraphicAttribute->getFillGraphic(); 211 } 212 213 const basegfx::B2DVector& SdrFillGraphicAttribute::getSize() const 214 { 215 return mpSdrFillGraphicAttribute->getSize(); 216 } 217 218 const basegfx::B2DVector& SdrFillGraphicAttribute::getOffset() const 219 { 220 return mpSdrFillGraphicAttribute->getOffset(); 221 } 222 223 const basegfx::B2DVector& SdrFillGraphicAttribute::getOffsetPosition() const 224 { 225 return mpSdrFillGraphicAttribute->getOffsetPosition(); 226 } 227 228 const basegfx::B2DVector& SdrFillGraphicAttribute::getRectPoint() const 229 { 230 return mpSdrFillGraphicAttribute->getRectPoint(); 231 } 232 233 bool SdrFillGraphicAttribute::getTiling() const 234 { 235 return mpSdrFillGraphicAttribute->getTiling(); 236 } 237 238 bool SdrFillGraphicAttribute::getStretch() const 239 { 240 return mpSdrFillGraphicAttribute->getStretch(); 241 } 242 243 bool SdrFillGraphicAttribute::getLogSize() const 244 { 245 return mpSdrFillGraphicAttribute->getLogSize(); 246 } 247 248 FillGraphicAttribute SdrFillGraphicAttribute::createFillGraphicAttribute(const basegfx::B2DRange& rRange) const 249 { 250 // get logical size of bitmap (before expanding eventually) 251 Graphic aGraphic(getFillGraphic()); 252 const basegfx::B2DVector aLogicalSize(aGraphic.GetPrefSize().getWidth(), aGraphic.GetPrefSize().getHeight()); 253 254 // init values with defaults 255 basegfx::B2DPoint aBitmapSize(1.0, 1.0); 256 basegfx::B2DVector aBitmapTopLeft(0.0, 0.0); 257 258 // are changes needed? 259 if(getTiling() || !getStretch()) 260 { 261 // init values with range sizes 262 const double fRangeWidth(0.0 != rRange.getWidth() ? rRange.getWidth() : 1.0); 263 const double fRangeHeight(0.0 != rRange.getHeight() ? rRange.getHeight() : 1.0); 264 aBitmapSize = basegfx::B2DPoint(fRangeWidth, fRangeHeight); 265 266 // size changes 267 if(0.0 != getSize().getX()) 268 { 269 if(getSize().getX() < 0.0) 270 { 271 aBitmapSize.setX(aBitmapSize.getX() * (getSize().getX() * -0.01)); 272 } 273 else 274 { 275 aBitmapSize.setX(getSize().getX()); 276 } 277 } 278 else 279 { 280 aBitmapSize.setX(aLogicalSize.getX()); 281 } 282 283 if(0.0 != getSize().getY()) 284 { 285 if(getSize().getY() < 0.0) 286 { 287 aBitmapSize.setY(aBitmapSize.getY() * (getSize().getY() * -0.01)); 288 } 289 else 290 { 291 aBitmapSize.setY(getSize().getY()); 292 } 293 } 294 else 295 { 296 aBitmapSize.setY(aLogicalSize.getY()); 297 } 298 299 // get values, force to centered if necessary 300 const basegfx::B2DVector aRectPoint(getTiling() ? getRectPoint() : basegfx::B2DVector(0.0, 0.0)); 301 302 // position changes X 303 if(0.0 == aRectPoint.getX()) 304 { 305 aBitmapTopLeft.setX((fRangeWidth - aBitmapSize.getX()) * 0.5); 306 } 307 else if(1.0 == aRectPoint.getX()) 308 { 309 aBitmapTopLeft.setX(fRangeWidth - aBitmapSize.getX()); 310 } 311 312 if(getTiling() && 0.0 != getOffsetPosition().getX()) 313 { 314 aBitmapTopLeft.setX(aBitmapTopLeft.getX() + (aBitmapSize.getX() * (getOffsetPosition().getX() * 0.01))); 315 } 316 317 // position changes Y 318 if(0.0 == aRectPoint.getY()) 319 { 320 aBitmapTopLeft.setY((fRangeHeight - aBitmapSize.getY()) * 0.5); 321 } 322 else if(1.0 == aRectPoint.getY()) 323 { 324 aBitmapTopLeft.setY(fRangeHeight - aBitmapSize.getY()); 325 } 326 327 if(getTiling() && 0.0 != getOffsetPosition().getY()) 328 { 329 aBitmapTopLeft.setY(aBitmapTopLeft.getY() + (aBitmapSize.getY() * (getOffsetPosition().getY() * 0.01))); 330 } 331 332 // apply bitmap size scaling to unit rectangle 333 aBitmapTopLeft.setX(aBitmapTopLeft.getX() / fRangeWidth); 334 aBitmapTopLeft.setY(aBitmapTopLeft.getY() / fRangeHeight); 335 aBitmapSize.setX(aBitmapSize.getX() / fRangeWidth); 336 aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight); 337 } 338 339 // get offset in percent 340 const double fOffsetX(basegfx::clamp(getOffset().getX() * 0.01, 0.0, 1.0)); 341 const double fOffsetY(basegfx::clamp(getOffset().getY() * 0.01, 0.0, 1.0)); 342 343 // create FillGraphicAttribute 344 return FillGraphicAttribute( 345 aGraphic, 346 basegfx::B2DRange(aBitmapTopLeft, aBitmapTopLeft + aBitmapSize), 347 getTiling(), 348 fOffsetX, 349 fOffsetY); 350 } 351 } // end of namespace attribute 352 } // end of namespace drawinglayer 353 354 ////////////////////////////////////////////////////////////////////////////// 355 // eof 356