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 3, // same default as VCL, a minimum of three discrete units (pixels) offset 240 false); 241 const Primitive2DReference aPrimitive( 242 new PolyPolygonHatchPrimitive2D( 243 aHatchPolyPolygon, 244 aEmptyColor, 245 aFillHatchAttribute)); 246 247 aRetval = Primitive2DSequence(&aPrimitive, 1); 248 } 249 250 return aRetval; 251 } 252 253 bool OverlayHatchRectanglePrimitive::operator==( const BasePrimitive2D& rPrimitive ) const 254 { 255 if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive)) 256 { 257 const OverlayHatchRectanglePrimitive& rCompare = static_cast< const OverlayHatchRectanglePrimitive& >(rPrimitive); 258 259 return (getObjectRange() == rCompare.getObjectRange() 260 && getDiscreteHatchDistance() == rCompare.getDiscreteHatchDistance() 261 && getHatchRotation() == rCompare.getHatchRotation() 262 && getHatchColor() == rCompare.getHatchColor() 263 && getDiscreteGrow() == rCompare.getDiscreteGrow() 264 && getDiscreteShrink() == rCompare.getDiscreteShrink() 265 && getRotation() == rCompare.getRotation()); 266 } 267 268 return false; 269 } 270 271 ImplPrimitrive2DIDBlock(OverlayHatchRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYHATCHRECTANGLEPRIMITIVE) 272 273 } // end of namespace primitive2d 274 } // end of namespace drawinglayer 275 276 ////////////////////////////////////////////////////////////////////////////// 277 278 namespace drawinglayer 279 { 280 namespace primitive2d 281 { 282 OverlayHelplineStripedPrimitive::OverlayHelplineStripedPrimitive( 283 const basegfx::B2DPoint& rBasePosition, 284 HelplineStyle eStyle, 285 const basegfx::BColor& rRGBColorA, 286 const basegfx::BColor& rRGBColorB, 287 double fDiscreteDashLength) 288 : ViewportDependentPrimitive2D(), 289 maBasePosition(rBasePosition), 290 meStyle(eStyle), 291 maRGBColorA(rRGBColorA), 292 maRGBColorB(rRGBColorB), 293 mfDiscreteDashLength(fDiscreteDashLength) 294 {} 295 296 Primitive2DSequence OverlayHelplineStripedPrimitive::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 297 { 298 // use the prepared Viewport information accessible using getViewport() 299 Primitive2DSequence aRetval; 300 301 if(!getViewport().isEmpty()) 302 { 303 switch(getStyle()) 304 { 305 case HELPLINESTYLE_VERTICAL : 306 { 307 aRetval.realloc(1); 308 basegfx::B2DPolygon aLine; 309 310 aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY())); 311 aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY())); 312 313 aRetval[0] = Primitive2DReference( 314 new PolygonMarkerPrimitive2D( 315 aLine, 316 getRGBColorA(), 317 getRGBColorB(), 318 getDiscreteDashLength())); 319 break; 320 } 321 322 case HELPLINESTYLE_HORIZONTAL : 323 { 324 aRetval.realloc(1); 325 basegfx::B2DPolygon aLine; 326 327 aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY())); 328 aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY())); 329 330 aRetval[0] = Primitive2DReference( 331 new PolygonMarkerPrimitive2D( 332 aLine, 333 getRGBColorA(), 334 getRGBColorB(), 335 getDiscreteDashLength())); 336 break; 337 } 338 339 default: // case HELPLINESTYLE_POINT : 340 { 341 const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength()); 342 aRetval.realloc(2); 343 basegfx::B2DPolygon aLineA, aLineB; 344 345 aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() - fDiscreteUnit)); 346 aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() + fDiscreteUnit)); 347 348 aRetval[0] = Primitive2DReference( 349 new PolygonMarkerPrimitive2D( 350 aLineA, 351 getRGBColorA(), 352 getRGBColorB(), 353 getDiscreteDashLength())); 354 355 aLineB.append(basegfx::B2DPoint(getBasePosition().getX() - fDiscreteUnit, getBasePosition().getY())); 356 aLineB.append(basegfx::B2DPoint(getBasePosition().getX() + fDiscreteUnit, getBasePosition().getY())); 357 358 aRetval[1] = Primitive2DReference( 359 new PolygonMarkerPrimitive2D( 360 aLineB, 361 getRGBColorA(), 362 getRGBColorB(), 363 getDiscreteDashLength())); 364 365 break; 366 } 367 } 368 } 369 370 return aRetval; 371 } 372 373 bool OverlayHelplineStripedPrimitive::operator==( const BasePrimitive2D& rPrimitive ) const 374 { 375 if(ViewportDependentPrimitive2D::operator==(rPrimitive)) 376 { 377 const OverlayHelplineStripedPrimitive& rCompare = static_cast< const OverlayHelplineStripedPrimitive& >(rPrimitive); 378 379 return (getBasePosition() == rCompare.getBasePosition() 380 && getStyle() == rCompare.getStyle() 381 && getRGBColorA() == rCompare.getRGBColorA() 382 && getRGBColorB() == rCompare.getRGBColorB() 383 && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 384 } 385 386 return false; 387 } 388 389 ImplPrimitrive2DIDBlock(OverlayHelplineStripedPrimitive, PRIMITIVE2D_ID_OVERLAYHELPLINESTRIPEDPRIMITIVE) 390 391 } // end of namespace primitive2d 392 } // end of namespace drawinglayer 393 394 ////////////////////////////////////////////////////////////////////////////// 395 396 namespace drawinglayer 397 { 398 namespace primitive2d 399 { 400 OverlayRollingRectanglePrimitive::OverlayRollingRectanglePrimitive( 401 const basegfx::B2DRange& aRollingRectangle, 402 const basegfx::BColor& rRGBColorA, 403 const basegfx::BColor& rRGBColorB, 404 double fDiscreteDashLength) 405 : ViewportDependentPrimitive2D(), 406 maRollingRectangle(aRollingRectangle), 407 maRGBColorA(rRGBColorA), 408 maRGBColorB(rRGBColorB), 409 mfDiscreteDashLength(fDiscreteDashLength) 410 {} 411 412 Primitive2DSequence OverlayRollingRectanglePrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 413 { 414 // use the prepared Viewport information accessible using getViewport() 415 Primitive2DSequence aRetval; 416 417 if(!getViewport().isEmpty()) 418 { 419 basegfx::B2DPolygon aLine; 420 aRetval.realloc(8); 421 422 // Left lines 423 aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMinY())); 424 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY())); 425 aRetval[0] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 426 427 aLine.clear(); 428 aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMaxY())); 429 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY())); 430 aRetval[1] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 431 432 // Right lines 433 aLine.clear(); 434 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY())); 435 aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMinY())); 436 aRetval[2] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 437 438 aLine.clear(); 439 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY())); 440 aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMaxY())); 441 aRetval[3] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 442 443 // Top lines 444 aLine.clear(); 445 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMinY())); 446 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY())); 447 aRetval[4] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 448 449 aLine.clear(); 450 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMinY())); 451 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY())); 452 aRetval[5] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 453 454 // Bottom lines 455 aLine.clear(); 456 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY())); 457 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMaxY())); 458 aRetval[6] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 459 460 aLine.clear(); 461 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY())); 462 aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMaxY())); 463 aRetval[7] = Primitive2DReference(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength())); 464 } 465 466 return aRetval; 467 } 468 469 bool OverlayRollingRectanglePrimitive::operator==( const BasePrimitive2D& rPrimitive ) const 470 { 471 if(ViewportDependentPrimitive2D::operator==(rPrimitive)) 472 { 473 const OverlayRollingRectanglePrimitive& rCompare = static_cast< const OverlayRollingRectanglePrimitive& >(rPrimitive); 474 475 return (getRollingRectangle() == rCompare.getRollingRectangle() 476 && getRGBColorA() == rCompare.getRGBColorA() 477 && getRGBColorB() == rCompare.getRGBColorB() 478 && getDiscreteDashLength() == rCompare.getDiscreteDashLength()); 479 } 480 481 return false; 482 } 483 484 ImplPrimitrive2DIDBlock(OverlayRollingRectanglePrimitive, PRIMITIVE2D_ID_OVERLAYROLLINGRECTANGLEPRIMITIVE) 485 486 } // end of namespace primitive2d 487 } // end of namespace drawinglayer 488 489 ////////////////////////////////////////////////////////////////////////////// 490 // eof 491