1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <drawinglayer/primitive2d/discreteshadowprimitive2d.hxx> 21 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 22 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 23 #include <basegfx/matrix/b2dhommatrixtools.hxx> 24 #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 25 #include <drawinglayer/geometry/viewinformation2d.hxx> 26 27 28 namespace drawinglayer 29 { 30 namespace primitive2d 31 { DiscreteShadow(const BitmapEx & rBitmapEx)32 DiscreteShadow::DiscreteShadow(const BitmapEx& rBitmapEx) 33 : maBitmapEx(rBitmapEx), 34 maTopLeft(), 35 maTop(), 36 maTopRight(), 37 maRight(), 38 maBottomRight(), 39 maBottom(), 40 maBottomLeft(), 41 maLeft() 42 { 43 const Size& rBitmapSize = getBitmapEx().GetSizePixel(); 44 45 if(rBitmapSize.Width() != rBitmapSize.Height() || rBitmapSize.Width() < 7) 46 { 47 OSL_ENSURE(false, "DiscreteShadowPrimitive2D: wrong bitmap format (!)"); 48 maBitmapEx = BitmapEx(); 49 } 50 } 51 getTopLeft() const52 const BitmapEx& DiscreteShadow::getTopLeft() const 53 { 54 if(maTopLeft.IsEmpty()) 55 { 56 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); 57 const_cast< DiscreteShadow* >(this)->maTopLeft = getBitmapEx(); 58 const_cast< DiscreteShadow* >(this)->maTopLeft.Crop( 59 ::tools::Rectangle(Point(0, 0), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1))); 60 } 61 62 return maTopLeft; 63 } 64 getTop() const65 const BitmapEx& DiscreteShadow::getTop() const 66 { 67 if(maTop.IsEmpty()) 68 { 69 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); 70 const_cast< DiscreteShadow* >(this)->maTop = getBitmapEx(); 71 const_cast< DiscreteShadow* >(this)->maTop.Crop( 72 ::tools::Rectangle(Point((nQuarter * 2) + 1, 0), Size(1, nQuarter))); 73 } 74 75 return maTop; 76 } 77 getTopRight() const78 const BitmapEx& DiscreteShadow::getTopRight() const 79 { 80 if(maTopRight.IsEmpty()) 81 { 82 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); 83 const_cast< DiscreteShadow* >(this)->maTopRight = getBitmapEx(); 84 const_cast< DiscreteShadow* >(this)->maTopRight.Crop( 85 ::tools::Rectangle(Point((nQuarter * 2) + 2, 0), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1))); 86 } 87 88 return maTopRight; 89 } 90 getRight() const91 const BitmapEx& DiscreteShadow::getRight() const 92 { 93 if(maRight.IsEmpty()) 94 { 95 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); 96 const_cast< DiscreteShadow* >(this)->maRight = getBitmapEx(); 97 const_cast< DiscreteShadow* >(this)->maRight.Crop( 98 ::tools::Rectangle(Point((nQuarter * 3) + 3, (nQuarter * 2) + 1), Size(nQuarter, 1))); 99 } 100 101 return maRight; 102 } 103 getBottomRight() const104 const BitmapEx& DiscreteShadow::getBottomRight() const 105 { 106 if(maBottomRight.IsEmpty()) 107 { 108 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); 109 const_cast< DiscreteShadow* >(this)->maBottomRight = getBitmapEx(); 110 const_cast< DiscreteShadow* >(this)->maBottomRight.Crop( 111 ::tools::Rectangle(Point((nQuarter * 2) + 2, (nQuarter * 2) + 2), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1))); 112 } 113 114 return maBottomRight; 115 } 116 getBottom() const117 const BitmapEx& DiscreteShadow::getBottom() const 118 { 119 if(maBottom.IsEmpty()) 120 { 121 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); 122 const_cast< DiscreteShadow* >(this)->maBottom = getBitmapEx(); 123 const_cast< DiscreteShadow* >(this)->maBottom.Crop( 124 ::tools::Rectangle(Point((nQuarter * 2) + 1, (nQuarter * 3) + 3), Size(1, nQuarter))); 125 } 126 127 return maBottom; 128 } 129 getBottomLeft() const130 const BitmapEx& DiscreteShadow::getBottomLeft() const 131 { 132 if(maBottomLeft.IsEmpty()) 133 { 134 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); 135 const_cast< DiscreteShadow* >(this)->maBottomLeft = getBitmapEx(); 136 const_cast< DiscreteShadow* >(this)->maBottomLeft.Crop( 137 ::tools::Rectangle(Point(0, (nQuarter * 2) + 2), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1))); 138 } 139 140 return maBottomLeft; 141 } 142 getLeft() const143 const BitmapEx& DiscreteShadow::getLeft() const 144 { 145 if(maLeft.IsEmpty()) 146 { 147 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2); 148 const_cast< DiscreteShadow* >(this)->maLeft = getBitmapEx(); 149 const_cast< DiscreteShadow* >(this)->maLeft.Crop( 150 ::tools::Rectangle(Point(0, (nQuarter * 2) + 1), Size(nQuarter, 1))); 151 } 152 153 return maLeft; 154 } 155 156 } // end of namespace primitive2d 157 } // end of namespace drawinglayer 158 159 160 namespace drawinglayer 161 { 162 namespace primitive2d 163 { create2DDecomposition(Primitive2DContainer & rContainer,const geometry::ViewInformation2D &) const164 void DiscreteShadowPrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const 165 { 166 Primitive2DContainer xRetval; 167 168 if(!getDiscreteShadow().getBitmapEx().IsEmpty()) 169 { 170 const sal_Int32 nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2); 171 const basegfx::B2DVector aScale(getTransform() * basegfx::B2DVector(1.0, 1.0)); 172 const double fSingleX(getDiscreteUnit() / aScale.getX()); 173 const double fSingleY(getDiscreteUnit() / aScale.getY()); 174 const double fBorderX(fSingleX * nQuarter); 175 const double fBorderY(fSingleY * nQuarter); 176 const double fBigLenX((fBorderX * 2.0) + fSingleX); 177 const double fBigLenY((fBorderY * 2.0) + fSingleY); 178 179 xRetval.resize(8); 180 181 // TopLeft 182 xRetval[0] = Primitive2DReference( 183 new BitmapPrimitive2D( 184 getDiscreteShadow().getTopLeft(), 185 basegfx::utils::createScaleTranslateB2DHomMatrix( 186 fBigLenX, 187 fBigLenY, 188 -fBorderX, 189 -fBorderY))); 190 191 // Top 192 xRetval[1] = Primitive2DReference( 193 new BitmapPrimitive2D( 194 getDiscreteShadow().getTop(), 195 basegfx::utils::createScaleTranslateB2DHomMatrix( 196 1.0 - (2.0 * (fBorderX + fSingleX)) + fSingleX, 197 fBorderY, 198 fBorderX + fSingleX, 199 -fBorderY))); 200 201 // TopRight 202 xRetval[2] = Primitive2DReference( 203 new BitmapPrimitive2D( 204 getDiscreteShadow().getTopRight(), 205 basegfx::utils::createScaleTranslateB2DHomMatrix( 206 fBigLenX, 207 fBigLenY, 208 1.0 - fBorderX, 209 -fBorderY))); 210 211 // Right 212 xRetval[3] = Primitive2DReference( 213 new BitmapPrimitive2D( 214 getDiscreteShadow().getRight(), 215 basegfx::utils::createScaleTranslateB2DHomMatrix( 216 fBorderX, 217 1.0 - (2.0 * (fBorderY + fSingleY)) + fSingleY, 218 1.0 + fSingleX, 219 fBorderY + fSingleY))); 220 221 // BottomRight 222 xRetval[4] = Primitive2DReference( 223 new BitmapPrimitive2D( 224 getDiscreteShadow().getBottomRight(), 225 basegfx::utils::createScaleTranslateB2DHomMatrix( 226 fBigLenX, 227 fBigLenY, 228 1.0 - (fBorderX + fSingleX) + fSingleX, 229 1.0 - (fBorderY + fSingleY) + fSingleY))); 230 231 // Bottom 232 xRetval[5] = Primitive2DReference( 233 new BitmapPrimitive2D( 234 getDiscreteShadow().getBottom(), 235 basegfx::utils::createScaleTranslateB2DHomMatrix( 236 1.0 - (2.0 * (fBorderX + fSingleX)) + fSingleX, 237 fBorderY, 238 fBorderX + fSingleX, 239 1.0 + fSingleY))); 240 241 // BottomLeft 242 xRetval[6] = Primitive2DReference( 243 new BitmapPrimitive2D( 244 getDiscreteShadow().getBottomLeft(), 245 basegfx::utils::createScaleTranslateB2DHomMatrix( 246 fBigLenX, 247 fBigLenY, 248 -fBorderX, 249 1.0 - fBorderY))); 250 251 // Left 252 xRetval[7] = Primitive2DReference( 253 new BitmapPrimitive2D( 254 getDiscreteShadow().getLeft(), 255 basegfx::utils::createScaleTranslateB2DHomMatrix( 256 fBorderX, 257 1.0 - (2.0 * (fBorderY + fSingleY)) + fSingleY, 258 -fBorderX, 259 fBorderY + fSingleY))); 260 261 // put all in object transformation to get to target positions 262 rContainer.push_back( 263 new TransformPrimitive2D( 264 getTransform(), 265 xRetval)); 266 } 267 } 268 DiscreteShadowPrimitive2D(const basegfx::B2DHomMatrix & rTransform,const DiscreteShadow & rDiscreteShadow)269 DiscreteShadowPrimitive2D::DiscreteShadowPrimitive2D( 270 const basegfx::B2DHomMatrix& rTransform, 271 const DiscreteShadow& rDiscreteShadow) 272 : DiscreteMetricDependentPrimitive2D(), 273 maTransform(rTransform), 274 maDiscreteShadow(rDiscreteShadow) 275 { 276 } 277 operator ==(const BasePrimitive2D & rPrimitive) const278 bool DiscreteShadowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 279 { 280 if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) 281 { 282 const DiscreteShadowPrimitive2D& rCompare = static_cast<const DiscreteShadowPrimitive2D&>(rPrimitive); 283 284 return (getTransform() == rCompare.getTransform() 285 && getDiscreteShadow() == rCompare.getDiscreteShadow()); 286 } 287 288 return false; 289 } 290 getB2DRange(const geometry::ViewInformation2D & rViewInformation) const291 basegfx::B2DRange DiscreteShadowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 292 { 293 if(getDiscreteShadow().getBitmapEx().IsEmpty()) 294 { 295 // no graphics without valid bitmap definition 296 return basegfx::B2DRange(); 297 } 298 else 299 { 300 // prepare normal objectrange 301 basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0); 302 aRetval.transform(getTransform()); 303 304 // extract discrete shadow size and grow 305 const basegfx::B2DVector aScale(rViewInformation.getViewTransformation() * basegfx::B2DVector(1.0, 1.0)); 306 const sal_Int32 nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2); 307 const double fGrowX((1.0 / aScale.getX()) * nQuarter); 308 const double fGrowY((1.0 / aScale.getY()) * nQuarter); 309 aRetval.grow(std::max(fGrowX, fGrowY)); 310 311 return aRetval; 312 } 313 } 314 315 // provide unique ID 316 ImplPrimitive2DIDBlock(DiscreteShadowPrimitive2D, PRIMITIVE2D_ID_DISCRETESHADOWPRIMITIVE2D) 317 318 } // end of namespace primitive2d 319 } // end of namespace drawinglayer 320 321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 322