LibreOffice Module svx (master)  1
overlaytools.cxx
Go to the documentation of this file.
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 
32 #include <vcl/svapp.hxx>
33 #include <vcl/settings.hxx>
34 
35 
37 {
38 
40  const basegfx::B2DPoint& rPosition,
41  const basegfx::B2DSize& rSize,
42  const basegfx::BColor& rStrokeColor,
43  const basegfx::BColor& rFillColor,
44  double fTransparence,
45  double fRotation)
47  , maPosition(rPosition)
48  , maSize(rSize)
49  , maStrokeColor(rStrokeColor)
50  , maFillColor(rFillColor)
51  , mfTransparence(fTransparence)
52  , mfRotation(fRotation)
53 {}
54 
56 {
57  Primitive2DContainer aPrimitive2DSequence;
58  const double fHalfWidth = maSize.getX() * getDiscreteUnit() / 2.0;
59  const double fHalfHeight = maSize.getY() * getDiscreteUnit() / 2.0;
60 
61  basegfx::B2DRange aRange(
62  maPosition.getX() - fHalfWidth, maPosition.getY() - fHalfHeight,
63  maPosition.getX() + fHalfWidth, maPosition.getY() + fHalfHeight);
64 
66  {
67  basegfx::B2DPolygon aPolygon(
69 
70  // create filled primitive
71  basegfx::B2DPolyPolygon aPolyPolygon;
72  aPolyPolygon.append(aPolygon);
73 
74  const attribute::LineAttribute aLineAttribute(maStrokeColor, 1.0);
75 
76  // create data
77  const Primitive2DReference aStroke(
78  new PolyPolygonStrokePrimitive2D(aPolyPolygon, aLineAttribute));
79 
80  // create fill primitive
81  const Primitive2DReference aFill(
82  new PolyPolygonColorPrimitive2D(aPolyPolygon, maFillColor));
83 
84  aPrimitive2DSequence = Primitive2DContainer(2);
85  aPrimitive2DSequence[0] = aFill;
86  aPrimitive2DSequence[1] = aStroke;
87 
88  // embed filled to transparency (if used)
89  if (mfTransparence > 0.0)
90  {
91  const Primitive2DReference aFillTransparent(
93  aPrimitive2DSequence,
95 
96  aPrimitive2DSequence = Primitive2DContainer { aFillTransparent };
97  }
98  }
99 
100  rContainer.insert(rContainer.end(), aPrimitive2DSequence.begin(), aPrimitive2DSequence.end());
101 }
102 
104 {
105  if (DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
106  {
107  const OverlayStaticRectanglePrimitive& rCompare = static_cast<const OverlayStaticRectanglePrimitive&>(rPrimitive);
108 
109  return (maPosition == rCompare.maPosition
110  && maSize == rCompare.maSize
111  && maStrokeColor == rCompare.maStrokeColor
112  && maFillColor == rCompare.maFillColor
113  && mfTransparence == rCompare.mfTransparence
114  && mfRotation == rCompare.mfRotation);
115  }
116 
117  return false;
118 }
119 
121 
122 
123 
125  const BitmapEx& rBitmapEx,
126  const basegfx::B2DPoint& rBasePosition,
127  sal_uInt16 nCenterX,
128  sal_uInt16 nCenterY,
129  double fShearX,
130  double fRotation)
132  maBitmapEx(rBitmapEx),
133  maBasePosition(rBasePosition),
134  mnCenterX(nCenterX),
135  mnCenterY(nCenterY),
136  mfShearX(fShearX),
137  mfRotation(fRotation)
138  {}
139 
141  {
142  const Size aBitmapSize(getBitmapEx().GetSizePixel());
143 
144  if(!aBitmapSize.Width() || !aBitmapSize.Height() || !basegfx::fTools::more(getDiscreteUnit(), 0.0))
145  return;
146 
147  // calculate back from internal bitmap's extreme coordinates (the edges)
148  // to logical coordinates. Only use a unified scaling value (getDiscreteUnit(),
149  // the prepared one which expresses how many logic units form a discrete unit)
150  // for this step. This primitive is to be displayed always unscaled (in its pixel size)
151  // and unrotated, more like a marker
152  const double fLeft((0.0 - getCenterX()) * getDiscreteUnit());
153  const double fTop((0.0 - getCenterY()) * getDiscreteUnit());
154  const double fRight((aBitmapSize.getWidth() - getCenterX()) * getDiscreteUnit());
155  const double fBottom((aBitmapSize.getHeight() - getCenterY()) * getDiscreteUnit());
156 
157  // create a BitmapPrimitive2D using those positions
158  basegfx::B2DHomMatrix aTransform;
159 
160  aTransform.set(0, 0, fRight - fLeft);
161  aTransform.set(1, 1, fBottom - fTop);
162  aTransform.set(0, 2, fLeft);
163  aTransform.set(1, 2, fTop);
164 
165  // if shearX is used, apply it, too
167  {
168  aTransform.shearX(getShearX());
169  }
170 
171  // if rotation is used, apply it, too
173  {
174  aTransform.rotate(getRotation());
175  }
176 
177  // add BasePosition
178  aTransform.translate(getBasePosition().getX(), getBasePosition().getY());
179 
180  rContainer.push_back(new BitmapPrimitive2D(getBitmapEx(), aTransform));
181  }
182 
184  {
185  if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
186  {
187  const OverlayBitmapExPrimitive& rCompare = static_cast< const OverlayBitmapExPrimitive& >(rPrimitive);
188 
189  return (getBitmapEx() == rCompare.getBitmapEx()
190  && getBasePosition() == rCompare.getBasePosition()
191  && getCenterX() == rCompare.getCenterX()
192  && getCenterY() == rCompare.getCenterY()
193  && getShearX() == rCompare.getShearX()
194  && getRotation() == rCompare.getRotation());
195  }
196 
197  return false;
198  }
199 
201 
202 
203 
205  const basegfx::B2DPoint& rBasePosition,
206  const basegfx::BColor& rRGBColorA,
207  const basegfx::BColor& rRGBColorB,
208  double fDiscreteDashLength)
210  maBasePosition(rBasePosition),
211  maRGBColorA(rRGBColorA),
212  maRGBColorB(rRGBColorB),
213  mfDiscreteDashLength(fDiscreteDashLength)
214  {}
215 
217  {
218  // use the prepared Viewport information accessible using getViewport()
219 
220  if(!getViewport().isEmpty())
221  {
222  basegfx::B2DPolygon aPolygon;
223 
224  aPolygon.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY()));
225  aPolygon.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY()));
226 
227  rContainer.push_back(
229  aPolygon,
230  getRGBColorA(),
231  getRGBColorB(),
233 
234  aPolygon.clear();
235  aPolygon.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY()));
236  aPolygon.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY()));
237 
238  rContainer.push_back(
240  aPolygon,
241  getRGBColorA(),
242  getRGBColorB(),
244  }
245  }
246 
248  {
249  if(ViewportDependentPrimitive2D::operator==(rPrimitive))
250  {
251  const OverlayCrosshairPrimitive& rCompare = static_cast< const OverlayCrosshairPrimitive& >(rPrimitive);
252 
253  return (getBasePosition() == rCompare.getBasePosition()
254  && getRGBColorA() == rCompare.getRGBColorA()
255  && getRGBColorB() == rCompare.getRGBColorB()
256  && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
257  }
258 
259  return false;
260  }
261 
263 
264 
265 
267  const basegfx::B2DRange& rObjectRange,
268  const basegfx::BColor& rColor,
269  double fTransparence,
270  double fDiscreteGrow,
271  double fDiscreteShrink,
272  double fRotation)
274  maObjectRange(rObjectRange),
275  maColor(rColor),
276  mfTransparence(fTransparence),
277  mfDiscreteGrow(fDiscreteGrow),
278  mfDiscreteShrink(fDiscreteShrink),
279  mfRotation(fRotation)
280  {}
281 
283  {
284  Primitive2DContainer aRetval;
285  basegfx::B2DRange aInnerRange(getObjectRange());
286 
287  if(!aInnerRange.isEmpty() && basegfx::fTools::more(getDiscreteUnit(), 0.0) && getTransparence() <= 1.0)
288  {
289  basegfx::B2DRange aOuterRange(getObjectRange());
290 
291  // grow/shrink inner/outer polygons
292  aOuterRange.grow(getDiscreteUnit() * getDiscreteGrow());
293  aInnerRange.grow(getDiscreteUnit() * -getDiscreteShrink());
294 
295  // convert to polygons
296  const double fFullGrow(getDiscreteGrow() + getDiscreteShrink());
297  const double fRelativeRadiusX(fFullGrow / aOuterRange.getWidth());
298  const double fRelativeRadiusY(fFullGrow / aOuterRange.getHeight());
299  basegfx::B2DPolygon aOuterPolygon(
301  aOuterRange,
302  fRelativeRadiusX,
303  fRelativeRadiusY));
304  basegfx::B2DPolygon aInnerPolygon(
306  aInnerRange));
307 
308  // apply evtl. existing rotation
310  {
312  getObjectRange().getMinX(), getObjectRange().getMinY(), getRotation()));
313 
314  aOuterPolygon.transform(aTransform);
315  aInnerPolygon.transform(aTransform);
316  }
317 
318  // create filled primitive
319  basegfx::B2DPolyPolygon aPolyPolygon;
320 
321  aPolyPolygon.append(aOuterPolygon);
322  aPolyPolygon.append(aInnerPolygon);
323 
324  if(Application::GetSettings().GetStyleSettings().GetHighContrastMode())
325  {
326  // for high contrast, use hatch
327  const basegfx::BColor aHighContrastLineColor(Application::GetSettings().GetStyleSettings().GetFontColor().getBColor());
328  const basegfx::BColor aEmptyColor(0.0, 0.0, 0.0);
329  const double fHatchRotation(basegfx::deg2rad(45));
330  const double fDiscreteHatchDistance(3.0);
331  const drawinglayer::attribute::FillHatchAttribute aFillHatchAttribute(
333  fDiscreteHatchDistance * getDiscreteUnit(),
334  fHatchRotation - getRotation(),
335  aHighContrastLineColor,
336  3, // same default as VCL, a minimum of three discrete units (pixels) offset
337  false);
338  const Primitive2DReference aHatch(
340  aPolyPolygon,
341  aEmptyColor,
342  aFillHatchAttribute));
343 
344  aRetval = Primitive2DContainer { aHatch };
345  }
346  else
347  {
348  // create fill primitive
349  const Primitive2DReference aFill(
351  aPolyPolygon,
352  getColor()));
353 
354  aRetval = Primitive2DContainer { aFill };
355 
356  // embed filled to transparency (if used)
357  if(getTransparence() > 0.0)
358  {
359  const Primitive2DReference aFillTransparent(
361  aRetval,
362  getTransparence()));
363 
364  aRetval = Primitive2DContainer { aFillTransparent };
365  }
366  }
367  }
368 
369  rContainer.insert(rContainer.end(), aRetval.begin(), aRetval.end());
370  }
371 
373  {
374  if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
375  {
376  const OverlayRectanglePrimitive& rCompare = static_cast< const OverlayRectanglePrimitive& >(rPrimitive);
377 
378  return (getObjectRange() == rCompare.getObjectRange()
379  && getColor() == rCompare.getColor()
380  && getTransparence() == rCompare.getTransparence()
381  && getDiscreteGrow() == rCompare.getDiscreteGrow()
382  && getDiscreteShrink() == rCompare.getDiscreteShrink()
383  && getRotation() == rCompare.getRotation());
384  }
385 
386  return false;
387  }
388 
390 
391 
392 
394  const basegfx::B2DPoint& rBasePosition,
395  HelplineStyle eStyle,
396  const basegfx::BColor& rRGBColorA,
397  const basegfx::BColor& rRGBColorB,
398  double fDiscreteDashLength)
400  maBasePosition(rBasePosition),
401  meStyle(eStyle),
402  maRGBColorA(rRGBColorA),
403  maRGBColorB(rRGBColorB),
404  mfDiscreteDashLength(fDiscreteDashLength)
405  {}
406 
408  {
409  // use the prepared Viewport information accessible using getViewport()
410 
411  if(!getViewport().isEmpty())
412  {
413  switch(getStyle())
414  {
416  {
417  basegfx::B2DPolygon aLine;
418 
419  aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMinY()));
420  aLine.append(basegfx::B2DPoint(getBasePosition().getX(), getViewport().getMaxY()));
421 
422  rContainer.push_back(
424  aLine,
425  getRGBColorA(),
426  getRGBColorB(),
428  break;
429  }
430 
432  {
433  basegfx::B2DPolygon aLine;
434 
435  aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getBasePosition().getY()));
436  aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getBasePosition().getY()));
437 
438  rContainer.push_back(
440  aLine,
441  getRGBColorA(),
442  getRGBColorB(),
444  break;
445  }
446 
447  default: // case HELPLINESTYLE_POINT :
448  {
449  const double fDiscreteUnit((rViewInformation.getInverseObjectToViewTransformation() * basegfx::B2DVector(1.0, 0.0)).getLength());
450  basegfx::B2DPolygon aLineA, aLineB;
451 
452  aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() - fDiscreteUnit));
453  aLineA.append(basegfx::B2DPoint(getBasePosition().getX(), getBasePosition().getY() + fDiscreteUnit));
454 
455  rContainer.push_back(
457  aLineA,
458  getRGBColorA(),
459  getRGBColorB(),
461 
462  aLineB.append(basegfx::B2DPoint(getBasePosition().getX() - fDiscreteUnit, getBasePosition().getY()));
463  aLineB.append(basegfx::B2DPoint(getBasePosition().getX() + fDiscreteUnit, getBasePosition().getY()));
464 
465  rContainer.push_back(
467  aLineB,
468  getRGBColorA(),
469  getRGBColorB(),
471 
472  break;
473  }
474  }
475  }
476  }
477 
479  {
480  if(ViewportDependentPrimitive2D::operator==(rPrimitive))
481  {
482  const OverlayHelplineStripedPrimitive& rCompare = static_cast< const OverlayHelplineStripedPrimitive& >(rPrimitive);
483 
484  return (getBasePosition() == rCompare.getBasePosition()
485  && getStyle() == rCompare.getStyle()
486  && getRGBColorA() == rCompare.getRGBColorA()
487  && getRGBColorB() == rCompare.getRGBColorB()
488  && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
489  }
490 
491  return false;
492  }
493 
495 
496 
497 
499  const basegfx::B2DRange& aRollingRectangle,
500  const basegfx::BColor& rRGBColorA,
501  const basegfx::BColor& rRGBColorB,
502  double fDiscreteDashLength)
504  maRollingRectangle(aRollingRectangle),
505  maRGBColorA(rRGBColorA),
506  maRGBColorB(rRGBColorB),
507  mfDiscreteDashLength(fDiscreteDashLength)
508  {}
509 
511  {
512  // use the prepared Viewport information accessible using getViewport()
513 
514  if(getViewport().isEmpty())
515  return;
516 
517  basegfx::B2DPolygon aLine;
518 
519  // Left lines
520  aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMinY()));
521  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY()));
522  rContainer.push_back(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
523 
524  aLine.clear();
525  aLine.append(basegfx::B2DPoint(getViewport().getMinX(), getRollingRectangle().getMaxY()));
526  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY()));
527  rContainer.push_back(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
528 
529  // Right lines
530  aLine.clear();
531  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY()));
532  aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMinY()));
533  rContainer.push_back(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
534 
535  aLine.clear();
536  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY()));
537  aLine.append(basegfx::B2DPoint(getViewport().getMaxX(), getRollingRectangle().getMaxY()));
538  rContainer.push_back(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
539 
540  // Top lines
541  aLine.clear();
542  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMinY()));
543  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMinY()));
544  rContainer.push_back(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
545 
546  aLine.clear();
547  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMinY()));
548  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMinY()));
549  rContainer.push_back(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
550 
551  // Bottom lines
552  aLine.clear();
553  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getRollingRectangle().getMaxY()));
554  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMinX(), getViewport().getMaxY()));
555  rContainer.push_back(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
556 
557  aLine.clear();
558  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getRollingRectangle().getMaxY()));
559  aLine.append(basegfx::B2DPoint(getRollingRectangle().getMaxX(), getViewport().getMaxY()));
560  rContainer.push_back(new PolygonMarkerPrimitive2D(aLine, getRGBColorA(), getRGBColorB(), getDiscreteDashLength()));
561 
562  }
563 
565  {
566  if(ViewportDependentPrimitive2D::operator==(rPrimitive))
567  {
568  const OverlayRollingRectanglePrimitive& rCompare = static_cast< const OverlayRollingRectanglePrimitive& >(rPrimitive);
569 
570  return (getRollingRectangle() == rCompare.getRollingRectangle()
571  && getRGBColorA() == rCompare.getRGBColorA()
572  && getRGBColorB() == rCompare.getRGBColorB()
573  && getDiscreteDashLength() == rCompare.getDiscreteDashLength());
574  }
575 
576  return false;
577  }
578 
580 
581 } // end of namespace
582 
583 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
long Width() const
virtual bool operator==(const BasePrimitive2D &rPrimitive) const override
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
ImplPrimitive2DIDBlock(BorderLinePrimitive2D, PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D) Primitive2DReference tryMergeBorderLinePrimitive2D(const Primitive2DReference &rCandidateA
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
double getHeight() const
static bool more(const double &rfValA, const double &rfValB)
long Height() const
const basegfx::B2DRange & getViewport() const
#define PRIMITIVE2D_ID_OVERLAYBITMAPEXPRIMITIVE
static const AllSettings & GetSettings()
virtual void create2DDecomposition(Primitive2DContainer &rContainer, const geometry::ViewInformation2D &rViewInformation) const override
double getX() const
Color GetFontColor()
Definition: svdetc.hxx:67
double getY() const
geometry::RealPoint2D maPosition
const basegfx::B2DPoint & getBasePosition() const
const basegfx::B2DPoint & getBasePosition() const
double getWidth() const
#define PRIMITIVE2D_ID_OVERLAYRECTANGLEPRIMITIVE
virtual void create2DDecomposition(Primitive2DContainer &rContainer, const geometry::ViewInformation2D &rViewInformation) const override
void grow(double fValue)
virtual bool operator==(const BasePrimitive2D &rPrimitive) const override
bool isEmpty() const
virtual bool operator==(const BasePrimitive2D &rPrimitive) const override
virtual void create2DDecomposition(Primitive2DContainer &rContainer, const geometry::ViewInformation2D &rViewInformation) const override
#define PRIMITIVE2D_ID_OVERLAYROLLINGRECTANGLEPRIMITIVE
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
const basegfx::B2DRange & getObjectRange() const
static bool equalZero(const double &rfVal)
virtual void append(const Primitive2DReference &) override
constexpr double deg2rad(double v)
virtual void create2DDecomposition(Primitive2DContainer &rContainer, const geometry::ViewInformation2D &rViewInformation) const override
#define PRIMITIVE2D_ID_OVERLAYCROSSHAIRPRIMITIVE
virtual void create2DDecomposition(Primitive2DContainer &rContainer, const geometry::ViewInformation2D &rViewInformation) const override
void transform(const basegfx::B2DHomMatrix &rMatrix)
#define PRIMITIVE2D_ID_OVERLAYHELPLINESTRIPEDPRIMITIVE
uno::Sequence< double > maFillColor
virtual bool operator==(const BasePrimitive2D &rPrimitive) const override
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
const basegfx::B2DHomMatrix & getInverseObjectToViewTransformation() const
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
virtual bool operator==(const BasePrimitive2D &rPrimitive) const override
virtual bool operator==(const BasePrimitive2D &rPrimitive) const override
B2DHomMatrix createRotateAroundPoint(double fPointX, double fPointY, double fRadiant)
double getLength(const B2DPolygon &rCandidate)
long getHeight() const
long getWidth() const
virtual void create2DDecomposition(Primitive2DContainer &rContainer, const geometry::ViewInformation2D &rViewInformation) const override
::basegfx::B2IVector maSize
OverlayStaticRectanglePrimitive(const basegfx::B2DPoint &rPosition, const basegfx::B2DSize &rSize, const basegfx::BColor &rStrokeColor, const basegfx::BColor &rFillColor, double fTransparence, double fRotation)