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_svx.hxx" 26 27 #include <svx/sdr/overlay/overlaytools.hxx> 28 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> 29 #include <basegfx/matrix/b2dhommatrix.hxx> 30 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> 31 #include <basegfx/polygon/b2dpolygon.hxx> 32 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> 33 #include <basegfx/polygon/b2dpolygontools.hxx> 34 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> 35 #include <drawinglayer/geometry/viewinformation2d.hxx> 36 #include <basegfx/matrix/b2dhommatrixtools.hxx> 37 38 ////////////////////////////////////////////////////////////////////////////// 39 40 namespace drawinglayer 41 { 42 namespace primitive2d 43 { 44 OverlayBitmapExPrimitive::OverlayBitmapExPrimitive( 45 const BitmapEx& rBitmapEx, 46 const basegfx::B2DPoint& rBasePosition, 47 sal_uInt16 nCenterX, 48 sal_uInt16 nCenterY) 49 : DiscreteMetricDependentPrimitive2D(), 50 maBitmapEx(rBitmapEx), 51 maBasePosition(rBasePosition), 52 mnCenterX(nCenterX), 53 mnCenterY(nCenterY) 54 {} 55 56 Primitive2DSequence OverlayBitmapExPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 57 { 58 Primitive2DSequence aRetval; 59 const Size aBitmapSize(getBitmapEx().GetSizePixel()); 60 61 if(aBitmapSize.Width() && aBitmapSize.Height() && basegfx::fTools::more(getDiscreteUnit(), 0.0)) 62 { 63 // calculate back from internal bitmap's extreme coordinates (the edges) 64 // to logical coordinates. Only use a unified scaling value (getDiscreteUnit(), 65 // the prepared one which expresses how many logic units form a discrete unit) 66 // for this step. This primitive is to be displayed always unscaled (in it's pixel size) 67 // and unrotated, more like a marker 68 const double fLeft(((0.0 - getCenterX()) * getDiscreteUnit()) + getBasePosition().getX()); 69 const double fTop(((0.0 - getCenterY()) * getDiscreteUnit()) + getBasePosition().getY()); 70 const double fRight((((aBitmapSize.getWidth() - 1.0) - getCenterX()) * getDiscreteUnit()) + getBasePosition().getX()); 71 const double fBottom((((aBitmapSize.getHeight() - 1.0) - getCenterY()) * getDiscreteUnit()) + getBasePosition().getY()); 72 73 // create a BitmapPrimitive2D using those positions 74 basegfx::B2DHomMatrix aTransform; 75 76 aTransform.set(0, 0, fRight - fLeft); 77 aTransform.set(1, 1, fBottom - fTop); 78 aTransform.set(0, 2, fLeft); 79 aTransform.set(1, 2, fTop); 80 81 const Primitive2DReference aPrimitive(new BitmapPrimitive2D(getBitmapEx(), aTransform)); 82 aRetval = Primitive2DSequence(&aPrimitive, 1); 83 } 84 85 return aRetval; 86 } 87 88 bool OverlayBitmapExPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const 89 { 90 if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) 91 { 92 const OverlayBitmapExPrimitive& rCompare = static_cast< const OverlayBitmapExPrimitive& >(rPrimitive); 93 94 return (getBitmapEx() == rCompare.getBitmapEx() 95 && getBasePosition() == rCompare.getBasePosition() 96 && getCenterX() == rCompare.getCenterX() 97 && getCenterY() == rCompare.getCenterY()); 98 } 99 100 return false; 101 } 102 103 ImplPrimitrive2DIDBlock(OverlayBitmapExPrimitive, PRIMITIVE2D_ID_OVERLAYBITMAPEXPRIMITIVE) 104 105 } // end of namespace primitive2d 106 } // end of namespace drawinglayer 107 108 ////////////////////////////////////////////////////////////////////////////// 109 110 namespace drawinglayer 111 { 112 namespace primitive2d 113 { 114 OverlayCrosshairPrimitive::OverlayCrosshairPrimitive( 115 const basegfx::B2DPoint& rBasePosition, 116 const basegfx::BColor& rRGBColorA, 117 const basegfx::BColor& rRGBColorB, 118 double fDiscreteDashLength) 119 : ViewportDependentPrimitive2D(), 120 maBasePosition(rBasePosition), 121 maRGBColorA(rRGBColorA), 122 maRGBColorB(rRGBColorB), 123 mfDiscreteDashLength(fDiscreteDashLength) 124 {} 125 126 Primitive2DSequence OverlayCrosshairPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 127 { 128 // use the prepared Viewport information accessible using getViewport() 129 Primitive2DSequence aRetval; 130 131 if(!getViewport().isEmpty()) 132 { 133 aRetval.realloc(2); 134 basegfx::B2DPolygon aPolygon; 135 136 aPolygon.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY())); 137 aPolygon.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY())); 138 139 aRetval[0] = Primitive2DReference( 140 new PolygonMarkerPrimitive2D( 141 aPolygon, 142 getRGBColorA(), 143 getRGBColorB(), 144 getDiscreteDashLength())); 145 146 aPolygon.clear(); 147 aPolygon.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY())); 148 aPolygon.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY())); 149 150 aRetval[1] = Primitive2DReference( 151 new PolygonMarkerPrimitive2D( 152 aPolygon, 153 getRGBColorA(), 154 getRGBColorB(), 155 getDiscreteDashLength())); 156 } 157 158 return aRetval; 159 } 160 161 bool OverlayCrosshairPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const 162 { 163 if(ViewportDependentPrimitive2D::operator==(rPrimitive)) 164 { 165 const OverlayCrosshairPrimitive& rCompare = static_cast< const OverlayCrosshairPrimitive& >(rPrimitive); 166 167 return (getBasePosition() == rCompare.getBasePosition() 168 && getRGBColorA() == rCompare.getRGBColorA() 169 && getRGBColorB() == rCompare.getRGBColorB() 170 && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 171 } 172 173 return false; 174 } 175 176 ImplPrimitrive2DIDBlock(OverlayCrosshairPrimitive, PRIMITIVE2D_ID_OVERLAYCROSSHAIRPRIMITIVE) 177 178 } // end of namespace primitive2d 179 } // end of namespace drawinglayer 180 181 ////////////////////////////////////////////////////////////////////////////// 182 183 namespace drawinglayer 184 { 185 namespace primitive2d 186 { 187 OverlayHatchRectanglePrimitive::OverlayHatchRectanglePrimitive( 188 const basegfx::B2DRange& rObjectRange, 189 double fDiscreteHatchDistance, 190 double fHatchRotation, 191 const basegfx::BColor& rHatchColor, 192 double fDiscreteGrow, 193 double fDiscreteShrink, 194 double fRotation) 195 : DiscreteMetricDependentPrimitive2D(), 196 maObjectRange(rObjectRange), 197 mfDiscreteHatchDistance(fDiscreteHatchDistance), 198 mfHatchRotation(fHatchRotation), 199 maHatchColor(rHatchColor), 200 mfDiscreteGrow(fDiscreteGrow), 201 mfDiscreteShrink(fDiscreteShrink), 202 mfRotation(fRotation) 203 {} 204 205 Primitive2DSequence OverlayHatchRectanglePrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 206 { 207 Primitive2DSequence aRetval; 208 209 if(basegfx::fTools::more(getDiscreteUnit(), 0.0)) 210 { 211 basegfx::B2DRange aInnerRange(getObjectRange()); 212 basegfx::B2DRange aOuterRange(getObjectRange()); 213 basegfx::B2DPolyPolygon aHatchPolyPolygon; 214 215 aOuterRange.grow(getDiscreteUnit() * getDiscreteGrow()); 216 aInnerRange.grow(getDiscreteUnit() * -getDiscreteShrink()); 217 218 aHatchPolyPolygon.append(basegfx::tools::createPolygonFromRect(aOuterRange)); 219 220 if(!aInnerRange.isEmpty()) 221 { 222 aHatchPolyPolygon.append(basegfx::tools::createPolygonFromRect(aInnerRange)); 223 } 224 225 if(!basegfx::fTools::equalZero(getRotation())) 226 { 227 const basegfx::B2DHomMatrix aTransform(basegfx::tools::createRotateAroundPoint( 228 getObjectRange().getMinX(), getObjectRange().getMinY(), getRotation())); 229 230 aHatchPolyPolygon.transform(aTransform); 231 } 232 233 const basegfx::BColor aEmptyColor(0.0, 0.0, 0.0); 234 const drawinglayer::attribute::FillHatchAttribute aFillHatchAttribute( 235 drawinglayer::attribute::HATCHSTYLE_SINGLE, 236 getDiscreteHatchDistance() * getDiscreteUnit(), 237 getHatchRotation() - getRotation(), 238 getHatchColor(), 239 false); 240 const Primitive2DReference aPrimitive( 241 new PolyPolygonHatchPrimitive2D( 242 aHatchPolyPolygon, 243 aEmptyColor, 244 aFillHatchAttribute)); 245 246 aRetval = Primitive2DSequence(&aPrimitive, 1); 247 } 248 249 return aRetval; 250 } 251 252 bool OverlayHatchRectanglePrimitive::operator==( const BasePrimitive2D& rPrimitive ) const 253 { 254 if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) 255 { 256 const OverlayHatchRectanglePrimitive& rCompare = static_cast< const OverlayHatchRectanglePrimitive& >(rPrimitive); 257 258 return (getObjectRange() == rCompare.getObjectRange() 259 && getDiscreteHatchDistance() == rCompare.getDiscreteHatchDistance() 260 && getHatchRotation() == rCompare.getHatchRotation() 261 && getHatchColor() == rCompare.getHatchColor() 262 && getDiscreteGrow() == rCompare.getDiscreteGrow() 263 && getDiscreteShrink() == rCompare.getDiscreteShrink() 264 && getRotation() == rCompare.getRotation()); 265 } 266 267 return false; 268 } 269 270 ImplPrimitrive2DIDBlock(OverlayHatchRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYHATCHRECTANGLEPRIMITIVE) 271 272 } // end of namespace primitive2d 273 } // end of namespace drawinglayer 274 275 ////////////////////////////////////////////////////////////////////////////// 276 277 namespace drawinglayer 278 { 279 namespace primitive2d 280 { 281 OverlayHelplineStripedPrimitive::OverlayHelplineStripedPrimitive( 282 const basegfx::B2DPoint& rBasePosition, 283 HelplineStyle eStyle, 284 const basegfx::BColor& rRGBColorA, 285 const basegfx::BColor& rRGBColorB, 286 double fDiscreteDashLength) 287 : ViewportDependentPrimitive2D(), 288 maBasePosition(rBasePosition), 289 meStyle(eStyle), 290 maRGBColorA(rRGBColorA), 291 maRGBColorB(rRGBColorB), 292 mfDiscreteDashLength(fDiscreteDashLength) 293 {} 294 295 Primitive2DSequence OverlayHelplineStripedPrimitive::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 296 { 297 // use the prepared Viewport information accessible using getViewport() 298 Primitive2DSequence aRetval; 299 300 if(!getViewport().isEmpty()) 301 { 302 switch(getStyle()) 303 { 304 case HELPLINESTYLE_VERTICAL : 305 { 306 aRetval.realloc(1); 307 basegfx::B2DPolygon aLine; 308 309 aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY())); 310 aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY())); 311 312 aRetval[0] = Primitive2DReference( 313 new PolygonMarkerPrimitive2D( 314 aLine, 315 getRGBColorA(), 316 getRGBColorB(), 317 getDiscreteDashLength())); 318 break; 319 } 320 321 case HELPLINESTYLE_HORIZONTAL : 322 { 323 aRetval.realloc(1); 324 basegfx::B2DPolygon aLine; 325 326 aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY())); 327 aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY())); 328 329 aRetval[0] = Primitive2DReference( 330 new PolygonMarkerPrimitive2D( 331 aLine, 332 getRGBColorA(), 333 getRGBColorB(), 334 getDiscreteDashLength())); 335 break; 336 } 337 338 default: // case HELPLINESTYLE_POINT : 339 { 340 const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength()); 341 aRetval.realloc(2); 342 basegfx::B2DPolygon aLineA, aLineB; 343 344 aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() - fDiscreteUnit)); 345 aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() + fDiscreteUnit)); 346 347 aRetval[0] = Primitive2DReference( 348 new PolygonMarkerPrimitive2D( 349 aLineA, 350 getRGBColorA(), 351 getRGBColorB(), 352 getDiscreteDashLength())); 353 354 aLineB.append(basegfx::B2DPoint(getBasePosition().getX() - fDiscreteUnit, getBasePosition().getY())); 355 aLineB.append(basegfx::B2DPoint(getBasePosition().getX() + fDiscreteUnit, getBasePosition().getY())); 356 357 aRetval[1] = Primitive2DReference( 358 new PolygonMarkerPrimitive2D( 359 aLineB, 360 getRGBColorA(), 361 getRGBColorB(), 362 getDiscreteDashLength())); 363 364 break; 365 } 366 } 367 } 368 369 return aRetval; 370 } 371 372 bool OverlayHelplineStripedPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const 373 { 374 if(ViewportDependentPrimitive2D::operator==(rPrimitive)) 375 { 376 const OverlayHelplineStripedPrimitive& rCompare = static_cast< const OverlayHelplineStripedPrimitive& >(rPrimitive); 377 378 return (getBasePosition() == rCompare.getBasePosition() 379 && getStyle() == rCompare.getStyle() 380 && getRGBColorA() == rCompare.getRGBColorA() 381 && getRGBColorB() == rCompare.getRGBColorB() 382 && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 383 } 384 385 return false; 386 } 387 388 ImplPrimitrive2DIDBlock(OverlayHelplineStripedPrimitive, PRIMITIVE2D_ID_OVERLAYHELPLINESTRIPEDPRIMITIVE) 389 390 } // end of namespace primitive2d 391 } // end of namespace drawinglayer 392 393 ////////////////////////////////////////////////////////////////////////////// 394 395 namespace drawinglayer 396 { 397 namespace primitive2d 398 { 399 OverlayRollingRectanglePrimitive::OverlayRollingRectanglePrimitive( 400 const basegfx::B2DRange& aRollingRectangle, 401 const basegfx::BColor& rRGBColorA, 402 const basegfx::BColor& rRGBColorB, 403 double fDiscreteDashLength) 404 : ViewportDependentPrimitive2D(), 405 maRollingRectangle(aRollingRectangle), 406 maRGBColorA(rRGBColorA), 407 maRGBColorB(rRGBColorB), 408 mfDiscreteDashLength(fDiscreteDashLength) 409 {} 410 411 Primitive2DSequence OverlayRollingRectanglePrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 412 { 413 // use the prepared Viewport information accessible using getViewport() 414 Primitive2DSequence aRetval; 415 416 if(!getViewport().isEmpty()) 417 { 418 basegfx::B2DPolygon aLine; 419 aRetval.realloc(8); 420 421 // Left lines 422 aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMinY())); 423 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY())); 424 aRetval[0] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 425 426 aLine.clear(); 427 aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMaxY())); 428 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY())); 429 aRetval[1] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 430 431 // Right lines 432 aLine.clear(); 433 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY())); 434 aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMinY())); 435 aRetval[2] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 436 437 aLine.clear(); 438 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY())); 439 aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMaxY())); 440 aRetval[3] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 441 442 // Top lines 443 aLine.clear(); 444 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMinY())); 445 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY())); 446 aRetval[4] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 447 448 aLine.clear(); 449 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMinY())); 450 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY())); 451 aRetval[5] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 452 453 // Bottom lines 454 aLine.clear(); 455 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY())); 456 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMaxY())); 457 aRetval[6] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 458 459 aLine.clear(); 460 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY())); 461 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMaxY())); 462 aRetval[7] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 463 } 464 465 return aRetval; 466 } 467 468 bool OverlayRollingRectanglePrimitive::operator==( const BasePrimitive2D& rPrimitive ) const 469 { 470 if(ViewportDependentPrimitive2D::operator==(rPrimitive)) 471 { 472 const OverlayRollingRectanglePrimitive& rCompare = static_cast< const OverlayRollingRectanglePrimitive& >(rPrimitive); 473 474 return (getRollingRectangle() == rCompare.getRollingRectangle() 475 && getRGBColorA() == rCompare.getRGBColorA() 476 && getRGBColorB() == rCompare.getRGBColorB() 477 && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 478 } 479 480 return false; 481 } 482 483 ImplPrimitrive2DIDBlock(OverlayRollingRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYROLLINGRECTANGLEPRIMITIVE) 484 485 } // end of namespace primitive2d 486 } // end of namespace drawinglayer 487 488 ////////////////////////////////////////////////////////////////////////////// 489 // eof 490