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