summaryrefslogtreecommitdiffstats
path: root/basegfx/source
diff options
context:
space:
mode:
Diffstat (limited to 'basegfx/source')
-rw-r--r--basegfx/source/color/bcolormodifier.cxx253
-rw-r--r--basegfx/source/curve/b2dcubicbezier.cxx42
-rw-r--r--basegfx/source/inc/hommatrixtemplate.hxx525
-rw-r--r--basegfx/source/inc/stringconversiontools.hxx2
-rw-r--r--basegfx/source/matrix/b2dhommatrix.cxx218
-rw-r--r--basegfx/source/matrix/b3dhommatrix.cxx7
-rw-r--r--basegfx/source/numeric/ftools.cxx2
-rw-r--r--basegfx/source/point/b2dpoint.cxx34
-rw-r--r--basegfx/source/point/b2ipoint.cxx15
-rw-r--r--basegfx/source/point/b3dpoint.cxx30
-rw-r--r--basegfx/source/polygon/b2dlinegeometry.cxx129
-rw-r--r--basegfx/source/polygon/b2dpolygon.cxx330
-rw-r--r--basegfx/source/polygon/b2dpolygonclipper.cxx31
-rw-r--r--basegfx/source/polygon/b2dpolygoncutandtouch.cxx43
-rw-r--r--basegfx/source/polygon/b2dpolygontools.cxx169
-rw-r--r--basegfx/source/polygon/b2dpolygontriangulator.cxx14
-rw-r--r--basegfx/source/polygon/b2dpolypolygon.cxx154
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx65
-rw-r--r--basegfx/source/polygon/b2dpolypolygontools.cxx7
-rw-r--r--basegfx/source/polygon/b2dsvgpolypolygon.cxx18
-rw-r--r--basegfx/source/polygon/b2dtrapezoid.cxx11
-rw-r--r--basegfx/source/polygon/b3dpolygon.cxx5
-rw-r--r--basegfx/source/polygon/b3dpolygontools.cxx20
-rw-r--r--basegfx/source/polygon/b3dpolypolygon.cxx5
-rw-r--r--basegfx/source/polygon/b3dpolypolygontools.cxx27
-rw-r--r--basegfx/source/range/b2dpolyrange.cxx5
-rw-r--r--basegfx/source/range/b2drange.cxx12
-rw-r--r--basegfx/source/tools/b2dclipstate.cxx10
-rw-r--r--basegfx/source/tools/bgradient.cxx996
-rw-r--r--basegfx/source/tools/canvastools.cxx18
-rw-r--r--basegfx/source/tools/gradienttools.cxx361
-rw-r--r--basegfx/source/tools/stringconversiontools.cxx34
-rw-r--r--basegfx/source/tools/systemdependentdata.cxx8
-rw-r--r--basegfx/source/tools/unopolypolygon.cxx26
-rw-r--r--basegfx/source/tools/zoomtools.cxx16
-rw-r--r--basegfx/source/vector/b2dvector.cxx64
-rw-r--r--basegfx/source/vector/b2ivector.cxx4
-rw-r--r--basegfx/source/vector/b3dvector.cxx28
-rw-r--r--basegfx/source/workbench/Makefile13
-rw-r--r--basegfx/source/workbench/bezierclip.cxx188
-rw-r--r--basegfx/source/workbench/gauss.hxx6
41 files changed, 2397 insertions, 1548 deletions
diff --git a/basegfx/source/color/bcolormodifier.cxx b/basegfx/source/color/bcolormodifier.cxx
index 8620a94fe2c7..3b9d1ce158c3 100644
--- a/basegfx/source/color/bcolormodifier.cxx
+++ b/basegfx/source/color/bcolormodifier.cxx
@@ -18,10 +18,10 @@
*/
#include <sal/config.h>
-
#include <algorithm>
-
+#include <float.h>
#include <basegfx/color/bcolormodifier.hxx>
+#include <comphelper/random.hxx>
namespace basegfx
{
@@ -45,6 +45,11 @@ namespace basegfx
return ::basegfx::BColor(fLuminance, fLuminance, fLuminance);
}
+ OUString BColorModifier_gray::getModifierName() const
+ {
+ return "gray";
+ }
+
BColorModifier_invert::~BColorModifier_invert()
{
}
@@ -59,6 +64,11 @@ namespace basegfx
return ::basegfx::BColor(1.0 - aSourceColor.getRed(), 1.0 - aSourceColor.getGreen(), 1.0 - aSourceColor.getBlue());
}
+ OUString BColorModifier_invert::getModifierName() const
+ {
+ return "invert";
+ }
+
BColorModifier_luminance_to_alpha::~BColorModifier_luminance_to_alpha()
{
}
@@ -75,6 +85,11 @@ namespace basegfx
return ::basegfx::BColor(fAlpha, fAlpha, fAlpha);
}
+ OUString BColorModifier_luminance_to_alpha::getModifierName() const
+ {
+ return "luminance_to_alpha";
+ }
+
BColorModifier_replace::~BColorModifier_replace()
{
}
@@ -96,6 +111,11 @@ namespace basegfx
return maBColor;
}
+ OUString BColorModifier_replace::getModifierName() const
+ {
+ return "replace";
+ }
+
BColorModifier_interpolate::~BColorModifier_interpolate()
{
}
@@ -117,6 +137,162 @@ namespace basegfx
return interpolate(maBColor, aSourceColor, mfValue);
}
+ OUString BColorModifier_interpolate::getModifierName() const
+ {
+ return "interpolate";
+ }
+
+ BColorModifier_matrix::~BColorModifier_matrix()
+ {
+ }
+
+ bool BColorModifier_matrix::operator==(const BColorModifier& rCompare) const
+ {
+ const BColorModifier_matrix* pCompare = dynamic_cast< const BColorModifier_matrix* >(&rCompare);
+
+ if(!pCompare)
+ {
+ return false;
+ }
+
+ return maVector == pCompare->maVector;
+ }
+
+ ::basegfx::BColor BColorModifier_matrix::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
+ {
+ if (maVector.size() != 20)
+ return aSourceColor;
+
+ const double aRed = maVector[0] * aSourceColor.getRed()
+ + maVector[1] * aSourceColor.getGreen()
+ + maVector[2] * aSourceColor.getBlue()
+ + maVector[3] * 1.0
+ + maVector[4];
+ const double aGreen = maVector[5] * aSourceColor.getRed()
+ + maVector[6] * aSourceColor.getGreen()
+ + maVector[7] * aSourceColor.getBlue()
+ + maVector[8] * 1.0
+ + maVector[9];
+ const double aBlue = maVector[10] * aSourceColor.getRed()
+ + maVector[11] * aSourceColor.getGreen()
+ + maVector[12] * aSourceColor.getBlue()
+ + maVector[13] * 1.0
+ + maVector[14];
+ /*TODO: add support for alpha
+ const double aAlpha = maVector[15] * aSourceColor.getRed()
+ + maVector[16] * aSourceColor.getGreen()
+ + maVector[17] * aSourceColor.getBlue()
+ + maVector[18] * 1.0
+ + maVector[19]);
+ */
+
+ return ::basegfx::BColor(
+ std::clamp(aRed, 0.0, 1.0),
+ std::clamp(aGreen, 0.0, 1.0),
+ std::clamp(aBlue, 0.0, 1.0));
+ }
+
+ OUString BColorModifier_matrix::getModifierName() const
+ {
+ return "matrix";
+ }
+
+ BColorModifier_saturate::BColorModifier_saturate(double fValue)
+ {
+ maSatMatrix.set(0, 0, 0.213 + 0.787 * fValue);
+ maSatMatrix.set(0, 1, 0.715 - 0.715 * fValue);
+ maSatMatrix.set(0, 2, 0.072 - 0.072 * fValue);
+ maSatMatrix.set(1, 0, 0.213 - 0.213 * fValue);
+ maSatMatrix.set(1, 1, 0.715 + 0.285 * fValue);
+ maSatMatrix.set(1, 2, 0.072 - 0.072 * fValue);
+ maSatMatrix.set(2, 0, 0.213 - 0.213 * fValue);
+ maSatMatrix.set(2, 1, 0.715 - 0.715 * fValue);
+ maSatMatrix.set(2, 2, 0.072 + 0.928 * fValue);
+ }
+
+ BColorModifier_saturate::~BColorModifier_saturate()
+ {
+ }
+
+ bool BColorModifier_saturate::operator==(const BColorModifier& rCompare) const
+ {
+ const BColorModifier_saturate* pCompare = dynamic_cast< const BColorModifier_saturate* >(&rCompare);
+
+ if(!pCompare)
+ {
+ return false;
+ }
+
+ return maSatMatrix == pCompare->maSatMatrix;
+ }
+
+ ::basegfx::BColor BColorModifier_saturate::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
+ {
+ basegfx::B3DHomMatrix aColorMatrix;
+ aColorMatrix.set(0, 0, aSourceColor.getRed());
+ aColorMatrix.set(1, 0, aSourceColor.getGreen());
+ aColorMatrix.set(2, 0, aSourceColor.getBlue());
+
+ aColorMatrix = maSatMatrix * aColorMatrix;
+ return ::basegfx::BColor(aColorMatrix.get(0, 0), aColorMatrix.get(1, 0), aColorMatrix.get(2, 0));
+ }
+
+ OUString BColorModifier_saturate::getModifierName() const
+ {
+ return "saturate";
+ }
+
+ BColorModifier_hueRotate::BColorModifier_hueRotate(double fRad)
+ {
+ const double fCos = cos(fRad);
+ const double fSin = sin(fRad);
+
+ maHueMatrix.set(0, 0, 0.213 + fCos * 0.787 - fSin * 0.213);
+ maHueMatrix.set(0, 1, 0.715 - fCos * 0.715 - fSin * 0.715);
+ maHueMatrix.set(0, 2, 0.072 - fCos * 0.072 + fSin * 0.928);
+ maHueMatrix.set(1, 0, 0.213 - fCos * 0.213 + fSin * 0.143);
+ maHueMatrix.set(1, 1, 0.715 + fCos * 0.285 + fSin * 0.140);
+ maHueMatrix.set(1, 2, 0.072 - fCos * 0.072 - fSin * 0.283);
+ maHueMatrix.set(2, 0, 0.213 - fCos * 0.213 - fSin * 0.787);
+ maHueMatrix.set(2, 1, 0.715 - fCos * 0.715 + fSin * 0.715);
+ maHueMatrix.set(2, 2, 0.072 + fCos * 0.928 + fSin * 0.072);
+ }
+
+ BColorModifier_hueRotate::~BColorModifier_hueRotate()
+ {
+ }
+
+ bool BColorModifier_hueRotate::operator==(const BColorModifier& rCompare) const
+ {
+ const BColorModifier_hueRotate* pCompare = dynamic_cast< const BColorModifier_hueRotate* >(&rCompare);
+
+ if(!pCompare)
+ {
+ return false;
+ }
+
+ return maHueMatrix == pCompare->maHueMatrix;
+ }
+
+ ::basegfx::BColor BColorModifier_hueRotate::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
+ {
+ basegfx::B3DHomMatrix aColorMatrix;
+ aColorMatrix.set(0, 0, aSourceColor.getRed());
+ aColorMatrix.set(1, 0, aSourceColor.getGreen());
+ aColorMatrix.set(2, 0, aSourceColor.getBlue());
+
+ aColorMatrix = maHueMatrix * aColorMatrix;
+ return ::basegfx::BColor(
+ std::clamp(aColorMatrix.get(0, 0), 0.0, 1.0),
+ std::clamp(aColorMatrix.get(1, 0), 0.0, 1.0),
+ std::clamp(aColorMatrix.get(2, 0), 0.0, 1.0));
+ }
+
+ OUString BColorModifier_hueRotate::getModifierName() const
+ {
+ return "hueRotate";
+ }
+
BColorModifier_black_and_white::~BColorModifier_black_and_white()
{
}
@@ -147,10 +323,15 @@ namespace basegfx
}
}
+ OUString BColorModifier_black_and_white::getModifierName() const
+ {
+ return "black_and_white";
+ }
+
BColorModifier_gamma::BColorModifier_gamma(double fValue)
: mfValue(fValue),
mfInvValue(fValue),
- mbUseIt(!basegfx::fTools::equal(fValue, 1.0) && basegfx::fTools::more(fValue, 0.0) && basegfx::fTools::lessOrEqual(fValue, 10.0))
+ mbUseIt(!basegfx::fTools::equal(fValue, 1.0) && fValue > 0.0 && basegfx::fTools::lessOrEqual(fValue, 10.0))
{
if(mbUseIt)
{
@@ -193,6 +374,11 @@ namespace basegfx
}
}
+ OUString BColorModifier_gamma::getModifierName() const
+ {
+ return "gamma";
+ }
+
BColorModifier_RGBLuminanceContrast::BColorModifier_RGBLuminanceContrast(double fRed, double fGreen, double fBlue, double fLuminance, double fContrast)
: mfRed(std::clamp(fRed, -1.0, 1.0)),
mfGreen(std::clamp(fGreen, -1.0, 1.0)),
@@ -270,6 +456,67 @@ namespace basegfx
}
}
+ OUString BColorModifier_RGBLuminanceContrast::getModifierName() const
+ {
+ return "RGBLuminanceContrast";
+ }
+
+ BColorModifier_randomize::BColorModifier_randomize(double fRandomPart)
+ : mfRandomPart(fRandomPart)
+ {
+ }
+
+ BColorModifier_randomize::~BColorModifier_randomize()
+ {
+ }
+
+ // compare operator
+ bool BColorModifier_randomize::operator==(const BColorModifier& rCompare) const
+ {
+ const BColorModifier_randomize* pCompare = dynamic_cast< const BColorModifier_randomize* >(&rCompare);
+
+ if(!pCompare)
+ {
+ return false;
+ }
+
+ return mfRandomPart == pCompare->mfRandomPart;
+ }
+
+ // compute modified color
+ ::basegfx::BColor BColorModifier_randomize::getModifiedColor(const ::basegfx::BColor& aSourceColor) const
+ {
+ if(0.0 >= mfRandomPart)
+ {
+ // no randomizing, use orig color
+ return aSourceColor;
+ }
+
+ if(1.0 <= mfRandomPart)
+ {
+ // full randomized color
+ return basegfx::BColor(
+ comphelper::rng::uniform_real_distribution(0.0, nextafter(1.0, DBL_MAX)),
+ comphelper::rng::uniform_real_distribution(0.0, nextafter(1.0, DBL_MAX)),
+ comphelper::rng::uniform_real_distribution(0.0, nextafter(1.0, DBL_MAX)));
+ }
+
+ // mixed color
+ const double fMulA(1.0 - mfRandomPart);
+ return basegfx::BColor(
+ aSourceColor.getRed() * fMulA +
+ comphelper::rng::uniform_real_distribution(0.0, nextafter(mfRandomPart, DBL_MAX)),
+ aSourceColor.getGreen() * fMulA +
+ comphelper::rng::uniform_real_distribution(0.0, nextafter(mfRandomPart, DBL_MAX)),
+ aSourceColor.getBlue() * fMulA +
+ comphelper::rng::uniform_real_distribution(0.0, nextafter(mfRandomPart, DBL_MAX)));
+ }
+
+ OUString BColorModifier_randomize::getModifierName() const
+ {
+ return "randomize";
+ }
+
::basegfx::BColor BColorModifierStack::getModifiedColor(const ::basegfx::BColor& rSource) const
{
if(maBColorModifiers.empty())
diff --git a/basegfx/source/curve/b2dcubicbezier.cxx b/basegfx/source/curve/b2dcubicbezier.cxx
index a04c17568b38..3f5d87aa79f6 100644
--- a/basegfx/source/curve/b2dcubicbezier.cxx
+++ b/basegfx/source/curve/b2dcubicbezier.cxx
@@ -337,8 +337,6 @@ namespace basegfx
{
}
- B2DCubicBezier::~B2DCubicBezier() = default;
-
// assignment operator
B2DCubicBezier& B2DCubicBezier::operator=(const B2DCubicBezier&) = default;
@@ -353,16 +351,6 @@ namespace basegfx
);
}
- bool B2DCubicBezier::operator!=(const B2DCubicBezier& rBezier) const
- {
- return (
- maStartPoint != rBezier.maStartPoint
- || maEndPoint != rBezier.maEndPoint
- || maControlPointA != rBezier.maControlPointA
- || maControlPointB != rBezier.maControlPointB
- );
- }
-
bool B2DCubicBezier::equal(const B2DCubicBezier& rBezier) const
{
return (
@@ -543,7 +531,7 @@ namespace basegfx
B2DVector B2DCubicBezier::getTangent(double t) const
{
- if(fTools::lessOrEqual(t, 0.0))
+ if(t <= 0.0)
{
// tangent in start point
B2DVector aTangent(getControlPointA() - getStartPoint());
@@ -612,12 +600,12 @@ namespace basegfx
}
// adaptive subdivide by distance
- void B2DCubicBezier::adaptiveSubdivideByDistance(B2DPolygon& rTarget, double fDistanceBound) const
+ void B2DCubicBezier::adaptiveSubdivideByDistance(B2DPolygon& rTarget, double fDistanceBound, int nRecurseLimit) const
{
if(isBezier())
{
ImpSubDivDistance(maStartPoint, maControlPointA, maControlPointB, maEndPoint, rTarget,
- fDistanceBound * fDistanceBound, std::numeric_limits<double>::max(), 30);
+ fDistanceBound * fDistanceBound, std::numeric_limits<double>::max(), nRecurseLimit);
}
else
{
@@ -1023,33 +1011,33 @@ namespace basegfx
if(maControlPointA == maStartPoint)
{
maControlPointA = maStartPoint = basegfx::B2DPoint(
- basegfx::fround(maStartPoint.getX()),
- basegfx::fround(maStartPoint.getY()));
+ std::round(maStartPoint.getX()),
+ std::round(maStartPoint.getY()));
}
else
{
maStartPoint = basegfx::B2DPoint(
- basegfx::fround(maStartPoint.getX()),
- basegfx::fround(maStartPoint.getY()));
+ std::round(maStartPoint.getX()),
+ std::round(maStartPoint.getY()));
maControlPointA = basegfx::B2DPoint(
- basegfx::fround(maControlPointA.getX()),
- basegfx::fround(maControlPointA.getY()));
+ std::round(maControlPointA.getX()),
+ std::round(maControlPointA.getY()));
}
if(maControlPointB == maEndPoint)
{
maControlPointB = maEndPoint = basegfx::B2DPoint(
- basegfx::fround(maEndPoint.getX()),
- basegfx::fround(maEndPoint.getY()));
+ std::round(maEndPoint.getX()),
+ std::round(maEndPoint.getY()));
}
else
{
maEndPoint = basegfx::B2DPoint(
- basegfx::fround(maEndPoint.getX()),
- basegfx::fround(maEndPoint.getY()));
+ std::round(maEndPoint.getX()),
+ std::round(maEndPoint.getY()));
maControlPointB = basegfx::B2DPoint(
- basegfx::fround(maControlPointB.getX()),
- basegfx::fround(maControlPointB.getY()));
+ std::round(maControlPointB.getX()),
+ std::round(maControlPointB.getY()));
}
}
} // end of namespace basegfx
diff --git a/basegfx/source/inc/hommatrixtemplate.hxx b/basegfx/source/inc/hommatrixtemplate.hxx
deleted file mode 100644
index a80df114c3e3..000000000000
--- a/basegfx/source/inc/hommatrixtemplate.hxx
+++ /dev/null
@@ -1,525 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#pragma once
-
-#include <sal/types.h>
-#include <basegfx/numeric/ftools.hxx>
-#include <cmath>
-#include <string.h>
-
-#include <memory>
-
-namespace basegfx::internal
- {
-
- inline double implGetDefaultValue(sal_uInt16 nRow, sal_uInt16 nColumn)
- {
- if(nRow == nColumn)
- return 1.0;
- return 0.0;
- }
-
- template < sal_uInt16 RowSize > class ImplMatLine
- {
- double mfValue[RowSize];
-
- public:
- ImplMatLine()
- {
- }
-
- explicit ImplMatLine(sal_uInt16 nRow, ImplMatLine< RowSize >* pToBeCopied)
- {
- if(pToBeCopied)
- {
- memcpy(&mfValue, pToBeCopied, sizeof(double) * RowSize);
- }
- else
- {
- for(sal_uInt16 a(0); a < RowSize; a++)
- {
- mfValue[a] = implGetDefaultValue(nRow, a);
- }
- }
- }
-
- double get(sal_uInt16 nColumn) const
- {
- return mfValue[nColumn];
- }
-
- void set(sal_uInt16 nColumn, const double& rValue)
- {
- mfValue[nColumn] = rValue;
- }
- };
-
- template < sal_uInt16 RowSize > class ImplHomMatrixTemplate
- {
- ImplMatLine< RowSize > maLine[RowSize - 1];
- std::unique_ptr<ImplMatLine< RowSize >> mutable mpLine;
-
- public:
- // Is last line used?
- bool isLastLineDefault() const
- {
- if(!mpLine)
- return true;
-
- for(sal_uInt16 a(0); a < RowSize; a++)
- {
- const double fDefault(implGetDefaultValue((RowSize - 1), a));
- const double fLineValue(mpLine->get(a));
-
- if(!::basegfx::fTools::equal(fDefault, fLineValue))
- {
- return false;
- }
- }
-
- // reset last line, it equals default
- mpLine.reset();
-
- return true;
- }
-
- ImplHomMatrixTemplate()
- {
- // complete initialization with identity matrix, all lines
- // were initialized with a trailing 1 followed by 0's.
- for(sal_uInt16 a(0); a < RowSize-1; a++)
- {
- for(sal_uInt16 b(0); b < RowSize; b++)
- maLine[a].set(b, implGetDefaultValue(a, b) );
- }
- }
-
- ImplHomMatrixTemplate(const ImplHomMatrixTemplate& rToBeCopied)
- {
- operator=(rToBeCopied);
- }
-
- ImplHomMatrixTemplate& operator=(const ImplHomMatrixTemplate& rToBeCopied)
- {
- if (this != &rToBeCopied)
- {
- // complete initialization using copy
- for(sal_uInt16 a(0); a < (RowSize - 1); a++)
- {
- memcpy(&maLine[a], &rToBeCopied.maLine[a], sizeof(ImplMatLine< RowSize >));
- }
- if(rToBeCopied.mpLine)
- {
- mpLine.reset( new ImplMatLine< RowSize >((RowSize - 1), rToBeCopied.mpLine.get()) );
- }
- }
- return *this;
- }
-
- static sal_uInt16 getEdgeLength() { return RowSize; }
-
- double get(sal_uInt16 nRow, sal_uInt16 nColumn) const
- {
- if(nRow < (RowSize - 1))
- {
- return maLine[nRow].get(nColumn);
- }
-
- if(mpLine)
- {
- return mpLine->get(nColumn);
- }
-
- return implGetDefaultValue((RowSize - 1), nColumn);
- }
-
- void set(sal_uInt16 nRow, sal_uInt16 nColumn, const double& rValue)
- {
- if(nRow < (RowSize - 1))
- {
- maLine[nRow].set(nColumn, rValue);
- }
- else if(mpLine)
- {
- mpLine->set(nColumn, rValue);
- }
- else
- {
- const double fDefault(implGetDefaultValue((RowSize - 1), nColumn));
-
- if(!::basegfx::fTools::equal(fDefault, rValue))
- {
- mpLine.reset(new ImplMatLine< RowSize >((RowSize - 1), nullptr));
- mpLine->set(nColumn, rValue);
- }
- }
- }
-
- void testLastLine()
- {
- if(!mpLine)
- return;
-
- bool bNecessary(false);
-
- for(sal_uInt16 a(0);!bNecessary && a < RowSize; a++)
- {
- const double fDefault(implGetDefaultValue((RowSize - 1), a));
- const double fLineValue(mpLine->get(a));
-
- if(!::basegfx::fTools::equal(fDefault, fLineValue))
- {
- bNecessary = true;
- }
- }
-
- if(!bNecessary)
- {
- mpLine.reset();
- }
- }
-
- // Left-upper decomposition
- bool ludcmp(sal_uInt16 nIndex[], sal_Int16& nParity)
- {
- double fBig, fSum, fDum;
- double fStorage[RowSize];
- sal_uInt16 a, b, c;
-
- // #i30874# Initialize nAMax (compiler warns)
- sal_uInt16 nAMax = 0;
-
- nParity = 1;
-
- // Calc the max of each line. If a line is empty,
- // stop immediately since matrix is not invertible then.
- for(a = 0; a < RowSize; a++)
- {
- fBig = 0.0;
-
- for(b = 0; b < RowSize; b++)
- {
- double fTemp(fabs(get(a, b)));
-
- if(::basegfx::fTools::more(fTemp, fBig))
- {
- fBig = fTemp;
- }
- }
-
- if(::basegfx::fTools::equalZero(fBig))
- {
- return false;
- }
-
- fStorage[a] = 1.0 / fBig;
- }
-
- // start normalizing
- for(b = 0; b < RowSize; b++)
- {
- for(a = 0; a < b; a++)
- {
- fSum = get(a, b);
-
- for(c = 0; c < a; c++)
- {
- fSum -= get(a, c) * get(c, b);
- }
-
- set(a, b, fSum);
- }
-
- fBig = 0.0;
-
- for(a = b; a < RowSize; a++)
- {
- fSum = get(a, b);
-
- for(c = 0; c < b; c++)
- {
- fSum -= get(a, c) * get(c, b);
- }
-
- set(a, b, fSum);
- fDum = fStorage[a] * fabs(fSum);
-
- if(::basegfx::fTools::moreOrEqual(fDum, fBig))
- {
- fBig = fDum;
- nAMax = a;
- }
- }
-
- if(b != nAMax)
- {
- for(c = 0; c < RowSize; c++)
- {
- fDum = get(nAMax, c);
- set(nAMax, c, get(b, c));
- set(b, c, fDum);
- }
-
- nParity = -nParity;
- fStorage[nAMax] = fStorage[b];
- }
-
- nIndex[b] = nAMax;
-
- // here the failure of precision occurs
- const double fValBB(fabs(get(b, b)));
-
- if(::basegfx::fTools::equalZero(fValBB))
- {
- return false;
- }
-
- if(b != (RowSize - 1))
- {
- fDum = 1.0 / get(b, b);
-
- for(a = b + 1; a < RowSize; a++)
- {
- set(a, b, get(a, b) * fDum);
- }
- }
- }
-
- return true;
- }
-
- void lubksb(const sal_uInt16 nIndex[], double fRow[]) const
- {
- sal_uInt16 b, ip;
- sal_Int16 a, a2 = -1;
- double fSum;
-
- for(a = 0; a < RowSize; a++)
- {
- ip = nIndex[a];
- fSum = fRow[ip];
- fRow[ip] = fRow[a];
-
- if(a2 >= 0)
- {
- for(b = a2; b < a; b++)
- {
- fSum -= get(a, b) * fRow[b];
- }
- }
- else if(!::basegfx::fTools::equalZero(fSum))
- {
- a2 = a;
- }
-
- fRow[a] = fSum;
- }
-
- for(a = (RowSize - 1); a >= 0; a--)
- {
- fSum = fRow[a];
-
- for(b = a + 1; b < RowSize; b++)
- {
- fSum -= get(a, b) * fRow[b];
- }
-
- const double fValueAA(get(a, a));
-
- if(!::basegfx::fTools::equalZero(fValueAA))
- {
- fRow[a] = fSum / get(a, a);
- }
- }
- }
-
- bool isIdentity() const
- {
- // last line needs no testing if not existing
- const sal_uInt16 nMaxLine(
- sal::static_int_cast<sal_uInt16>(mpLine ? RowSize : (RowSize - 1)) );
-
- for(sal_uInt16 a(0); a < nMaxLine; a++)
- {
- for(sal_uInt16 b(0); b < RowSize; b++)
- {
- const double fDefault(implGetDefaultValue(a, b));
- const double fValueAB(get(a, b));
-
- if(!::basegfx::fTools::equal(fDefault, fValueAB))
- {
- return false;
- }
- }
- }
-
- return true;
- }
-
- bool isInvertible() const
- {
- ImplHomMatrixTemplate aWork(*this);
- sal_uInt16 nIndex[RowSize];
- sal_Int16 nParity;
-
- return aWork.ludcmp(nIndex, nParity);
- }
-
- void doInvert(const ImplHomMatrixTemplate& rWork, const sal_uInt16 nIndex[])
- {
- double fArray[RowSize];
-
- for(sal_uInt16 a(0); a < RowSize; a++)
- {
- // prepare line
- sal_uInt16 b;
- for( b = 0; b < RowSize; b++)
- {
- fArray[b] = implGetDefaultValue(a, b);
- }
-
- // expand line
- rWork.lubksb(nIndex, fArray);
-
- // copy line transposed to this matrix
- for( b = 0; b < RowSize; b++)
- {
- set(b, a, fArray[b]);
- }
- }
-
- // evtl. get rid of last matrix line
- testLastLine();
- }
-
- double doDeterminant() const
- {
- ImplHomMatrixTemplate aWork(*this);
- sal_uInt16 nIndex[RowSize];
- sal_Int16 nParity;
- double fRetval(0.0);
-
- if(aWork.ludcmp(nIndex, nParity))
- {
- fRetval = static_cast<double>(nParity);
-
- // last line needs no multiply if not existing; default value would be 1.
- const sal_uInt16 nMaxLine(
- sal::static_int_cast<sal_uInt16>(aWork.mpLine ? RowSize : (RowSize - 1)) );
-
- for(sal_uInt16 a(0); a < nMaxLine; a++)
- {
- fRetval *= aWork.get(a, a);
- }
- }
-
- return fRetval;
- }
-
- void doAddMatrix(const ImplHomMatrixTemplate& rMat)
- {
- for(sal_uInt16 a(0); a < RowSize; a++)
- {
- for(sal_uInt16 b(0); b < RowSize; b++)
- {
- set(a, b, get(a, b) + rMat.get(a, b));
- }
- }
-
- testLastLine();
- }
-
- void doSubMatrix(const ImplHomMatrixTemplate& rMat)
- {
- for(sal_uInt16 a(0); a < RowSize; a++)
- {
- for(sal_uInt16 b(0); b < RowSize; b++)
- {
- set(a, b, get(a, b) - rMat.get(a, b));
- }
- }
-
- testLastLine();
- }
-
- void doMulMatrix(const double& rfValue)
- {
- for(sal_uInt16 a(0); a < RowSize; a++)
- {
- for(sal_uInt16 b(0); b < RowSize; b++)
- {
- set(a, b, get(a, b) * rfValue);
- }
- }
-
- testLastLine();
- }
-
- void doMulMatrix(const ImplHomMatrixTemplate& rMat)
- {
- // create a copy as source for the original values
- const ImplHomMatrixTemplate aCopy(*this);
-
- // TODO: maybe optimize cases where last line is [0 0 1].
-
- double fValue(0.0);
-
- for(sal_uInt16 a(0); a < RowSize; ++a)
- {
- for(sal_uInt16 b(0); b < RowSize; ++b)
- {
- fValue = 0.0;
-
- for(sal_uInt16 c(0); c < RowSize; ++c)
- fValue += aCopy.get(c, b) * rMat.get(a, c);
-
- set(a, b, fValue);
- }
- }
-
- testLastLine();
- }
-
- bool isEqual(const ImplHomMatrixTemplate& rMat) const
- {
- const sal_uInt16 nMaxLine(
- sal::static_int_cast<sal_uInt16>((mpLine || rMat.mpLine) ? RowSize : (RowSize - 1)) );
-
- for(sal_uInt16 a(0); a < nMaxLine; a++)
- {
- for(sal_uInt16 b(0); b < RowSize; b++)
- {
- const double fValueA(get(a, b));
- const double fValueB(rMat.get(a, b));
-
- if(!::basegfx::fTools::equal(fValueA, fValueB))
- {
- return false;
- }
- }
- }
-
- return true;
- }
- };
-
-} // namespace basegfx::internal
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basegfx/source/inc/stringconversiontools.hxx b/basegfx/source/inc/stringconversiontools.hxx
index fdf2f83e0f4e..797697d203ac 100644
--- a/basegfx/source/inc/stringconversiontools.hxx
+++ b/basegfx/source/inc/stringconversiontools.hxx
@@ -51,7 +51,7 @@ namespace basegfx::internal
bool importDoubleAndSpaces(double& o_fRetval,
sal_Int32& io_rPos,
- const OUString& rStr,
+ std::u16string_view rStr,
const sal_Int32 nLen );
bool importFlagAndSpaces(sal_Int32& o_nRetval,
diff --git a/basegfx/source/matrix/b2dhommatrix.cxx b/basegfx/source/matrix/b2dhommatrix.cxx
index f3d2622db27a..dc5c02b0e33f 100644
--- a/basegfx/source/matrix/b2dhommatrix.cxx
+++ b/basegfx/source/matrix/b2dhommatrix.cxx
@@ -18,7 +18,7 @@
*/
#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <hommatrixtemplate.hxx>
+#include <basegfx/matrix/hommatrixtemplate.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
@@ -26,125 +26,100 @@
namespace basegfx
{
- typedef ::basegfx::internal::ImplHomMatrixTemplate< 3 > Impl2DHomMatrix_Base;
- class Impl2DHomMatrix : public Impl2DHomMatrix_Base
- {
- };
-
- static o3tl::cow_wrapper<Impl2DHomMatrix> DEFAULT;
-
- B2DHomMatrix::B2DHomMatrix() : mpImpl(DEFAULT) {}
-
- B2DHomMatrix::B2DHomMatrix(const B2DHomMatrix&) = default;
-
- B2DHomMatrix::B2DHomMatrix(B2DHomMatrix&&) = default;
-
- B2DHomMatrix::~B2DHomMatrix() = default;
-
- B2DHomMatrix::B2DHomMatrix(double f_0x0, double f_0x1, double f_0x2, double f_1x0, double f_1x1, double f_1x2)
- {
- mpImpl->set(0, 0, f_0x0);
- mpImpl->set(0, 1, f_0x1);
- mpImpl->set(0, 2, f_0x2);
- mpImpl->set(1, 0, f_1x0);
- mpImpl->set(1, 1, f_1x1);
- mpImpl->set(1, 2, f_1x2);
- }
-
- B2DHomMatrix& B2DHomMatrix::operator=(const B2DHomMatrix&) = default;
-
- B2DHomMatrix& B2DHomMatrix::operator=(B2DHomMatrix&&) = default;
-
- double B2DHomMatrix::get(sal_uInt16 nRow, sal_uInt16 nColumn) const
- {
- return mpImpl->get(nRow, nColumn);
- }
-
- void B2DHomMatrix::set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
- {
- mpImpl->set(nRow, nColumn, fValue);
- }
+ constexpr int RowSize = 3;
void B2DHomMatrix::set3x2(double f_0x0, double f_0x1, double f_0x2, double f_1x0, double f_1x1, double f_1x2)
{
- mpImpl->set(0, 0, f_0x0);
- mpImpl->set(0, 1, f_0x1);
- mpImpl->set(0, 2, f_0x2);
- mpImpl->set(1, 0, f_1x0);
- mpImpl->set(1, 1, f_1x1);
- mpImpl->set(1, 2, f_1x2);
- }
-
- bool B2DHomMatrix::isLastLineDefault() const
- {
- return mpImpl->isLastLineDefault();
+ mfValues[0][0] = f_0x0;
+ mfValues[0][1] = f_0x1;
+ mfValues[0][2] = f_0x2;
+ mfValues[1][0] = f_1x0;
+ mfValues[1][1] = f_1x1;
+ mfValues[1][2] = f_1x2;
}
bool B2DHomMatrix::isIdentity() const
{
- return mpImpl->isIdentity();
+ for(sal_uInt16 a(0); a < RowSize - 1; a++)
+ {
+ for(sal_uInt16 b(0); b < RowSize; b++)
+ {
+ const double fDefault(internal::implGetDefaultValue(a, b));
+ const double fValueAB(get(a, b));
+
+ if(!::basegfx::fTools::equal(fDefault, fValueAB))
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
}
void B2DHomMatrix::identity()
{
- *mpImpl = Impl2DHomMatrix();
+ for(sal_uInt16 a(0); a < RowSize - 1; a++)
+ {
+ for(sal_uInt16 b(0); b < RowSize; b++)
+ mfValues[a][b] = internal::implGetDefaultValue(a, b);
+ }
}
bool B2DHomMatrix::isInvertible() const
{
- return mpImpl->isInvertible();
+ double dst[6];
+ /* Compute adjoint: */
+ computeAdjoint(dst);
+ /* Compute determinant: */
+ double det = computeDeterminant(dst);
+ if (fTools::equalZero(det))
+ return false;
+ return true;
}
bool B2DHomMatrix::invert()
{
if(isIdentity())
- {
return true;
- }
- Impl2DHomMatrix aWork(*mpImpl);
- std::unique_ptr<sal_uInt16[]> pIndex( new sal_uInt16[Impl2DHomMatrix_Base::getEdgeLength()] );
- sal_Int16 nParity;
+ double dst[6];
- if(aWork.ludcmp(pIndex.get(), nParity))
- {
- mpImpl->doInvert(aWork, pIndex.get());
- return true;
- }
+ /* Compute adjoint: */
+ computeAdjoint(dst);
- return false;
- }
+ /* Compute determinant: */
+ double det = computeDeterminant(dst);
+ if (fTools::equalZero(det))
+ return false;
- B2DHomMatrix& B2DHomMatrix::operator+=(const B2DHomMatrix& rMat)
- {
- mpImpl->doAddMatrix(*rMat.mpImpl);
- return *this;
- }
+ /* Multiply adjoint with reciprocal of determinant: */
+ det = 1.0 / det;
+ mfValues[0][0] = dst[0] * det;
+ mfValues[0][1] = dst[1] * det;
+ mfValues[0][2] = dst[2] * det;
+ mfValues[1][0] = dst[3] * det;
+ mfValues[1][1] = dst[4] * det;
+ mfValues[1][2] = dst[5] * det;
- B2DHomMatrix& B2DHomMatrix::operator-=(const B2DHomMatrix& rMat)
- {
- mpImpl->doSubMatrix(*rMat.mpImpl);
- return *this;
+ return true;
}
- B2DHomMatrix& B2DHomMatrix::operator*=(double fValue)
+ /* Compute adjoint, optimised for the case where the last (not stored) row is { 0, 0, 1 } */
+ void B2DHomMatrix::computeAdjoint(double (&dst)[6]) const
{
- const double fOne(1.0);
-
- if(!fTools::equal(fOne, fValue))
- mpImpl->doMulMatrix(fValue);
-
- return *this;
+ dst[0] = + get(1, 1);
+ dst[1] = - get(0, 1);
+ dst[2] = + get(0, 1) * get(1, 2) - get(0, 2) * get(1, 1);
+ dst[3] = - get(1, 0);
+ dst[4] = + get(0, 0);
+ dst[5] = - get(0, 0) * get(1, 2) + get(0, 2) * get(1, 0);
}
- B2DHomMatrix& B2DHomMatrix::operator/=(double fValue)
+ /* Compute the determinant, given the adjoint matrix */
+ double B2DHomMatrix::computeDeterminant(double (&dst)[6]) const
{
- const double fOne(1.0);
-
- if(!fTools::equal(fOne, fValue))
- mpImpl->doMulMatrix(1.0 / fValue);
-
- return *this;
+ return mfValues[0][0] * dst[0] + mfValues[0][1] * dst[3];
}
B2DHomMatrix& B2DHomMatrix::operator*=(const B2DHomMatrix& rMat)
@@ -161,23 +136,50 @@ namespace basegfx
else
{
// multiply
- mpImpl->doMulMatrix(*rMat.mpImpl);
+ doMulMatrix(rMat);
}
return *this;
}
- bool B2DHomMatrix::operator==(const B2DHomMatrix& rMat) const
+ void B2DHomMatrix::doMulMatrix(const B2DHomMatrix& rMat)
{
- if(mpImpl.same_object(rMat.mpImpl))
- return true;
+ // create a copy as source for the original values
+ const B2DHomMatrix aCopy(*this);
- return mpImpl->isEqual(*rMat.mpImpl);
+ for(sal_uInt16 a(0); a < 2; ++a)
+ {
+ for(sal_uInt16 b(0); b < 3; ++b)
+ {
+ double fValue = 0.0;
+
+ for(sal_uInt16 c(0); c < 2; ++c)
+ fValue += aCopy.mfValues[c][b] * rMat.mfValues[a][c];
+
+ mfValues[a][b] = fValue;
+ }
+ mfValues[a][2] += rMat.mfValues[a][2];
+ }
}
- bool B2DHomMatrix::operator!=(const B2DHomMatrix& rMat) const
+ bool B2DHomMatrix::operator==(const B2DHomMatrix& rMat) const
{
- return !(*this == rMat);
+ if (&rMat == this)
+ return true;
+ for(sal_uInt16 a(0); a < 2; a++)
+ {
+ for(sal_uInt16 b(0); b < 3; b++)
+ {
+ const double fValueA(mfValues[a][b]);
+ const double fValueB(rMat.mfValues[a][b]);
+
+ if(!::basegfx::fTools::equal(fValueA, fValueB))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
}
void B2DHomMatrix::rotate(double fRadiant)
@@ -189,26 +191,26 @@ namespace basegfx
double fCos(1.0);
utils::createSinCosOrthogonal(fSin, fCos, fRadiant);
- Impl2DHomMatrix aRotMat;
+ B2DHomMatrix aRotMat;
aRotMat.set(0, 0, fCos);
aRotMat.set(1, 1, fCos);
aRotMat.set(1, 0, fSin);
aRotMat.set(0, 1, -fSin);
- mpImpl->doMulMatrix(aRotMat);
+ doMulMatrix(aRotMat);
}
void B2DHomMatrix::translate(double fX, double fY)
{
if(!fTools::equalZero(fX) || !fTools::equalZero(fY))
{
- Impl2DHomMatrix aTransMat;
+ B2DHomMatrix aTransMat;
aTransMat.set(0, 2, fX);
aTransMat.set(1, 2, fY);
- mpImpl->doMulMatrix(aTransMat);
+ doMulMatrix(aTransMat);
}
}
@@ -223,12 +225,12 @@ namespace basegfx
if(!fTools::equal(fOne, fX) || !fTools::equal(fOne, fY))
{
- Impl2DHomMatrix aScaleMat;
+ B2DHomMatrix aScaleMat;
aScaleMat.set(0, 0, fX);
aScaleMat.set(1, 1, fY);
- mpImpl->doMulMatrix(aScaleMat);
+ doMulMatrix(aScaleMat);
}
}
@@ -242,11 +244,11 @@ namespace basegfx
// #i76239# do not test against 1.0, but against 0.0. We are talking about a value not on the diagonal (!)
if(!fTools::equalZero(fSx))
{
- Impl2DHomMatrix aShearXMat;
+ B2DHomMatrix aShearXMat;
aShearXMat.set(0, 1, fSx);
- mpImpl->doMulMatrix(aShearXMat);
+ doMulMatrix(aShearXMat);
}
}
@@ -255,11 +257,11 @@ namespace basegfx
// #i76239# do not test against 1.0, but against 0.0. We are talking about a value not on the diagonal (!)
if(!fTools::equalZero(fSy))
{
- Impl2DHomMatrix aShearYMat;
+ B2DHomMatrix aShearYMat;
aShearYMat.set(1, 0, fSy);
- mpImpl->doMulMatrix(aShearYMat);
+ doMulMatrix(aShearYMat);
}
}
@@ -272,12 +274,6 @@ namespace basegfx
*/
bool B2DHomMatrix::decompose(B2DTuple& rScale, B2DTuple& rTranslate, double& rRotate, double& rShearX) const
{
- // when perspective is used, decompose is not made here
- if(!mpImpl->isLastLineDefault())
- {
- return false;
- }
-
// reset rotate and shear and copy translation values in every case
rRotate = rShearX = 0.0;
rTranslate.setX(get(0, 2));
diff --git a/basegfx/source/matrix/b3dhommatrix.cxx b/basegfx/source/matrix/b3dhommatrix.cxx
index 3605767d681d..96edab9158b6 100644
--- a/basegfx/source/matrix/b3dhommatrix.cxx
+++ b/basegfx/source/matrix/b3dhommatrix.cxx
@@ -18,7 +18,7 @@
*/
#include <basegfx/matrix/b3dhommatrix.hxx>
-#include <hommatrixtemplate.hxx>
+#include <basegfx/matrix/hommatrixtemplate.hxx>
#include <basegfx/vector/b3dvector.hxx>
#include <memory>
@@ -142,11 +142,6 @@ namespace basegfx
return mpImpl->isEqual(*rMat.mpImpl);
}
- bool B3DHomMatrix::operator!=(const B3DHomMatrix& rMat) const
- {
- return !(*this == rMat);
- }
-
void B3DHomMatrix::rotate(double fAngleX,double fAngleY,double fAngleZ)
{
if(fTools::equalZero(fAngleX) && fTools::equalZero(fAngleY) && fTools::equalZero(fAngleZ))
diff --git a/basegfx/source/numeric/ftools.cxx b/basegfx/source/numeric/ftools.cxx
index 246d8d548aac..4a01a4c0eca0 100644
--- a/basegfx/source/numeric/ftools.cxx
+++ b/basegfx/source/numeric/ftools.cxx
@@ -99,7 +99,7 @@ namespace basegfx
double normalizeToRange(double v, const double fRange)
{
- if(fTools::lessOrEqual(fRange, 0.0))
+ if(fRange <= 0.0)
{
// with a zero (or less) range, all normalizes to 0.0
return 0.0;
diff --git a/basegfx/source/point/b2dpoint.cxx b/basegfx/source/point/b2dpoint.cxx
index 0dc18b513db1..d12c3dd04c4f 100644
--- a/basegfx/source/point/b2dpoint.cxx
+++ b/basegfx/source/point/b2dpoint.cxx
@@ -23,41 +23,19 @@
namespace basegfx
{
- B2DPoint& B2DPoint::operator=( const ::basegfx::B2DTuple& rPoint )
- {
- mfX = rPoint.getX();
- mfY = rPoint.getY();
- return *this;
- }
-
B2DPoint& B2DPoint::operator*=( const ::basegfx::B2DHomMatrix& rMat )
{
double fTempX(
- rMat.get(0, 0) * mfX +
- rMat.get(0, 1) * mfY +
+ rMat.get(0, 0) * mnX +
+ rMat.get(0, 1) * mnY +
rMat.get(0, 2));
double fTempY(
- rMat.get(1, 0) * mfX +
- rMat.get(1, 1) * mfY +
+ rMat.get(1, 0) * mnX +
+ rMat.get(1, 1) * mnY +
rMat.get(1, 2));
- if(!rMat.isLastLineDefault())
- {
- const double fOne(1.0);
- const double fTempM(
- rMat.get(2, 0) * mfX +
- rMat.get(2, 1) * mfY +
- rMat.get(2, 2));
-
- if(!fTools::equalZero(fTempM) && !fTools::equal(fOne, fTempM))
- {
- fTempX /= fTempM;
- fTempY /= fTempM;
- }
- }
-
- mfX = fTempX;
- mfY = fTempY;
+ mnX = fTempX;
+ mnY = fTempY;
return *this;
}
diff --git a/basegfx/source/point/b2ipoint.cxx b/basegfx/source/point/b2ipoint.cxx
index 7b43ebc860e2..2790fe3a18a8 100644
--- a/basegfx/source/point/b2ipoint.cxx
+++ b/basegfx/source/point/b2ipoint.cxx
@@ -41,21 +41,6 @@ namespace basegfx
rMat.get(1, 1) * mnY +
rMat.get(1, 2));
- if(!rMat.isLastLineDefault())
- {
- const double fOne(1.0);
- const double fTempM(
- rMat.get(2, 0) * mnX +
- rMat.get(2, 1) * mnY +
- rMat.get(2, 2));
-
- if(!fTools::equalZero(fTempM) && !fTools::equal(fOne, fTempM))
- {
- fTempX /= fTempM;
- fTempY /= fTempM;
- }
- }
-
mnX = fround(fTempX);
mnY = fround(fTempY);
diff --git a/basegfx/source/point/b3dpoint.cxx b/basegfx/source/point/b3dpoint.cxx
index ff70b501ed7a..7d2d4cf4a22b 100644
--- a/basegfx/source/point/b3dpoint.cxx
+++ b/basegfx/source/point/b3dpoint.cxx
@@ -26,28 +26,28 @@ namespace basegfx
B3DPoint& B3DPoint::operator*=( const ::basegfx::B3DHomMatrix& rMat )
{
double fTempX(
- rMat.get(0, 0) * mfX +
- rMat.get(0, 1) * mfY +
- rMat.get(0, 2) * mfZ +
+ rMat.get(0, 0) * mnX +
+ rMat.get(0, 1) * mnY +
+ rMat.get(0, 2) * mnZ +
rMat.get(0, 3));
double fTempY(
- rMat.get(1, 0) * mfX +
- rMat.get(1, 1) * mfY +
- rMat.get(1, 2) * mfZ +
+ rMat.get(1, 0) * mnX +
+ rMat.get(1, 1) * mnY +
+ rMat.get(1, 2) * mnZ +
rMat.get(1, 3));
double fTempZ(
- rMat.get(2, 0) * mfX +
- rMat.get(2, 1) * mfY +
- rMat.get(2, 2) * mfZ +
+ rMat.get(2, 0) * mnX +
+ rMat.get(2, 1) * mnY +
+ rMat.get(2, 2) * mnZ +
rMat.get(2, 3));
if(!rMat.isLastLineDefault())
{
const double fOne(1.0);
const double fTempM(
- rMat.get(3, 0) * mfX +
- rMat.get(3, 1) * mfY +
- rMat.get(3, 2) * mfZ +
+ rMat.get(3, 0) * mnX +
+ rMat.get(3, 1) * mnY +
+ rMat.get(3, 2) * mnZ +
rMat.get(3, 3));
if(!fTools::equalZero(fTempM) && !fTools::equal(fOne, fTempM))
@@ -58,9 +58,9 @@ namespace basegfx
}
}
- mfX = fTempX;
- mfY = fTempY;
- mfZ = fTempZ;
+ mnX = fTempX;
+ mnY = fTempY;
+ mnZ = fTempZ;
return *this;
}
diff --git a/basegfx/source/polygon/b2dlinegeometry.cxx b/basegfx/source/polygon/b2dlinegeometry.cxx
index 6dda8f9e7e1f..a6a88c557ee8 100644
--- a/basegfx/source/polygon/b2dlinegeometry.cxx
+++ b/basegfx/source/polygon/b2dlinegeometry.cxx
@@ -147,7 +147,7 @@ namespace basegfx
const B2DVector aTangentA(rCandidate.getTangent(0.0));
const double fScalarAE(aEdge.scalar(aTangentA));
- if(fTools::lessOrEqual(fScalarAE, 0.0))
+ if(fScalarAE <= 0.0)
{
// angle between TangentA and Edge is bigger or equal 90 degrees
return false;
@@ -174,7 +174,7 @@ namespace basegfx
const B2DVector aTangentB(rCandidate.getTangent(1.0));
const double fScalarBE(aEdge.scalar(aTangentB));
- if(fTools::lessOrEqual(fScalarBE, 0.0))
+ if(fScalarBE <= 0.0)
{
// angle between TangentB and Edge is bigger or equal 90 degrees
return false;
@@ -335,8 +335,7 @@ namespace basegfx
bool bStartRound,
bool bEndRound,
bool bStartSquare,
- bool bEndSquare,
- basegfx::triangulator::B2DTriangleVector* pTriangles)
+ bool bEndSquare)
{
// create polygon for edge
// Unfortunately, while it would be geometrically correct to not add
@@ -565,15 +564,6 @@ namespace basegfx
}
}
- if(nullptr != pTriangles)
- {
- const basegfx::triangulator::B2DTriangleVector aResult(
- basegfx::triangulator::triangulate(
- aBezierPolygon));
- pTriangles->insert(pTriangles->end(), aResult.begin(), aResult.end());
- aBezierPolygon.clear();
- }
-
// return
return aBezierPolygon;
}
@@ -672,15 +662,6 @@ namespace basegfx
// close and return
aEdgePolygon.setClosed(true);
- if(nullptr != pTriangles)
- {
- const basegfx::triangulator::B2DTriangleVector aResult(
- basegfx::triangulator::triangulate(
- aEdgePolygon));
- pTriangles->insert(pTriangles->end(), aResult.begin(), aResult.end());
- aEdgePolygon.clear();
- }
-
return aEdgePolygon;
}
}
@@ -693,8 +674,7 @@ namespace basegfx
const B2DPoint& rPoint,
double fHalfLineWidth,
B2DLineJoin eJoin,
- double fMiterMinimumAngle,
- basegfx::triangulator::B2DTriangleVector* pTriangles)
+ double fMiterMinimumAngle)
{
SAL_WARN_IF(fHalfLineWidth <= 0.0,"basegfx","createAreaGeometryForJoin: LineWidth too small (!)");
assert((eJoin != B2DLineJoin::NONE) && "createAreaGeometryForJoin: B2DLineJoin::NONE not allowed (!)");
@@ -721,19 +701,9 @@ namespace basegfx
{
case B2DLineJoin::Miter :
{
- if(nullptr != pTriangles)
- {
- pTriangles->emplace_back(
- aEndPoint,
- rPoint,
- aStartPoint);
- }
- else
- {
- aEdgePolygon.append(aEndPoint);
- aEdgePolygon.append(rPoint);
- aEdgePolygon.append(aStartPoint);
- }
+ aEdgePolygon.append(aEndPoint);
+ aEdgePolygon.append(rPoint);
+ aEdgePolygon.append(aStartPoint);
// Look for the cut point between start point along rTangentPrev and
// end point along rTangentEdge. -rTangentEdge should be used, but since
@@ -746,18 +716,7 @@ namespace basegfx
if(fCutPos != 0.0)
{
const B2DPoint aCutPoint(aStartPoint + (rTangentPrev * fCutPos));
-
- if(nullptr != pTriangles)
- {
- pTriangles->emplace_back(
- aStartPoint,
- aCutPoint,
- aEndPoint);
- }
- else
- {
- aEdgePolygon.append(aCutPoint);
- }
+ aEdgePolygon.append(aCutPoint);
}
break;
@@ -783,27 +742,14 @@ namespace basegfx
if(aBow.count() > 1)
{
- if(nullptr != pTriangles)
- {
- for(sal_uInt32 a(0); a < aBow.count() - 1; a++)
- {
- pTriangles->emplace_back(
- 0 == a ? aStartPoint : aBow.getB2DPoint(a),
- rPoint,
- aBow.count() - 1 == a + 1 ? aEndPoint : aBow.getB2DPoint(a + 1));
- }
- }
- else
- {
- // #i101491#
- // use the original start/end positions; the ones from bow creation may be numerically
- // different due to their different creation. To guarantee good merging quality with edges
- // and edge roundings (and to reduce point count)
- aEdgePolygon = aBow;
- aEdgePolygon.setB2DPoint(0, aStartPoint);
- aEdgePolygon.setB2DPoint(aEdgePolygon.count() - 1, aEndPoint);
- aEdgePolygon.append(rPoint);
- }
+ // #i101491#
+ // use the original start/end positions; the ones from bow creation may be numerically
+ // different due to their different creation. To guarantee good merging quality with edges
+ // and edge roundings (and to reduce point count)
+ aEdgePolygon = aBow;
+ aEdgePolygon.setB2DPoint(0, aStartPoint);
+ aEdgePolygon.setB2DPoint(aEdgePolygon.count() - 1, aEndPoint);
+ aEdgePolygon.append(rPoint);
break;
}
@@ -814,19 +760,9 @@ namespace basegfx
}
default: // B2DLineJoin::Bevel
{
- if(nullptr != pTriangles)
- {
- pTriangles->emplace_back(
- aEndPoint,
- rPoint,
- aStartPoint);
- }
- else
- {
- aEdgePolygon.append(aEndPoint);
- aEdgePolygon.append(rPoint);
- aEdgePolygon.append(aStartPoint);
- }
+ aEdgePolygon.append(aEndPoint);
+ aEdgePolygon.append(rPoint);
+ aEdgePolygon.append(aStartPoint);
break;
}
@@ -848,8 +784,7 @@ namespace basegfx
css::drawing::LineCap eCap,
double fMaxAllowedAngle,
double fMaxPartOfEdge,
- double fMiterMinimumAngle,
- basegfx::triangulator::B2DTriangleVector* pTriangles)
+ double fMiterMinimumAngle)
{
if(fMaxAllowedAngle > M_PI_2)
{
@@ -958,8 +893,7 @@ namespace basegfx
aEdge.getStartPoint(),
fHalfLineWidth,
eJoin,
- fMiterMinimumAngle,
- pTriangles));
+ fMiterMinimumAngle));
}
else if(aOrientation == B2VectorOrientation::Negative)
{
@@ -975,8 +909,7 @@ namespace basegfx
aEdge.getStartPoint(),
fHalfLineWidth,
eJoin,
- fMiterMinimumAngle,
- pTriangles));
+ fMiterMinimumAngle));
}
}
@@ -994,8 +927,7 @@ namespace basegfx
bFirst && eCap == css::drawing::LineCap_ROUND,
bLast && eCap == css::drawing::LineCap_ROUND,
bFirst && eCap == css::drawing::LineCap_SQUARE,
- bLast && eCap == css::drawing::LineCap_SQUARE,
- pTriangles));
+ bLast && eCap == css::drawing::LineCap_SQUARE));
}
else
{
@@ -1006,8 +938,7 @@ namespace basegfx
false,
false,
false,
- false,
- pTriangles));
+ false));
}
// prepare next step
@@ -1030,17 +961,7 @@ namespace basegfx
aCandidate.getB2DPoint(0),
fHalfLineWidth));
- if(nullptr != pTriangles)
- {
- const basegfx::triangulator::B2DTriangleVector aResult(
- basegfx::triangulator::triangulate(
- aCircle));
- pTriangles->insert(pTriangles->end(), aResult.begin(), aResult.end());
- }
- else
- {
- aRetval.append(aCircle);
- }
+ aRetval.append(aCircle);
}
return aRetval;
diff --git a/basegfx/source/polygon/b2dpolygon.cxx b/basegfx/source/polygon/b2dpolygon.cxx
index 3c85a2666d25..cf7309d20dd3 100644
--- a/basegfx/source/polygon/b2dpolygon.cxx
+++ b/basegfx/source/polygon/b2dpolygon.cxx
@@ -17,7 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include <osl/diagnose.h>
+#include <sal/config.h>
+
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dvector.hxx>
@@ -28,34 +29,13 @@
#include <memory>
#include <vector>
-namespace {
-
-struct CoordinateData2D : public basegfx::B2DPoint
+namespace
{
-public:
- CoordinateData2D() {}
-
- explicit CoordinateData2D(const basegfx::B2DPoint& rData)
- : B2DPoint(rData)
- {}
-
- CoordinateData2D& operator=(const basegfx::B2DPoint& rData)
- {
- B2DPoint::operator=(rData);
- return *this;
- }
-
- void transform(const basegfx::B2DHomMatrix& rMatrix)
- {
- *this *= rMatrix;
- }
-};
class CoordinateDataArray2D
{
- typedef std::vector< CoordinateData2D > CoordinateData2DVector;
-
- CoordinateData2DVector maVector;
+private:
+ std::vector<basegfx::B2DPoint> maVector;
public:
explicit CoordinateDataArray2D(sal_uInt32 nCount)
@@ -80,11 +60,13 @@ public:
const basegfx::B2DPoint& getCoordinate(sal_uInt32 nIndex) const
{
+ assert(nIndex < maVector.size());
return maVector[nIndex];
}
void setCoordinate(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue)
{
+ assert(nIndex < maVector.size());
maVector[nIndex] = rValue;
}
@@ -93,59 +75,50 @@ public:
maVector.reserve(nCount);
}
- void append(const CoordinateData2D& rValue)
+ void append(const basegfx::B2DPoint& rValue)
{
maVector.push_back(rValue);
}
- void insert(sal_uInt32 nIndex, const CoordinateData2D& rValue, sal_uInt32 nCount)
+ void insert(sal_uInt32 nIndex, const basegfx::B2DPoint& rValue, sal_uInt32 nCount)
{
- if(nCount)
- {
- // add nCount copies of rValue
- CoordinateData2DVector::iterator aIndex(maVector.begin());
- aIndex += nIndex;
- maVector.insert(aIndex, nCount, rValue);
- }
+ assert(nCount > 0);
+ assert(nIndex <= maVector.size());
+ // add nCount copies of rValue
+ maVector.insert(maVector.begin() + nIndex, nCount, rValue);
}
void insert(sal_uInt32 nIndex, const CoordinateDataArray2D& rSource)
{
- const sal_uInt32 nCount(rSource.maVector.size());
-
- if(nCount)
- {
- // insert data
- CoordinateData2DVector::iterator aIndex(maVector.begin());
- aIndex += nIndex;
- CoordinateData2DVector::const_iterator aStart(rSource.maVector.begin());
- CoordinateData2DVector::const_iterator aEnd(rSource.maVector.end());
- maVector.insert(aIndex, aStart, aEnd);
- }
+ assert(rSource.maVector.size() > 0);
+ assert(nIndex <= maVector.size());
+ // insert data
+ auto aIndex = maVector.begin();
+ aIndex += nIndex;
+ auto aStart = rSource.maVector.cbegin();
+ auto aEnd = rSource.maVector.cend();
+ maVector.insert(aIndex, aStart, aEnd);
}
void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
{
- if(nCount)
- {
- // remove point data
- CoordinateData2DVector::iterator aStart(maVector.begin());
- aStart += nIndex;
- const CoordinateData2DVector::iterator aEnd(aStart + nCount);
- maVector.erase(aStart, aEnd);
- }
+ assert(nCount > 0);
+ assert(nIndex + nCount <= maVector.size());
+ // remove point data
+ const auto aStart = maVector.begin() + nIndex;
+ const auto aEnd = aStart + nCount;
+ maVector.erase(aStart, aEnd);
}
void flip(bool bIsClosed)
{
- if(maVector.size() <= 1)
- return;
+ assert(maVector.size() > 1);
// to keep the same point at index 0, just flip all points except the
// first one when closed
const sal_uInt32 nHalfSize(bIsClosed ? (maVector.size() - 1) >> 1 : maVector.size() >> 1);
- CoordinateData2DVector::iterator aStart(bIsClosed ? maVector.begin() + 1 : maVector.begin());
- CoordinateData2DVector::iterator aEnd(maVector.end() - 1);
+ auto aStart = bIsClosed ? maVector.begin() + 1 : maVector.begin();
+ auto aEnd = maVector.end() - 1;
for(sal_uInt32 a(0); a < nHalfSize; a++)
{
@@ -188,9 +161,9 @@ public:
void transform(const basegfx::B2DHomMatrix& rMatrix)
{
- for (auto & elem : maVector)
+ for (auto& point : maVector)
{
- elem.transform(rMatrix);
+ point *= rMatrix;
}
}
};
@@ -252,10 +225,9 @@ public:
ControlVectorArray2D(const ControlVectorArray2D& rOriginal, sal_uInt32 nIndex, sal_uInt32 nCount)
: mnUsedVectors(0)
{
- ControlVectorPair2DVector::const_iterator aStart(rOriginal.maVector.begin());
- aStart += nIndex;
- ControlVectorPair2DVector::const_iterator aEnd(aStart);
- aEnd += nCount;
+ assert(nIndex + nCount <= rOriginal.maVector.size());
+ auto aStart(rOriginal.maVector.begin() + nIndex);
+ auto aEnd(aStart + nCount);
maVector.reserve(nCount);
for(; aStart != aEnd; ++aStart)
@@ -282,6 +254,7 @@ public:
const basegfx::B2DVector& getPrevVector(sal_uInt32 nIndex) const
{
+ assert(nIndex < maVector.size());
return maVector[nIndex].getPrevVector();
}
@@ -314,6 +287,7 @@ public:
const basegfx::B2DVector& getNextVector(sal_uInt32 nIndex) const
{
+ assert(nIndex < maVector.size());
return maVector[nIndex].getNextVector();
}
@@ -357,13 +331,11 @@ public:
void insert(sal_uInt32 nIndex, const ControlVectorPair2D& rValue, sal_uInt32 nCount)
{
- if(!nCount)
- return;
+ assert(nCount > 0);
+ assert(nIndex <= maVector.size());
// add nCount copies of rValue
- ControlVectorPair2DVector::iterator aIndex(maVector.begin());
- aIndex += nIndex;
- maVector.insert(aIndex, nCount, rValue);
+ maVector.insert(maVector.begin() + nIndex, nCount, rValue);
if(!rValue.getPrevVector().equalZero())
mnUsedVectors += nCount;
@@ -374,14 +346,11 @@ public:
void insert(sal_uInt32 nIndex, const ControlVectorArray2D& rSource)
{
- const sal_uInt32 nCount(rSource.maVector.size());
-
- if(!nCount)
- return;
+ assert(rSource.maVector.size() > 0);
+ assert(nIndex <= maVector.size());
// insert data
- ControlVectorPair2DVector::iterator aIndex(maVector.begin());
- aIndex += nIndex;
+ ControlVectorPair2DVector::iterator aIndex(maVector.begin() + nIndex);
ControlVectorPair2DVector::const_iterator aStart(rSource.maVector.begin());
ControlVectorPair2DVector::const_iterator aEnd(rSource.maVector.end());
maVector.insert(aIndex, aStart, aEnd);
@@ -398,8 +367,8 @@ public:
void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
{
- if(!nCount)
- return;
+ assert(nCount > 0);
+ assert(nIndex + nCount <= maVector.size());
const ControlVectorPair2DVector::iterator aDeleteStart(maVector.begin() + nIndex);
const ControlVectorPair2DVector::iterator aDeleteEnd(aDeleteStart + nCount);
@@ -420,8 +389,7 @@ public:
void flip(bool bIsClosed)
{
- if(maVector.size() <= 1)
- return;
+ assert(maVector.size() > 1);
// to keep the same point at index 0, just flip all points except the
// first one when closed
@@ -460,7 +428,7 @@ class ImplBufferedData : public basegfx::SystemDependentDataHolder
{
private:
// Possibility to hold the last subdivision
- std::optional< basegfx::B2DPolygon > mpDefaultSubdivision;
+ mutable std::optional< basegfx::B2DPolygon > mpDefaultSubdivision;
// Possibility to hold the last B2DRange calculation
mutable std::optional< basegfx::B2DRange > moB2DRange;
@@ -474,7 +442,7 @@ public:
{
if(!mpDefaultSubdivision)
{
- const_cast< ImplBufferedData* >(this)->mpDefaultSubdivision = basegfx::utils::adaptiveSubdivideByAngle(rSource);
+ mpDefaultSubdivision = basegfx::utils::adaptiveSubdivideByAngle(rSource);
}
return *mpDefaultSubdivision;
@@ -563,7 +531,9 @@ private:
std::optional< ControlVectorArray2D > moControlVector;
// buffered data for e.g. default subdivision and range
- std::unique_ptr< ImplBufferedData > mpBufferedData;
+ // we do not want to 'modify' the ImplB2DPolygon,
+ // but add buffered data that is valid for all referencing instances
+ mutable std::unique_ptr<ImplBufferedData> mpBufferedData;
// flag which decides if this polygon is opened or closed
bool mbIsClosed;
@@ -578,7 +548,7 @@ public:
if(!mpBufferedData)
{
- const_cast< ImplB2DPolygon* >(this)->mpBufferedData.reset(new ImplBufferedData);
+ mpBufferedData.reset(new ImplBufferedData);
}
return mpBufferedData->getDefaultAdaptiveSubdivision(rSource);
@@ -588,7 +558,7 @@ public:
{
if(!mpBufferedData)
{
- const_cast< ImplB2DPolygon* >(this)->mpBufferedData.reset(new ImplBufferedData);
+ mpBufferedData.reset(new ImplBufferedData);
}
return mpBufferedData->getB2DRange(rSource);
@@ -713,7 +683,7 @@ public:
void append(const basegfx::B2DPoint& rPoint)
{
mpBufferedData.reset(); // TODO: is this needed?
- const CoordinateData2D aCoordinate(rPoint);
+ const auto aCoordinate = rPoint;
maPoints.append(aCoordinate);
if(moControlVector)
@@ -725,20 +695,23 @@ public:
void insert(sal_uInt32 nIndex, const basegfx::B2DPoint& rPoint, sal_uInt32 nCount)
{
- if(nCount)
- {
- mpBufferedData.reset();
- CoordinateData2D aCoordinate(rPoint);
- maPoints.insert(nIndex, aCoordinate, nCount);
+ assert(nCount > 0);
+ mpBufferedData.reset();
+ auto aCoordinate = rPoint;
+ maPoints.insert(nIndex, aCoordinate, nCount);
- if(moControlVector)
- {
- ControlVectorPair2D aVectorPair;
- moControlVector->insert(nIndex, aVectorPair, nCount);
- }
+ if(moControlVector)
+ {
+ ControlVectorPair2D aVectorPair;
+ moControlVector->insert(nIndex, aVectorPair, nCount);
}
}
+ void append(const basegfx::B2DPoint& rPoint, sal_uInt32 nCount)
+ {
+ insert(count(), rPoint, nCount);
+ }
+
const basegfx::B2DVector& getPrevControlVector(sal_uInt32 nIndex) const
{
if(moControlVector)
@@ -836,24 +809,19 @@ public:
setPrevControlVector(nCount, rPrev);
}
- void insert(sal_uInt32 nIndex, const ImplB2DPolygon& rSource)
+ void append(const ImplB2DPolygon& rSource)
{
- const sal_uInt32 nCount(rSource.maPoints.count());
-
- if(!nCount)
- return;
+ assert(rSource.maPoints.count() > 0);
+ const sal_uInt32 nIndex = count();
mpBufferedData.reset();
- if(rSource.moControlVector && rSource.moControlVector->isUsed() && !moControlVector)
- {
- moControlVector.emplace(maPoints.count());
- }
-
maPoints.insert(nIndex, rSource.maPoints);
if(rSource.moControlVector)
{
+ if (!moControlVector)
+ moControlVector.emplace(nIndex);
moControlVector->insert(nIndex, *rSource.moControlVector);
if(!moControlVector->isUsed())
@@ -862,15 +830,13 @@ public:
else if(moControlVector)
{
ControlVectorPair2D aVectorPair;
- moControlVector->insert(nIndex, aVectorPair, nCount);
+ moControlVector->insert(nIndex, aVectorPair, rSource.count());
}
}
void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
{
- if(!nCount)
- return;
-
+ assert(nCount > 0);
mpBufferedData.reset();
maPoints.remove(nIndex, nCount);
@@ -885,8 +851,7 @@ public:
void flip()
{
- if(maPoints.count() <= 1)
- return;
+ assert(maPoints.count() > 1);
mpBufferedData.reset();
@@ -1087,7 +1052,7 @@ public:
}
}
- void addOrReplaceSystemDependentData(basegfx::SystemDependentData_SharedPtr& rData)
+ void addOrReplaceSystemDependentData(basegfx::SystemDependentData_SharedPtr& rData) const
{
if(!mpBufferedData)
{
@@ -1110,7 +1075,10 @@ public:
namespace basegfx
{
- B2DPolygon::B2DPolygon() = default;
+ static o3tl::cow_wrapper<ImplB2DPolygon> DEFAULT;
+
+ B2DPolygon::B2DPolygon()
+ : mpPolygon(DEFAULT) {}
B2DPolygon::B2DPolygon(std::initializer_list<basegfx::B2DPoint> aPoints)
{
@@ -1127,9 +1095,6 @@ namespace basegfx
B2DPolygon::B2DPolygon(const B2DPolygon& rPolygon, sal_uInt32 nIndex, sal_uInt32 nCount)
: mpPolygon(ImplB2DPolygon(*rPolygon.mpPolygon, nIndex, nCount))
{
- // TODO(P2): one extra temporary here (cow_wrapper copies
- // given ImplB2DPolygon into its internal impl_t wrapper type)
- OSL_ENSURE(nIndex + nCount <= rPolygon.mpPolygon->count(), "B2DPolygon constructor outside range (!)");
}
B2DPolygon::~B2DPolygon() = default;
@@ -1151,11 +1116,6 @@ namespace basegfx
return ((*mpPolygon) == (*rPolygon.mpPolygon));
}
- bool B2DPolygon::operator!=(const B2DPolygon& rPolygon) const
- {
- return !(*this == rPolygon);
- }
-
sal_uInt32 B2DPolygon::count() const
{
return mpPolygon->count();
@@ -1163,16 +1123,12 @@ namespace basegfx
B2DPoint const & B2DPolygon::getB2DPoint(sal_uInt32 nIndex) const
{
- OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
-
return mpPolygon->getPoint(nIndex);
}
void B2DPolygon::setB2DPoint(sal_uInt32 nIndex, const B2DPoint& rValue)
{
- OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon access outside range (!)");
-
- if(std::as_const(mpPolygon)->getPoint(nIndex) != rValue)
+ if(getB2DPoint(nIndex) != rValue)
{
mpPolygon->setPoint(nIndex, rValue);
}
@@ -1185,8 +1141,6 @@ namespace basegfx
void B2DPolygon::insert(sal_uInt32 nIndex, const B2DPoint& rPoint, sal_uInt32 nCount)
{
- OSL_ENSURE(nIndex <= std::as_const(mpPolygon)->count(), "B2DPolygon Insert outside range (!)");
-
if(nCount)
{
mpPolygon->insert(nIndex, rPoint, nCount);
@@ -1197,7 +1151,7 @@ namespace basegfx
{
if(nCount)
{
- mpPolygon->insert(std::as_const(mpPolygon)->count(), rPoint, nCount);
+ mpPolygon->append(rPoint, nCount);
}
}
@@ -1206,40 +1160,45 @@ namespace basegfx
mpPolygon->append(rPoint);
}
- B2DPoint B2DPolygon::getPrevControlPoint(sal_uInt32 nIndex) const
+ const basegfx::B2DVector& B2DPolygon::getPrevControlVector(sal_uInt32 nIndex) const
+ {
+ return mpPolygon->getPrevControlVector(nIndex);
+ }
+
+ const basegfx::B2DVector& B2DPolygon::getNextControlVector(sal_uInt32 nIndex) const
{
- OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
+ return mpPolygon->getNextControlVector(nIndex);
+ }
- if(mpPolygon->areControlPointsUsed())
+ B2DPoint B2DPolygon::getPrevControlPoint(sal_uInt32 nIndex) const
+ {
+ if(areControlPointsUsed())
{
- return mpPolygon->getPoint(nIndex) + mpPolygon->getPrevControlVector(nIndex);
+ return getB2DPoint(nIndex) + getPrevControlVector(nIndex);
}
else
{
- return mpPolygon->getPoint(nIndex);
+ return getB2DPoint(nIndex);
}
}
B2DPoint B2DPolygon::getNextControlPoint(sal_uInt32 nIndex) const
{
- OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
-
- if(mpPolygon->areControlPointsUsed())
+ if(areControlPointsUsed())
{
- return mpPolygon->getPoint(nIndex) + mpPolygon->getNextControlVector(nIndex);
+ return getB2DPoint(nIndex) + getNextControlVector(nIndex);
}
else
{
- return mpPolygon->getPoint(nIndex);
+ return getB2DPoint(nIndex);
}
}
void B2DPolygon::setPrevControlPoint(sal_uInt32 nIndex, const B2DPoint& rValue)
{
- OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon access outside range (!)");
- const basegfx::B2DVector aNewVector(rValue - std::as_const(mpPolygon)->getPoint(nIndex));
+ const basegfx::B2DVector aNewVector(rValue - getB2DPoint(nIndex));
- if(std::as_const(mpPolygon)->getPrevControlVector(nIndex) != aNewVector)
+ if(getPrevControlVector(nIndex) != aNewVector)
{
mpPolygon->setPrevControlVector(nIndex, aNewVector);
}
@@ -1247,10 +1206,9 @@ namespace basegfx
void B2DPolygon::setNextControlPoint(sal_uInt32 nIndex, const B2DPoint& rValue)
{
- OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon access outside range (!)");
- const basegfx::B2DVector aNewVector(rValue - std::as_const(mpPolygon)->getPoint(nIndex));
+ const basegfx::B2DVector aNewVector(rValue - getB2DPoint(nIndex));
- if(std::as_const(mpPolygon)->getNextControlVector(nIndex) != aNewVector)
+ if(getNextControlVector(nIndex) != aNewVector)
{
mpPolygon->setNextControlVector(nIndex, aNewVector);
}
@@ -1258,12 +1216,11 @@ namespace basegfx
void B2DPolygon::setControlPoints(sal_uInt32 nIndex, const basegfx::B2DPoint& rPrev, const basegfx::B2DPoint& rNext)
{
- OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon access outside range (!)");
- const B2DPoint aPoint(std::as_const(mpPolygon)->getPoint(nIndex));
+ const B2DPoint aPoint(getB2DPoint(nIndex));
const basegfx::B2DVector aNewPrev(rPrev - aPoint);
const basegfx::B2DVector aNewNext(rNext - aPoint);
- if(std::as_const(mpPolygon)->getPrevControlVector(nIndex) != aNewPrev || std::as_const(mpPolygon)->getNextControlVector(nIndex) != aNewNext)
+ if(getPrevControlVector(nIndex) != aNewPrev || getNextControlVector(nIndex) != aNewNext)
{
mpPolygon->setControlVectors(nIndex, aNewPrev, aNewNext);
}
@@ -1271,9 +1228,7 @@ namespace basegfx
void B2DPolygon::resetPrevControlPoint(sal_uInt32 nIndex)
{
- OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon access outside range (!)");
-
- if(std::as_const(mpPolygon)->areControlPointsUsed() && !std::as_const(mpPolygon)->getPrevControlVector(nIndex).equalZero())
+ if(areControlPointsUsed() && !getPrevControlVector(nIndex).equalZero())
{
mpPolygon->setPrevControlVector(nIndex, B2DVector::getEmptyVector());
}
@@ -1281,9 +1236,7 @@ namespace basegfx
void B2DPolygon::resetNextControlPoint(sal_uInt32 nIndex)
{
- OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon access outside range (!)");
-
- if(std::as_const(mpPolygon)->areControlPointsUsed() && !std::as_const(mpPolygon)->getNextControlVector(nIndex).equalZero())
+ if(areControlPointsUsed() && !getNextControlVector(nIndex).equalZero())
{
mpPolygon->setNextControlVector(nIndex, B2DVector::getEmptyVector());
}
@@ -1291,7 +1244,7 @@ namespace basegfx
void B2DPolygon::resetControlPoints()
{
- if(std::as_const(mpPolygon)->areControlPointsUsed())
+ if(areControlPointsUsed())
{
mpPolygon->resetControlVectors();
}
@@ -1302,12 +1255,12 @@ namespace basegfx
const B2DPoint& rPrevControlPoint,
const B2DPoint& rPoint)
{
- const B2DVector aNewNextVector(std::as_const(mpPolygon)->count() ? B2DVector(rNextControlPoint - std::as_const(mpPolygon)->getPoint(std::as_const(mpPolygon)->count() - 1)) : B2DVector::getEmptyVector());
+ const B2DVector aNewNextVector(count() ? B2DVector(rNextControlPoint - getB2DPoint(count() - 1)) : B2DVector::getEmptyVector());
const B2DVector aNewPrevVector(rPrevControlPoint - rPoint);
if(aNewNextVector.equalZero() && aNewPrevVector.equalZero())
{
- mpPolygon->insert(std::as_const(mpPolygon)->count(), rPoint, 1);
+ mpPolygon->append(rPoint);
}
else
{
@@ -1317,7 +1270,7 @@ namespace basegfx
void B2DPolygon::appendQuadraticBezierSegment(const B2DPoint& rControlPoint, const B2DPoint& rPoint)
{
- if (std::as_const(mpPolygon)->count() == 0)
+ if (count() == 0)
{
mpPolygon->append(rPoint);
const double nX((rControlPoint.getX() * 2.0 + rPoint.getX()) / 3.0);
@@ -1326,7 +1279,7 @@ namespace basegfx
}
else
{
- const B2DPoint aPreviousPoint(std::as_const(mpPolygon)->getPoint(std::as_const(mpPolygon)->count() - 1));
+ const B2DPoint aPreviousPoint(getB2DPoint(count() - 1));
const double nX1((rControlPoint.getX() * 2.0 + aPreviousPoint.getX()) / 3.0);
const double nY1((rControlPoint.getY() * 2.0 + aPreviousPoint.getY()) / 3.0);
@@ -1344,26 +1297,20 @@ namespace basegfx
bool B2DPolygon::isPrevControlPointUsed(sal_uInt32 nIndex) const
{
- OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
-
- return (mpPolygon->areControlPointsUsed() && !mpPolygon->getPrevControlVector(nIndex).equalZero());
+ return (areControlPointsUsed() && !getPrevControlVector(nIndex).equalZero());
}
bool B2DPolygon::isNextControlPointUsed(sal_uInt32 nIndex) const
{
- OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
-
- return (mpPolygon->areControlPointsUsed() && !mpPolygon->getNextControlVector(nIndex).equalZero());
+ return (areControlPointsUsed() && !getNextControlVector(nIndex).equalZero());
}
B2VectorContinuity B2DPolygon::getContinuityInPoint(sal_uInt32 nIndex) const
{
- OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
-
- if(mpPolygon->areControlPointsUsed())
+ if(areControlPointsUsed())
{
- const B2DVector& rPrev(mpPolygon->getPrevControlVector(nIndex));
- const B2DVector& rNext(mpPolygon->getNextControlVector(nIndex));
+ const B2DVector& rPrev(getPrevControlVector(nIndex));
+ const B2DVector& rNext(getNextControlVector(nIndex));
return getContinuity(rPrev, rNext);
}
@@ -1375,19 +1322,18 @@ namespace basegfx
void B2DPolygon::getBezierSegment(sal_uInt32 nIndex, B2DCubicBezier& rTarget) const
{
- OSL_ENSURE(nIndex < mpPolygon->count(), "B2DPolygon access outside range (!)");
- const bool bNextIndexValidWithoutClose(nIndex + 1 < mpPolygon->count());
+ const bool bNextIndexValidWithoutClose(nIndex + 1 < count());
- if(bNextIndexValidWithoutClose || mpPolygon->isClosed())
+ if(bNextIndexValidWithoutClose || isClosed())
{
const sal_uInt32 nNextIndex(bNextIndexValidWithoutClose ? nIndex + 1 : 0);
- rTarget.setStartPoint(mpPolygon->getPoint(nIndex));
- rTarget.setEndPoint(mpPolygon->getPoint(nNextIndex));
+ rTarget.setStartPoint(getB2DPoint(nIndex));
+ rTarget.setEndPoint(getB2DPoint(nNextIndex));
- if(mpPolygon->areControlPointsUsed())
+ if(areControlPointsUsed())
{
- rTarget.setControlPointA(rTarget.getStartPoint() + mpPolygon->getNextControlVector(nIndex));
- rTarget.setControlPointB(rTarget.getEndPoint() + mpPolygon->getPrevControlVector(nNextIndex));
+ rTarget.setControlPointA(rTarget.getStartPoint() + getNextControlVector(nIndex));
+ rTarget.setControlPointB(rTarget.getEndPoint() + getPrevControlVector(nNextIndex));
}
else
{
@@ -1399,7 +1345,7 @@ namespace basegfx
else
{
// no valid edge at all, reset rTarget to current point
- const B2DPoint aPoint(mpPolygon->getPoint(nIndex));
+ const B2DPoint aPoint(getB2DPoint(nIndex));
rTarget.setStartPoint(aPoint);
rTarget.setEndPoint(aPoint);
rTarget.setControlPointA(aPoint);
@@ -1419,30 +1365,27 @@ namespace basegfx
void B2DPolygon::append(const B2DPolygon& rPoly, sal_uInt32 nIndex, sal_uInt32 nCount)
{
- if(!rPoly.count())
- return;
+ assert(nIndex + nCount <= rPoly.count());
if(!nCount)
{
- nCount = rPoly.count();
+ nCount = rPoly.count() - nIndex;
+ if (!nCount)
+ return;
}
if(nIndex == 0 && nCount == rPoly.count())
{
- mpPolygon->insert(std::as_const(mpPolygon)->count(), *rPoly.mpPolygon);
+ mpPolygon->append(*rPoly.mpPolygon);
}
else
{
- OSL_ENSURE(nIndex + nCount <= rPoly.mpPolygon->count(), "B2DPolygon Append outside range (!)");
- ImplB2DPolygon aTempPoly(*rPoly.mpPolygon, nIndex, nCount);
- mpPolygon->insert(std::as_const(mpPolygon)->count(), aTempPoly);
+ mpPolygon->append(ImplB2DPolygon(*rPoly.mpPolygon, nIndex, nCount));
}
}
void B2DPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
{
- OSL_ENSURE(nIndex + nCount <= std::as_const(mpPolygon)->count(), "B2DPolygon Remove outside range (!)");
-
if(nCount)
{
mpPolygon->remove(nIndex, nCount);
@@ -1477,7 +1420,7 @@ namespace basegfx
bool B2DPolygon::hasDoublePoints() const
{
- return (mpPolygon->count() > 1 && mpPolygon->hasDoublePoints());
+ return (count() > 1 && mpPolygon->hasDoublePoints());
}
void B2DPolygon::removeDoublePoints()
@@ -1491,7 +1434,7 @@ namespace basegfx
void B2DPolygon::transform(const B2DHomMatrix& rMatrix)
{
- if(std::as_const(mpPolygon)->count() && !rMatrix.isIdentity())
+ if(count() && !rMatrix.isIdentity())
{
mpPolygon->transform(rMatrix);
}
@@ -1499,14 +1442,7 @@ namespace basegfx
void B2DPolygon::addOrReplaceSystemDependentDataInternal(SystemDependentData_SharedPtr& rData) const
{
- // Need to get ImplB2DPolygon* from cow_wrapper *without*
- // calling make_unique() here - we do not want to
- // 'modify' the ImplB2DPolygon, but add buffered data that
- // is valid for all referencing instances
- const B2DPolygon* pMe(this);
- const ImplB2DPolygon* pMyImpl(pMe->mpPolygon.get());
-
- const_cast<ImplB2DPolygon*>(pMyImpl)->addOrReplaceSystemDependentData(rData);
+ mpPolygon->addOrReplaceSystemDependentData(rData);
}
SystemDependentData_SharedPtr B2DPolygon::getSystemDependantDataInternal(size_t hash_code) const
diff --git a/basegfx/source/polygon/b2dpolygonclipper.cxx b/basegfx/source/polygon/b2dpolygonclipper.cxx
index 246d5a10ab84..e2f1f060381e 100644
--- a/basegfx/source/polygon/b2dpolygonclipper.cxx
+++ b/basegfx/source/polygon/b2dpolygonclipper.cxx
@@ -25,6 +25,7 @@
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
#include <basegfx/utils/rectcliptools.hxx>
+#include <sal/log.hxx>
namespace basegfx::utils
{
@@ -161,12 +162,11 @@ namespace basegfx::utils
B2DPolyPolygon clipPolyPolygonOnParallelAxis(const B2DPolyPolygon& rCandidate, bool bParallelToXAxis, bool bAboveAxis, double fValueOnOtherAxis, bool bStroke)
{
- const sal_uInt32 nPolygonCount(rCandidate.count());
B2DPolyPolygon aRetval;
- for(sal_uInt32 a(0); a < nPolygonCount; a++)
+ for(const auto& rB2DPolygon : rCandidate )
{
- const B2DPolyPolygon aClippedPolyPolygon(clipPolygonOnParallelAxis(rCandidate.getB2DPolygon(a), bParallelToXAxis, bAboveAxis, fValueOnOtherAxis, bStroke));
+ const B2DPolyPolygon aClippedPolyPolygon(clipPolygonOnParallelAxis(rB2DPolygon, bParallelToXAxis, bAboveAxis, fValueOnOtherAxis, bStroke));
if(aClippedPolyPolygon.count())
{
@@ -283,10 +283,9 @@ namespace basegfx::utils
B2DPolyPolygon clipPolyPolygonOnRange(const B2DPolyPolygon& rCandidate, const B2DRange& rRange, bool bInside, bool bStroke)
{
- const sal_uInt32 nPolygonCount(rCandidate.count());
B2DPolyPolygon aRetval;
- if(!nPolygonCount)
+ if(!rCandidate.count())
{
// source is empty
return aRetval;
@@ -308,9 +307,9 @@ namespace basegfx::utils
if(bInside)
{
- for(sal_uInt32 a(0); a < nPolygonCount; a++)
+ for( const auto& rClippedPoly : rCandidate)
{
- const B2DPolyPolygon aClippedPolyPolygon(clipPolygonOnRange(rCandidate.getB2DPolygon(a), rRange, bInside, bStroke));
+ const B2DPolyPolygon aClippedPolyPolygon(clipPolygonOnRange(rClippedPoly , rRange, bInside, bStroke));
if(aClippedPolyPolygon.count())
{
@@ -330,7 +329,8 @@ namespace basegfx::utils
return aRetval;
}
- B2DPolyPolygon clipPolyPolygonOnPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPolyPolygon& rClip, bool bInside, bool bStroke)
+ B2DPolyPolygon clipPolyPolygonOnPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPolyPolygon& rClip,
+ bool bInside, bool bStroke, size_t* pPointLimit)
{
B2DPolyPolygon aRetval;
@@ -343,10 +343,10 @@ namespace basegfx::utils
// line clipping, create line snippets by first adding all cut points and
// then marching along the edges and detecting if they are inside or outside
// the clip polygon
- for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+ for(const auto& rPolygon : rCandidate)
{
// add cuts with clip to polygon, including bezier segments
- const B2DPolygon aCandidate(addPointsAtCuts(rCandidate.getB2DPolygon(a), rClip));
+ const B2DPolygon aCandidate(addPointsAtCuts(rPolygon, rClip));
const sal_uInt32 nPointCount(aCandidate.count());
const sal_uInt32 nEdgeCount(aCandidate.isClosed() ? nPointCount : nPointCount - 1);
B2DCubicBezier aEdge;
@@ -471,7 +471,14 @@ namespace basegfx::utils
// prepare 2nd source polygon in same way
- B2DPolyPolygon aMergePolyPolygonB = solveCrossovers(rCandidate);
+ B2DPolyPolygon aMergePolyPolygonB = solveCrossovers(rCandidate, pPointLimit);
+
+ if (pPointLimit && !*pPointLimit)
+ {
+ SAL_WARN("basegfx", "clipPolyPolygonOnPolyPolygon hit point limit");
+ return aRetval;
+ }
+
aMergePolyPolygonB = stripNeutralPolygons(aMergePolyPolygonB);
aMergePolyPolygonB = correctOrientations(aMergePolyPolygonB);
@@ -480,7 +487,7 @@ namespace basegfx::utils
// be solved again, they were solved in the preparation.
aRetval.append(aMergePolyPolygonA);
aRetval.append(aMergePolyPolygonB);
- aRetval = solveCrossovers(aRetval);
+ aRetval = solveCrossovers(aRetval, pPointLimit);
// now remove neutral polygons (closed, but no area). In a last
// step throw away all polygons which have a depth of less than 1
diff --git a/basegfx/source/polygon/b2dpolygoncutandtouch.cxx b/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
index 99a73ca82bc3..c91f0ec48f7d 100644
--- a/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
+++ b/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
@@ -19,6 +19,7 @@
#include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
#include <osl/diagnose.h>
+#include <sal/log.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/vector/b2dvector.hxx>
@@ -178,14 +179,12 @@ namespace basegfx
// (as in adaptiveSubdivideByCount) it is now possible to calculate back the
// cut positions in the polygon to relative cut positions on the original bezier
// segment.
- const sal_uInt32 nTempPointCount(rPointVector.size());
const sal_uInt32 nEdgeCount(rPolygon.count() ? rPolygon.count() - 1 : 0);
- if(nTempPointCount && nEdgeCount)
+ if(!rPointVector.empty() && nEdgeCount)
{
- for(sal_uInt32 a(0); a < nTempPointCount; a++)
+ for( const auto& rTempPoint : rPointVector )
{
- const temporaryPoint& rTempPoint = rPointVector[a];
const double fCutPosInPolygon(static_cast<double>(rTempPoint.getIndex()) + rTempPoint.getCut());
const double fRelativeCutPos(fCutPosInPolygon / static_cast<double>(nEdgeCount));
rTempPoints.emplace_back(rTempPoint.getPoint(), nInd, fRelativeCutPos);
@@ -203,7 +202,7 @@ namespace basegfx
// predefines for calls to this methods before method implementation
- void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints);
+ void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints, size_t* pPointLimit = nullptr);
void findTouches(const B2DPolygon& rEdgePolygon, const B2DPolygon& rPointPolygon, temporaryPointVector& rTempPoints);
void findCuts(const B2DPolygon& rCandidateA, const B2DPolygon& rCandidateB, temporaryPointVector& rTempPointsA, temporaryPointVector& rTempPointsB);
@@ -487,7 +486,7 @@ namespace basegfx
}
}
- void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints)
+ void findCuts(const B2DPolygon& rCandidate, temporaryPointVector& rTempPoints, size_t* pPointLimit)
{
// find out if there are edges with intersections (self-cuts). If yes, add
// entries to rTempPoints accordingly
@@ -588,6 +587,9 @@ namespace basegfx
findEdgeCutsTwoEdges(aCurrA, aNextA, aCurrB, aNextB, a, b, rTempPoints, rTempPoints);
}
+ if (pPointLimit && rTempPoints.size() > *pPointLimit)
+ break;
+
// prepare next step
aCurrB = aNextB;
}
@@ -596,6 +598,14 @@ namespace basegfx
aCurrA = aNextA;
}
}
+
+ if (pPointLimit)
+ {
+ if (rTempPoints.size() > *pPointLimit)
+ *pPointLimit = 0;
+ else
+ *pPointLimit -= rTempPoints.size();
+ }
}
} // end of anonymous namespace
@@ -841,14 +851,19 @@ namespace basegfx
namespace basegfx::utils
{
- B2DPolygon addPointsAtCutsAndTouches(const B2DPolygon& rCandidate)
+ B2DPolygon addPointsAtCutsAndTouches(const B2DPolygon& rCandidate, size_t* pPointLimit)
{
if(rCandidate.count())
{
temporaryPointVector aTempPoints;
findTouches(rCandidate, rCandidate, aTempPoints);
- findCuts(rCandidate, aTempPoints);
+ findCuts(rCandidate, aTempPoints, pPointLimit);
+ if (pPointLimit && !*pPointLimit)
+ {
+ SAL_WARN("basegfx", "addPointsAtCutsAndTouches hit point limit");
+ return rCandidate;
+ }
return mergeTemporaryPointsAndPolygon(rCandidate, aTempPoints);
}
@@ -858,7 +873,7 @@ namespace basegfx::utils
}
}
- B2DPolyPolygon addPointsAtCutsAndTouches(const B2DPolyPolygon& rCandidate)
+ B2DPolyPolygon addPointsAtCutsAndTouches(const B2DPolyPolygon& rCandidate, size_t* pPointLimit)
{
const sal_uInt32 nCount(rCandidate.count());
@@ -869,7 +884,7 @@ namespace basegfx::utils
if(nCount == 1)
{
// remove self intersections
- aRetval.append(addPointsAtCutsAndTouches(rCandidate.getB2DPolygon(0)));
+ aRetval.append(addPointsAtCutsAndTouches(rCandidate.getB2DPolygon(0), pPointLimit));
}
else
{
@@ -880,7 +895,13 @@ namespace basegfx::utils
for(a = 0; a < nCount; a++)
{
// use polygons with solved self intersections
- pTempData[a].setPolygon(addPointsAtCutsAndTouches(rCandidate.getB2DPolygon(a)));
+ pTempData[a].setPolygon(addPointsAtCutsAndTouches(rCandidate.getB2DPolygon(a), pPointLimit));
+ }
+
+ if (pPointLimit && !*pPointLimit)
+ {
+ SAL_WARN("basegfx", "addPointsAtCutsAndTouches hit point limit");
+ return rCandidate;
}
// now cuts and touches between the polygons
diff --git a/basegfx/source/polygon/b2dpolygontools.cxx b/basegfx/source/polygon/b2dpolygontools.cxx
index c6eb3cf5b28b..482d35d4df1d 100644
--- a/basegfx/source/polygon/b2dpolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolygontools.cxx
@@ -18,6 +18,7 @@
*/
#include <numeric>
#include <algorithm>
+#include <stack>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
@@ -157,7 +158,7 @@ namespace basegfx::utils
return rCandidate.getContinuityInPoint(nIndex);
}
- B2DPolygon adaptiveSubdivideByDistance(const B2DPolygon& rCandidate, double fDistanceBound)
+ B2DPolygon adaptiveSubdivideByDistance(const B2DPolygon& rCandidate, double fDistanceBound, int nRecurseLimit)
{
if(rCandidate.areControlPointsUsed())
{
@@ -213,7 +214,7 @@ namespace basegfx::utils
}
// call adaptive subdivide which adds edges to aRetval accordingly
- aBezier.adaptiveSubdivideByDistance(aRetval, fBound);
+ aBezier.adaptiveSubdivideByDistance(aRetval, fBound, nRecurseLimit);
}
else
{
@@ -1204,30 +1205,26 @@ namespace basegfx::utils
void applyLineDashing(
const B2DPolygon& rCandidate,
const std::vector<double>& rDotDashArray,
- std::function<void(const basegfx::B2DPolygon& rSnippet)> aLineTargetCallback,
- std::function<void(const basegfx::B2DPolygon& rSnippet)> aGapTargetCallback,
+ const std::function<void(const basegfx::B2DPolygon& rSnippet)>& rLineTargetCallback,
+ const std::function<void(const basegfx::B2DPolygon& rSnippet)>& rGapTargetCallback,
double fDotDashLength)
{
const sal_uInt32 nPointCount(rCandidate.count());
const sal_uInt32 nDotDashCount(rDotDashArray.size());
- if(fTools::lessOrEqual(fDotDashLength, 0.0))
+ if(fDotDashLength <= 0.0)
{
fDotDashLength = std::accumulate(rDotDashArray.begin(), rDotDashArray.end(), 0.0);
}
- if(fTools::lessOrEqual(fDotDashLength, 0.0) || (!aLineTargetCallback && !aGapTargetCallback) || !nPointCount)
+ if(fDotDashLength <= 0.0 || (!rLineTargetCallback && !rGapTargetCallback) || !nPointCount)
{
// parameters make no sense, just add source to targets
- if(aLineTargetCallback)
- {
- aLineTargetCallback(rCandidate);
- }
+ if (rLineTargetCallback)
+ rLineTargetCallback(rCandidate);
- if(aGapTargetCallback)
- {
- aGapTargetCallback(rCandidate);
- }
+ if (rGapTargetCallback)
+ rGapTargetCallback(rCandidate);
return;
}
@@ -1255,7 +1252,6 @@ namespace basegfx::utils
// to enlarge these as needed
const double fFactor(fCandidateLength / fAllowedLength);
std::for_each(aDotDashArray.begin(), aDotDashArray.end(), [&fFactor](double &f){ f *= fFactor; });
- fDotDashLength *= fFactor;
}
// prepare current edge's start
@@ -1299,8 +1295,8 @@ namespace basegfx::utils
while(fTools::less(fDotDashMovingLength, fEdgeLength))
{
// new split is inside edge, create and append snippet [fLastDotDashMovingLength, fDotDashMovingLength]
- const bool bHandleLine(bIsLine && aLineTargetCallback);
- const bool bHandleGap(!bIsLine && aGapTargetCallback);
+ const bool bHandleLine(bIsLine && rLineTargetCallback);
+ const bool bHandleGap(!bIsLine && rGapTargetCallback);
if(bHandleLine || bHandleGap)
{
@@ -1317,12 +1313,12 @@ namespace basegfx::utils
if(bHandleLine)
{
- implHandleSnippet(aSnippet, aLineTargetCallback, aFirstLine, aLastLine);
+ implHandleSnippet(aSnippet, rLineTargetCallback, aFirstLine, aLastLine);
}
if(bHandleGap)
{
- implHandleSnippet(aSnippet, aGapTargetCallback, aFirstGap, aLastGap);
+ implHandleSnippet(aSnippet, rGapTargetCallback, aFirstGap, aLastGap);
}
aSnippet.clear();
@@ -1335,8 +1331,8 @@ namespace basegfx::utils
}
// append closing snippet [fLastDotDashMovingLength, fEdgeLength]
- const bool bHandleLine(bIsLine && aLineTargetCallback);
- const bool bHandleGap(!bIsLine && aGapTargetCallback);
+ const bool bHandleLine(bIsLine && rLineTargetCallback);
+ const bool bHandleGap(!bIsLine && rGapTargetCallback);
if(bHandleLine || bHandleGap)
{
@@ -1367,8 +1363,8 @@ namespace basegfx::utils
while(fTools::less(fDotDashMovingLength, fEdgeLength))
{
// new split is inside edge, create and append snippet [fLastDotDashMovingLength, fDotDashMovingLength]
- const bool bHandleLine(bIsLine && aLineTargetCallback);
- const bool bHandleGap(!bIsLine && aGapTargetCallback);
+ const bool bHandleLine(bIsLine && rLineTargetCallback);
+ const bool bHandleGap(!bIsLine && rGapTargetCallback);
if(bHandleLine || bHandleGap)
{
@@ -1381,12 +1377,12 @@ namespace basegfx::utils
if(bHandleLine)
{
- implHandleSnippet(aSnippet, aLineTargetCallback, aFirstLine, aLastLine);
+ implHandleSnippet(aSnippet, rLineTargetCallback, aFirstLine, aLastLine);
}
if(bHandleGap)
{
- implHandleSnippet(aSnippet, aGapTargetCallback, aFirstGap, aLastGap);
+ implHandleSnippet(aSnippet, rGapTargetCallback, aFirstGap, aLastGap);
}
aSnippet.clear();
@@ -1399,8 +1395,8 @@ namespace basegfx::utils
}
// append snippet [fLastDotDashMovingLength, fEdgeLength]
- const bool bHandleLine(bIsLine && aLineTargetCallback);
- const bool bHandleGap(!bIsLine && aGapTargetCallback);
+ const bool bHandleLine(bIsLine && rLineTargetCallback);
+ const bool bHandleGap(!bIsLine && rGapTargetCallback);
if(bHandleLine || bHandleGap)
{
@@ -1424,28 +1420,28 @@ namespace basegfx::utils
// append last intermediate results (if exists)
if(aSnippet.count())
{
- const bool bHandleLine(bIsLine && aLineTargetCallback);
- const bool bHandleGap(!bIsLine && aGapTargetCallback);
+ const bool bHandleLine(bIsLine && rLineTargetCallback);
+ const bool bHandleGap(!bIsLine && rGapTargetCallback);
if(bHandleLine)
{
- implHandleSnippet(aSnippet, aLineTargetCallback, aFirstLine, aLastLine);
+ implHandleSnippet(aSnippet, rLineTargetCallback, aFirstLine, aLastLine);
}
if(bHandleGap)
{
- implHandleSnippet(aSnippet, aGapTargetCallback, aFirstGap, aLastGap);
+ implHandleSnippet(aSnippet, rGapTargetCallback, aFirstGap, aLastGap);
}
}
- if(bIsClosed && aLineTargetCallback)
+ if(bIsClosed && rLineTargetCallback)
{
- implHandleFirstLast(aLineTargetCallback, aFirstLine, aLastLine);
+ implHandleFirstLast(rLineTargetCallback, aFirstLine, aLastLine);
}
- if(bIsClosed && aGapTargetCallback)
+ if(bIsClosed && rGapTargetCallback)
{
- implHandleFirstLast(aGapTargetCallback, aFirstGap, aLastGap);
+ implHandleFirstLast(rGapTargetCallback, aFirstGap, aLastGap);
}
}
@@ -2823,7 +2819,7 @@ namespace basegfx::utils
{
OSL_ENSURE(rOld1.count() == rOld2.count(), "B2DPolygon interpolate: Different geometry (!)");
- if(fTools::lessOrEqual(t, 0.0) || rOld1 == rOld2)
+ if(t <= 0.0 || rOld1 == rOld2)
{
return rOld1;
}
@@ -3330,6 +3326,8 @@ namespace basegfx::utils
if(0 != nCount)
{
+ aRetval.reserve(nCount);
+
const css::awt::Point* pPointSequence = rPointSequenceSource.getConstArray();
const css::drawing::PolygonFlags* pFlagSequence = rFlagSequenceSource.getConstArray();
@@ -3573,6 +3571,105 @@ namespace basegfx::utils
}
}
+B2DPolygon createSimplifiedPolygon(const B2DPolygon& rCandidate, const double fTolerance)
+{
+ const sal_uInt32 nPointCount(rCandidate.count());
+ if (nPointCount < 3 || rCandidate.areControlPointsUsed())
+ return rCandidate;
+
+ // The solution does not use recursion directly, since this could lead to a stack overflow if
+ // nPointCount is very large. Instead, an own stack is used. This does not contain points, but
+ // pairs of low and high index of a range in rCandidate. A parallel boolean vector is used to note
+ // whether a point of rCandidate belongs to the output polygon or not.
+ std::vector<bool> bIsKeptVec(nPointCount, false);
+ bIsKeptVec[0] = true;
+ bIsKeptVec[nPointCount - 1] = true;
+ sal_uInt32 nKept = 2;
+ std::stack<std::pair<sal_uInt32, sal_uInt32>> aUnfinishedRangesStack;
+
+ // The RDP algorithm draws a straight line from the first point to the last point of a range.
+ // Then, from the inner points of the range, the point that has the largest distance to the line
+ // is determined. If the distance is greater than the tolerance, this point is kept and the lower
+ // and upper sub-segments of the range are treated in the same way. If the distance is smaller
+ // than the tolerance, none of the inner points will be kept.
+ sal_uInt32 nLowIndex = 0;
+ sal_uInt32 nHighIndex = nPointCount - 1;
+ bool bContinue = true;
+ do
+ {
+ bContinue = false;
+ if (nHighIndex - nLowIndex < 2) // maximal two points, range is finished.
+ {
+ // continue with sibling upper range if any
+ if (!aUnfinishedRangesStack.empty())
+ {
+ std::pair<sal_uInt32, sal_uInt32> aIndexPair = aUnfinishedRangesStack.top();
+ aUnfinishedRangesStack.pop();
+ nLowIndex = aIndexPair.first;
+ nHighIndex = aIndexPair.second;
+ bContinue = true;
+ }
+ }
+ else // the range needs examine the max distance
+ {
+ // Get maximal distance of inner points of the range to the straight line from start to
+ // end point of the range.
+ // For calculation of the distance we use the Hesse normal form of the straight line.
+ B2DPoint aLowPoint = rCandidate.getB2DPoint(nLowIndex);
+ B2DPoint aHighPoint = rCandidate.getB2DPoint(nHighIndex);
+ B2DVector aNormalVec
+ = basegfx::getNormalizedPerpendicular(B2DVector(aHighPoint) - B2DVector(aLowPoint));
+ double fLineOriginDistance = aNormalVec.scalar(B2DVector(aLowPoint));
+ double fMaxDist = 0;
+ sal_uInt32 nMaxPointIndex = nLowIndex;
+ for (sal_uInt32 i = nLowIndex + 1; i < nHighIndex; i++)
+ {
+ double fDistance
+ = aNormalVec.scalar(B2DVector(rCandidate.getB2DPoint(i))) - fLineOriginDistance;
+ if (std::fabs(fDistance) > fMaxDist)
+ {
+ fMaxDist = std::fabs(fDistance);
+ nMaxPointIndex = i;
+ }
+ }
+
+ if (fMaxDist >= fTolerance)
+ {
+ // We need to divide the current range into two sub ranges.
+ bIsKeptVec[nMaxPointIndex] = true;
+ nKept++;
+ // continue with lower sub range and push upper sub range to stack
+ aUnfinishedRangesStack.push(std::make_pair(nMaxPointIndex, nHighIndex));
+ nHighIndex = nMaxPointIndex;
+ bContinue = true;
+ }
+ else
+ {
+ // We do not keep any of the inner points of the current range.
+ // continue with sibling upper range if any
+ if (!aUnfinishedRangesStack.empty())
+ {
+ std::pair<sal_uInt32, sal_uInt32> aIndexPair = aUnfinishedRangesStack.top();
+ aUnfinishedRangesStack.pop();
+ nLowIndex = aIndexPair.first;
+ nHighIndex = aIndexPair.second;
+ bContinue = true;
+ }
+ }
+ }
+ } while (bContinue);
+
+ // Put all points which are marked as "keep" into the result polygon
+ B2DPolygon aResultPolygon;
+ aResultPolygon.reserve(nKept);
+ for (sal_uInt32 i = 0; i < nPointCount; i++)
+ {
+ if (bIsKeptVec[i])
+ aResultPolygon.append(rCandidate.getB2DPoint(i));
+ }
+ return aResultPolygon;
+}
+
} // end of namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basegfx/source/polygon/b2dpolygontriangulator.cxx b/basegfx/source/polygon/b2dpolygontriangulator.cxx
index 5fbd3960e585..b72e3da6039d 100644
--- a/basegfx/source/polygon/b2dpolygontriangulator.cxx
+++ b/basegfx/source/polygon/b2dpolygontriangulator.cxx
@@ -92,11 +92,6 @@ namespace basegfx
return (maStart.equal(rComp.maStart) && maEnd.equal(rComp.maEnd));
}
- bool operator!=(const EdgeEntry& rComp) const
- {
- return !(*this == rComp);
- }
-
const B2DPoint& getStart() const { return maStart; }
const B2DPoint& getEnd() const { return maEnd; }
@@ -218,18 +213,17 @@ namespace basegfx
// by Y,X,atan2 when adding nodes
if(rCandidate.count())
{
- for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+ for(const auto& rPolygonCandidate : rCandidate)
{
- const B2DPolygon& aPolygonCandidate(rCandidate.getB2DPolygon(a));
- const sal_uInt32 nCount(aPolygonCandidate.count());
+ const sal_uInt32 nCount {rPolygonCandidate.count()};
if(nCount > 2)
{
- B2DPoint aPrevPnt(aPolygonCandidate.getB2DPoint(nCount - 1));
+ B2DPoint aPrevPnt(rPolygonCandidate.getB2DPoint(nCount - 1));
for(sal_uInt32 b(0); b < nCount; b++)
{
- B2DPoint aNextPnt(aPolygonCandidate.getB2DPoint(b));
+ B2DPoint aNextPnt(rPolygonCandidate.getB2DPoint(b));
if( !aPrevPnt.equal(aNextPnt) )
{
diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx b/basegfx/source/polygon/b2dpolypolygon.cxx
index 4fd12bde4a10..fe2a7c7f94c8 100644
--- a/basegfx/source/polygon/b2dpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dpolypolygon.cxx
@@ -19,18 +19,23 @@
#include <sal/config.h>
+#include <cassert>
#include <utility>
#include <basegfx/polygon/b2dpolypolygon.hxx>
-#include <osl/diagnose.h>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/utils/systemdependentdata.hxx>
+namespace basegfx
+{
+
class ImplB2DPolyPolygon
{
basegfx::B2DPolygonVector maPolygons;
- std::unique_ptr< basegfx::SystemDependentDataHolder > mpSystemDependentDataHolder;
+ // we do not want to 'modify' the ImplB2DPolyPolygon,
+ // but add buffered data that is valid for all referencing instances
+ mutable std::unique_ptr<basegfx::SystemDependentDataHolder> mpSystemDependentDataHolder;
public:
ImplB2DPolyPolygon()
@@ -58,7 +63,7 @@ public:
return *this;
}
- void addOrReplaceSystemDependentData(basegfx::SystemDependentData_SharedPtr& rData)
+ void addOrReplaceSystemDependentData(basegfx::SystemDependentData_SharedPtr& rData) const
{
if(!mpSystemDependentDataHolder)
{
@@ -85,46 +90,55 @@ public:
const basegfx::B2DPolygon& getB2DPolygon(sal_uInt32 nIndex) const
{
+ assert(nIndex < maPolygons.size());
return maPolygons[nIndex];
}
void setB2DPolygon(sal_uInt32 nIndex, const basegfx::B2DPolygon& rPolygon)
{
+ assert(nIndex < maPolygons.size());
maPolygons[nIndex] = rPolygon;
}
void insert(sal_uInt32 nIndex, const basegfx::B2DPolygon& rPolygon, sal_uInt32 nCount)
{
- if(nCount)
- {
- // add nCount copies of rPolygon
- basegfx::B2DPolygonVector::iterator aIndex(maPolygons.begin());
- if( nIndex )
- aIndex += nIndex;
- maPolygons.insert(aIndex, nCount, rPolygon);
- }
+ assert(nCount > 0);
+ assert(nIndex <= maPolygons.size());
+ // add nCount copies of rPolygon
+ maPolygons.insert(maPolygons.begin() + nIndex, nCount, rPolygon);
+ }
+
+ void append(const basegfx::B2DPolygon& rPolygon, sal_uInt32 nCount)
+ {
+ insert(maPolygons.size(), rPolygon, nCount);
+ }
+
+ void reserve(sal_uInt32 nCount)
+ {
+ maPolygons.reserve(nCount);
}
void insert(sal_uInt32 nIndex, const basegfx::B2DPolyPolygon& rPolyPolygon)
{
+ assert(nIndex <= maPolygons.size());
// add nCount polygons from rPolyPolygon
- basegfx::B2DPolygonVector::iterator aIndex(maPolygons.begin());
- if( nIndex )
- aIndex += nIndex;
- maPolygons.insert(aIndex, rPolyPolygon.begin(), rPolyPolygon.end());
+ maPolygons.insert(maPolygons.begin() + nIndex, rPolyPolygon.begin(), rPolyPolygon.end());
+ }
+
+ void append(const basegfx::B2DPolyPolygon& rPolyPolygon)
+ {
+ insert(maPolygons.size(), rPolyPolygon);
}
void remove(sal_uInt32 nIndex, sal_uInt32 nCount)
{
- if(nCount)
- {
- // remove polygon data
- basegfx::B2DPolygonVector::iterator aStart(maPolygons.begin());
- aStart += nIndex;
- const basegfx::B2DPolygonVector::iterator aEnd(aStart + nCount);
+ assert(nCount > 0);
+ assert(nIndex + nCount <= maPolygons.size());
+ // remove polygon data
+ auto aStart(maPolygons.begin() + nIndex);
+ auto aEnd(aStart + nCount);
- maPolygons.erase(aStart, aEnd);
- }
+ maPolygons.erase(aStart, aEnd);
}
sal_uInt32 count() const
@@ -197,13 +211,7 @@ public:
}
};
-namespace basegfx
-{
-
- static o3tl::cow_wrapper<ImplB2DPolyPolygon> DEFAULT;
-
- B2DPolyPolygon::B2DPolyPolygon() :
- mpPolyPolygon(DEFAULT) {}
+ B2DPolyPolygon::B2DPolyPolygon() = default;
B2DPolyPolygon::B2DPolyPolygon(const B2DPolyPolygon&) = default;
@@ -222,8 +230,7 @@ namespace basegfx
void B2DPolyPolygon::makeUnique()
{
- mpPolyPolygon.make_unique();
- mpPolyPolygon->makeUnique();
+ mpPolyPolygon->makeUnique(); // non-const cow_wrapper::operator-> calls make_unique
}
bool B2DPolyPolygon::operator==(const B2DPolyPolygon& rPolyPolygon) const
@@ -234,11 +241,6 @@ namespace basegfx
return ((*mpPolyPolygon) == (*rPolyPolygon.mpPolyPolygon));
}
- bool B2DPolyPolygon::operator!=(const B2DPolyPolygon& rPolyPolygon) const
- {
- return !((*this) == rPolyPolygon);
- }
-
sal_uInt32 B2DPolyPolygon::count() const
{
return mpPolyPolygon->count();
@@ -246,26 +248,20 @@ namespace basegfx
B2DPolygon const & B2DPolyPolygon::getB2DPolygon(sal_uInt32 nIndex) const
{
- OSL_ENSURE(nIndex < mpPolyPolygon->count(), "B2DPolyPolygon access outside range (!)");
-
return mpPolyPolygon->getB2DPolygon(nIndex);
}
void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon& rPolygon)
{
- OSL_ENSURE(nIndex < std::as_const(mpPolyPolygon)->count(), "B2DPolyPolygon access outside range (!)");
-
if(getB2DPolygon(nIndex) != rPolygon)
mpPolyPolygon->setB2DPolygon(nIndex, rPolygon);
}
bool B2DPolyPolygon::areControlPointsUsed() const
{
- for(sal_uInt32 a(0); a < mpPolyPolygon->count(); a++)
+ for(sal_uInt32 a(0); a < count(); a++)
{
- const B2DPolygon& rPolygon = mpPolyPolygon->getB2DPolygon(a);
-
- if(rPolygon.areControlPointsUsed())
+ if(getB2DPolygon(a).areControlPointsUsed())
{
return true;
}
@@ -276,8 +272,6 @@ namespace basegfx
void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolygon& rPolygon, sal_uInt32 nCount)
{
- OSL_ENSURE(nIndex <= std::as_const(mpPolyPolygon)->count(), "B2DPolyPolygon Insert outside range (!)");
-
if(nCount)
mpPolyPolygon->insert(nIndex, rPolygon, nCount);
}
@@ -285,16 +279,27 @@ namespace basegfx
void B2DPolyPolygon::append(const B2DPolygon& rPolygon, sal_uInt32 nCount)
{
if(nCount)
- mpPolyPolygon->insert(std::as_const(mpPolyPolygon)->count(), rPolygon, nCount);
+ mpPolyPolygon->append(rPolygon, nCount);
+ }
+
+ void B2DPolyPolygon::reserve(sal_uInt32 nCount)
+ {
+ if(nCount)
+ mpPolyPolygon->reserve(nCount);
}
B2DPolyPolygon B2DPolyPolygon::getDefaultAdaptiveSubdivision() const
{
B2DPolyPolygon aRetval;
-
- for(sal_uInt32 a(0); a < mpPolyPolygon->count(); a++)
+ if (count())
{
- aRetval.append(mpPolyPolygon->getB2DPolygon(a).getDefaultAdaptiveSubdivision());
+ ImplB2DPolyPolygon& dest = *aRetval.mpPolyPolygon;
+ dest.reserve(count());
+
+ for (sal_uInt32 a(0); a < count(); a++)
+ {
+ dest.append(getB2DPolygon(a).getDefaultAdaptiveSubdivision(), 1);
+ }
}
return aRetval;
@@ -304,9 +309,9 @@ namespace basegfx
{
B2DRange aRetval;
- for(sal_uInt32 a(0); a < mpPolyPolygon->count(); a++)
+ for(sal_uInt32 a(0); a < count(); a++)
{
- aRetval.expand(mpPolyPolygon->getB2DPolygon(a).getB2DRange());
+ aRetval.expand(getB2DPolygon(a).getB2DRange());
}
return aRetval;
@@ -314,8 +319,6 @@ namespace basegfx
void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolyPolygon& rPolyPolygon)
{
- OSL_ENSURE(nIndex <= std::as_const(mpPolyPolygon)->count(), "B2DPolyPolygon Insert outside range (!)");
-
if(rPolyPolygon.count())
mpPolyPolygon->insert(nIndex, rPolyPolygon);
}
@@ -323,13 +326,11 @@ namespace basegfx
void B2DPolyPolygon::append(const B2DPolyPolygon& rPolyPolygon)
{
if(rPolyPolygon.count())
- mpPolyPolygon->insert(std::as_const(mpPolyPolygon)->count(), rPolyPolygon);
+ mpPolyPolygon->append(rPolyPolygon);
}
void B2DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
{
- OSL_ENSURE(nIndex + nCount <= std::as_const(mpPolyPolygon)->count(), "B2DPolyPolygon Remove outside range (!)");
-
if(nCount)
mpPolyPolygon->remove(nIndex, nCount);
}
@@ -341,19 +342,15 @@ namespace basegfx
bool B2DPolyPolygon::isClosed() const
{
- bool bRetval(true);
-
// PolyPOlygon is closed when all contained Polygons are closed or
// no Polygon exists.
- for(sal_uInt32 a(0); bRetval && a < mpPolyPolygon->count(); a++)
+ for(sal_uInt32 a(0); a < count(); a++)
{
- if(!mpPolyPolygon->getB2DPolygon(a).isClosed())
- {
- bRetval = false;
- }
+ if(!getB2DPolygon(a).isClosed())
+ return false;
}
- return bRetval;
+ return true;
}
void B2DPolyPolygon::setClosed(bool bNew)
@@ -364,7 +361,7 @@ namespace basegfx
void B2DPolyPolygon::flip()
{
- if(std::as_const(mpPolyPolygon)->count())
+ if(count())
{
mpPolyPolygon->flip();
}
@@ -372,17 +369,13 @@ namespace basegfx
bool B2DPolyPolygon::hasDoublePoints() const
{
- bool bRetval(false);
-
- for(sal_uInt32 a(0); !bRetval && a < mpPolyPolygon->count(); a++)
+ for(sal_uInt32 a(0); a < count(); a++)
{
- if(mpPolyPolygon->getB2DPolygon(a).hasDoublePoints())
- {
- bRetval = true;
- }
+ if(getB2DPolygon(a).hasDoublePoints())
+ return true;
}
- return bRetval;
+ return false;
}
void B2DPolyPolygon::removeDoublePoints()
@@ -393,7 +386,7 @@ namespace basegfx
void B2DPolyPolygon::transform(const B2DHomMatrix& rMatrix)
{
- if(std::as_const(mpPolyPolygon)->count() && !rMatrix.isIdentity())
+ if(count() && !rMatrix.isIdentity())
{
mpPolyPolygon->transform(rMatrix);
}
@@ -421,14 +414,7 @@ namespace basegfx
void B2DPolyPolygon::addOrReplaceSystemDependentDataInternal(SystemDependentData_SharedPtr& rData) const
{
- // Need to get ImplB2DPolyPolygon* from cow_wrapper *without*
- // calling make_unique() here - we do not want to
- // 'modify' the ImplB2DPolyPolygon, but add buffered data that
- // is valid for all referencing instances
- const B2DPolyPolygon* pMe(this);
- const ImplB2DPolyPolygon* pMyImpl(pMe->mpPolyPolygon.get());
-
- const_cast<ImplB2DPolyPolygon*>(pMyImpl)->addOrReplaceSystemDependentData(rData);
+ mpPolyPolygon->addOrReplaceSystemDependentData(rData);
}
SystemDependentData_SharedPtr B2DPolyPolygon::getSystemDependantDataInternal(size_t hash_code) const
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index ac1e10660607..4ad6eb5b219d 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -28,8 +28,10 @@
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
#include <sal/log.hxx>
+#include <utility>
#include <vector>
#include <algorithm>
+#include <numeric>
namespace basegfx
{
@@ -144,16 +146,16 @@ namespace basegfx
if(rVecA.cross(rVecB) > 0.0)
{
// b is left turn seen from a, test if Test is left of both and so inside (left is seen as inside)
- const bool bBoolA(fTools::moreOrEqual(rVecA.cross(rTest), 0.0));
- const bool bBoolB(fTools::lessOrEqual(rVecB.cross(rTest), 0.0));
+ const bool bBoolA(rVecA.cross(rTest) >= 0.0);
+ const bool bBoolB(rVecB.cross(rTest) <= 0.0);
return (bBoolA && bBoolB);
}
else
{
// b is right turn seen from a, test if Test is right of both and so outside (left is seen as inside)
- const bool bBoolA(fTools::lessOrEqual(rVecA.cross(rTest), 0.0));
- const bool bBoolB(fTools::moreOrEqual(rVecB.cross(rTest), 0.0));
+ const bool bBoolA(rVecA.cross(rTest) <= 0.0);
+ const bool bBoolB(rVecB.cross(rTest) >= 0.0);
return (!(bBoolA && bBoolB));
}
@@ -440,9 +442,9 @@ namespace basegfx
{
basegfx::B2DPoint* pLast(&maSNV[0].mpPN->maPoint);
- for(a = 1; a < nNodeCount; a++)
+ for(const auto& rSN : maSNV)
{
- basegfx::B2DPoint* pCurrent(&maSNV[a].mpPN->maPoint);
+ basegfx::B2DPoint* pCurrent(&rSN.mpPN->maPoint);
if(pLast->equal(*pCurrent) && (pLast->getX() != pCurrent->getX() || pLast->getY() != pCurrent->getY()))
{
@@ -513,8 +515,8 @@ namespace basegfx
impSolve();
}
- explicit solver(const B2DPolyPolygon& rOriginal)
- : maOriginal(rOriginal),
+ explicit solver(B2DPolyPolygon aOriginal, size_t* pPointLimit = nullptr)
+ : maOriginal(std::move(aOriginal)),
mbIsCurve(false),
mbChanged(false)
{
@@ -523,7 +525,7 @@ namespace basegfx
if(!nOriginalCount)
return;
- B2DPolyPolygon aGeometry(utils::addPointsAtCutsAndTouches(maOriginal));
+ B2DPolyPolygon aGeometry(utils::addPointsAtCutsAndTouches(maOriginal, pPointLimit));
aGeometry.removeDoublePoints();
aGeometry = utils::simplifyCurveSegments(aGeometry);
mbIsCurve = aGeometry.areControlPointsUsed();
@@ -532,25 +534,13 @@ namespace basegfx
if(!nOriginalCount)
return;
- sal_uInt32 nPointCount(0);
- sal_uInt32 a(0);
-
- // count points
- for(a = 0; a < nOriginalCount; a++)
- {
- const B2DPolygon& aCandidate(aGeometry.getB2DPolygon(a));
- const sal_uInt32 nCandCount(aCandidate.count());
-
- // If it's not a bezier curve, at least three points would be needed to have a
- // topological relevant (not empty) polygon. Since it's not known here if trivial
- // edges (dead ends) will be kept or sorted out, add non-bezier polygons with
- // more than one point.
- // For bezier curves, the minimum for defining an area is also one.
- if(nCandCount)
- {
- nPointCount += nCandCount;
- }
- }
+ // If it's not a bezier curve, at least three points would be needed to have a
+ // topological relevant (not empty) polygon. Since it's not known here if trivial
+ // edges (dead ends) will be kept or sorted out, add non-bezier polygons with
+ // more than one point.
+ // For bezier curves, the minimum for defining an area is also one.
+ sal_uInt32 nPointCount = std::accumulate( aGeometry.begin(), aGeometry.end(), sal_uInt32(0),
+ [](sal_uInt32 a, const basegfx::B2DPolygon& b){return a + b.count();});
if(!nPointCount)
return;
@@ -563,16 +553,15 @@ namespace basegfx
// fill data
sal_uInt32 nInsertIndex(0);
- for(a = 0; a < nOriginalCount; a++)
+ for(const auto& rCandidate : aGeometry )
{
- const B2DPolygon& aCandidate(aGeometry.getB2DPolygon(a));
- const sal_uInt32 nCandCount(aCandidate.count());
+ const sal_uInt32 nCandCount(rCandidate.count());
// use same condition as above, the data vector is
// pre-allocated
if(nCandCount)
{
- impAddPolygon(nInsertIndex, aCandidate);
+ impAddPolygon(nInsertIndex, rCandidate);
nInsertIndex += nCandCount;
}
}
@@ -684,11 +673,11 @@ namespace basegfx
namespace basegfx::utils
{
- B2DPolyPolygon solveCrossovers(const B2DPolyPolygon& rCandidate)
+ B2DPolyPolygon solveCrossovers(const B2DPolyPolygon& rCandidate, size_t* pPointLimit)
{
if(rCandidate.count() > 0)
{
- solver aSolver(rCandidate);
+ solver aSolver(rCandidate, pPointLimit);
return aSolver.getB2DPolyPolygon();
}
else
@@ -707,13 +696,11 @@ namespace basegfx::utils
{
B2DPolyPolygon aRetval;
- for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+ for(const auto& rPolygon : rCandidate)
{
- const B2DPolygon& aCandidate(rCandidate.getB2DPolygon(a));
-
- if(utils::getOrientation(aCandidate) != B2VectorOrientation::Neutral)
+ if(utils::getOrientation(rPolygon) != B2VectorOrientation::Neutral)
{
- aRetval.append(aCandidate);
+ aRetval.append(rPolygon);
}
}
diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx
index 74cdf23241d3..faf734f6e79e 100644
--- a/basegfx/source/polygon/b2dpolypolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolypolygontools.cxx
@@ -113,7 +113,7 @@ namespace basegfx::utils
return rCandidate;
}
- B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound)
+ B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound, int nRecurseLimit)
{
if(rCandidate.areControlPointsUsed())
{
@@ -123,7 +123,7 @@ namespace basegfx::utils
{
if(rPolygon.areControlPointsUsed())
{
- aRetval.append(utils::adaptiveSubdivideByDistance(rPolygon, fDistanceBound));
+ aRetval.append(utils::adaptiveSubdivideByDistance(rPolygon, fDistanceBound, nRecurseLimit));
}
else
{
@@ -514,7 +514,7 @@ namespace basegfx::utils
}
B2DPolygon aCurrSegment;
- const size_t sliceSize=SAL_N_ELEMENTS(numbers)/12;
+ const size_t sliceSize=std::size(numbers)/12;
const int* pCurrSegment=numbers + nNumber*sliceSize;
for( size_t i=0; i<sliceSize; i++, pCurrSegment++)
{
@@ -553,6 +553,7 @@ namespace basegfx::utils
const css::drawing::PointSequenceSequence& rPointSequenceSequenceSource)
{
B2DPolyPolygon aRetval;
+ aRetval.reserve(rPointSequenceSequenceSource.getLength());
const css::drawing::PointSequence* pPointSequence = rPointSequenceSequenceSource.getConstArray();
const css::drawing::PointSequence* pPointSeqEnd = pPointSequence + rPointSequenceSequenceSource.getLength();
diff --git a/basegfx/source/polygon/b2dsvgpolypolygon.cxx b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
index 323fff14c024..fe4f646eb3ba 100644
--- a/basegfx/source/polygon/b2dsvgpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
@@ -74,12 +74,12 @@ namespace basegfx::utils
bool importFromSvgD(
B2DPolyPolygon& o_rPolyPolygon,
- const OUString& rSvgDStatement,
+ std::u16string_view rSvgDStatement,
bool bHandleRelativeNextPointCompatible,
PointIndexSet* pHelpPointIndexSet)
{
o_rPolyPolygon.clear();
- const sal_Int32 nLen(rSvgDStatement.getLength());
+ const sal_Int32 nLen(rSvgDStatement.size());
sal_Int32 nPos(0);
double nLastX( 0.0 );
double nLastY( 0.0 );
@@ -272,7 +272,7 @@ namespace basegfx::utils
// get first control point. It's the reflection of the PrevControlPoint
// of the last point. If not existent, use current point (see SVG)
- B2DPoint aPrevControl(B2DPoint(nLastX, nLastY));
+ B2DPoint aPrevControl(nLastX, nLastY);
const sal_uInt32 nIndex(aCurrPoly.count() - 1);
if(aCurrPoly.areControlPointsUsed() && aCurrPoly.isPrevControlPointUsed(nIndex))
@@ -421,7 +421,7 @@ namespace basegfx::utils
// get first control point. It's the reflection of the PrevControlPoint
// of the last point. If not existent, use current point (see SVG)
- B2DPoint aPrevControl(B2DPoint(nLastX, nLastY));
+ B2DPoint aPrevControl(nLastX, nLastY);
const sal_uInt32 nIndex(aCurrPoly.count() - 1);
const B2DPoint aPrevPoint(aCurrPoly.getB2DPoint(nIndex));
@@ -664,10 +664,10 @@ namespace basegfx::utils
}
bool importFromSvgPoints( B2DPolygon& o_rPoly,
- const OUString& rSvgPointsAttribute )
+ std::u16string_view rSvgPointsAttribute )
{
o_rPoly.clear();
- const sal_Int32 nLen(rSvgPointsAttribute.getLength());
+ const sal_Int32 nLen(rSvgPointsAttribute.size());
sal_Int32 nPos(0);
double nX, nY;
@@ -704,9 +704,9 @@ namespace basegfx::utils
aResult.append(' ');
}
- aResult.append(aPoint.getX());
- aResult.append(',');
- aResult.append(aPoint.getY());
+ aResult.append(OUString::number(aPoint.getX())
+ + ","
+ + OUString::number(aPoint.getY()));
}
return aResult.makeStringAndClear();
diff --git a/basegfx/source/polygon/b2dtrapezoid.cxx b/basegfx/source/polygon/b2dtrapezoid.cxx
index b7991dbf55d4..654adc094ef9 100644
--- a/basegfx/source/polygon/b2dtrapezoid.cxx
+++ b/basegfx/source/polygon/b2dtrapezoid.cxx
@@ -174,6 +174,9 @@ namespace basegfx::trapezoidhelper
// method for cut support
B2DPoint getCutPointForGivenY(double fGivenY) const
{
+ // avoid div/0
+ if (getDeltaY() == 0)
+ return B2DPoint(getStart().getX(), fGivenY);
// Calculate cut point locally (do not use interpolate) since it is numerically
// necessary to guarantee the new, equal Y-coordinate
const double fFactor((fGivenY - getStart().getY()) / getDeltaY());
@@ -290,7 +293,7 @@ namespace basegfx::trapezoidhelper
const double fOldDeltaYStart(rCutPoint.getY() - aEdge.getStart().getY());
- if(fTools::lessOrEqual(fOldDeltaYStart, 0.0))
+ if(fOldDeltaYStart <= 0.0)
{
// do not split: the resulting edge would be horizontal
// correct it to new start point
@@ -300,7 +303,7 @@ namespace basegfx::trapezoidhelper
const double fNewDeltaYStart(aEdge.getEnd().getY() - rCutPoint.getY());
- if(fTools::lessOrEqual(fNewDeltaYStart, 0.0))
+ if(fNewDeltaYStart <= 0.0)
{
// do not split: the resulting edge would be horizontal
// correct it to new end point
@@ -946,7 +949,7 @@ namespace basegfx::utils
const B2DPoint& rPointB,
double fLineWidth)
{
- if(fTools::lessOrEqual(fLineWidth, 0.0))
+ if(fLineWidth <= 0.0)
{
// no line width
return;
@@ -1118,7 +1121,7 @@ namespace basegfx::utils
const B2DPolygon& rPolygon,
double fLineWidth)
{
- if(fTools::lessOrEqual(fLineWidth, 0.0))
+ if(fLineWidth <= 0.0)
{
return;
}
diff --git a/basegfx/source/polygon/b3dpolygon.cxx b/basegfx/source/polygon/b3dpolygon.cxx
index c1ee4b08345a..ebd9e3f4f7ea 100644
--- a/basegfx/source/polygon/b3dpolygon.cxx
+++ b/basegfx/source/polygon/b3dpolygon.cxx
@@ -1413,11 +1413,6 @@ namespace basegfx
return (*mpPolygon == *rPolygon.mpPolygon);
}
- bool B3DPolygon::operator!=(const B3DPolygon& rPolygon) const
- {
- return !(*this == rPolygon);
- }
-
sal_uInt32 B3DPolygon::count() const
{
return mpPolygon->count();
diff --git a/basegfx/source/polygon/b3dpolygontools.cxx b/basegfx/source/polygon/b3dpolygontools.cxx
index a1f65bef2f48..968624e0f28b 100644
--- a/basegfx/source/polygon/b3dpolygontools.cxx
+++ b/basegfx/source/polygon/b3dpolygontools.cxx
@@ -173,25 +173,22 @@ namespace basegfx::utils
void applyLineDashing(
const B3DPolygon& rCandidate,
const std::vector<double>& rDotDashArray,
- std::function<void(const basegfx::B3DPolygon& rSnippet)> aLineTargetCallback,
+ const std::function<void(const basegfx::B3DPolygon& rSnippet)>& rLineTargetCallback,
double fDotDashLength)
{
const sal_uInt32 nPointCount(rCandidate.count());
const sal_uInt32 nDotDashCount(rDotDashArray.size());
- if(fTools::lessOrEqual(fDotDashLength, 0.0))
+ if(fDotDashLength <= 0.0)
{
fDotDashLength = std::accumulate(rDotDashArray.begin(), rDotDashArray.end(), 0.0);
}
- if(fTools::lessOrEqual(fDotDashLength, 0.0) || !aLineTargetCallback || !nPointCount)
+ if(fDotDashLength <= 0.0 || !rLineTargetCallback || !nPointCount)
{
// parameters make no sense, just add source to targets
- if(aLineTargetCallback)
- {
- aLineTargetCallback(rCandidate);
- }
-
+ if (rLineTargetCallback)
+ rLineTargetCallback(rCandidate);
return;
}
@@ -219,7 +216,6 @@ namespace basegfx::utils
// to enlarge these as needed
const double fFactor(fCandidateLength / fAllowedLength);
std::for_each(aDotDashArray.begin(), aDotDashArray.end(), [&fFactor](double &f){ f *= fFactor; });
- fDotDashLength *= fFactor;
}
// prepare current edge's start
@@ -260,7 +256,7 @@ namespace basegfx::utils
aSnippet.append(interpolate(aCurrentPoint, aNextPoint, fDotDashMovingLength / fEdgeLength));
- implHandleSnippet(aSnippet, aLineTargetCallback, aFirstLine, aLastLine);
+ implHandleSnippet(aSnippet, rLineTargetCallback, aFirstLine, aLastLine);
aSnippet.clear();
}
@@ -295,13 +291,13 @@ namespace basegfx::utils
{
if(bIsLine)
{
- implHandleSnippet(aSnippet, aLineTargetCallback, aFirstLine, aLastLine);
+ implHandleSnippet(aSnippet, rLineTargetCallback, aFirstLine, aLastLine);
}
}
if(bIsClosed)
{
- implHandleFirstLast(aLineTargetCallback, aFirstLine, aLastLine);
+ implHandleFirstLast(rLineTargetCallback, aFirstLine, aLastLine);
}
}
diff --git a/basegfx/source/polygon/b3dpolypolygon.cxx b/basegfx/source/polygon/b3dpolypolygon.cxx
index 017906eef5b8..5a43cb876be6 100644
--- a/basegfx/source/polygon/b3dpolypolygon.cxx
+++ b/basegfx/source/polygon/b3dpolypolygon.cxx
@@ -223,11 +223,6 @@ namespace basegfx
return ((*mpPolyPolygon) == (*rPolyPolygon.mpPolyPolygon));
}
- bool B3DPolyPolygon::operator!=(const B3DPolyPolygon& rPolyPolygon) const
- {
- return !(*this == rPolyPolygon);
- }
-
sal_uInt32 B3DPolyPolygon::count() const
{
return mpPolyPolygon->count();
diff --git a/basegfx/source/polygon/b3dpolypolygontools.cxx b/basegfx/source/polygon/b3dpolypolygontools.cxx
index 62ddd3ae771f..ffd8bded4d59 100644
--- a/basegfx/source/polygon/b3dpolypolygontools.cxx
+++ b/basegfx/source/polygon/b3dpolypolygontools.cxx
@@ -37,12 +37,10 @@ namespace basegfx::utils
B3DRange getRange(const B3DPolyPolygon& rCandidate)
{
B3DRange aRetval;
- const sal_uInt32 nPolygonCount(rCandidate.count());
- for(sal_uInt32 a(0); a < nPolygonCount; a++)
+ for(const auto& rPolygon : rCandidate )
{
- const B3DPolygon& aCandidate = rCandidate.getB3DPolygon(a);
- aRetval.expand(getRange(aCandidate));
+ aRetval.expand(getRange(rPolygon));
}
return aRetval;
@@ -389,9 +387,9 @@ namespace basegfx::utils
{
B3DPolyPolygon aRetval;
- for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+ for( const auto& rB3DPolygon : rCandidate)
{
- aRetval.append(applyDefaultNormalsSphere(rCandidate.getB3DPolygon(a), rCenter));
+ aRetval.append(applyDefaultNormalsSphere(rB3DPolygon, rCenter));
}
return aRetval;
@@ -401,9 +399,9 @@ namespace basegfx::utils
{
B3DPolyPolygon aRetval;
- for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+ for( const auto& rB3DPolygon : rCandidate )
{
- aRetval.append(invertNormals(rCandidate.getB3DPolygon(a)));
+ aRetval.append(invertNormals(rB3DPolygon));
}
return aRetval;
@@ -413,9 +411,9 @@ namespace basegfx::utils
{
B3DPolyPolygon aRetval;
- for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+ for( const auto& rB3DPolygon : rCandidate)
{
- aRetval.append(applyDefaultTextureCoordinatesParallel(rCandidate.getB3DPolygon(a), rRange, bChangeX, bChangeY));
+ aRetval.append(applyDefaultTextureCoordinatesParallel(rB3DPolygon, rRange, bChangeX, bChangeY));
}
return aRetval;
@@ -425,9 +423,9 @@ namespace basegfx::utils
{
B3DPolyPolygon aRetval;
- for(sal_uInt32 a(0); a < rCandidate.count(); a++)
+ for( const auto& rB3DPolygon : rCandidate )
{
- aRetval.append(applyDefaultTextureCoordinatesSphere(rCandidate.getB3DPolygon(a), rCenter, bChangeX, bChangeY));
+ aRetval.append(applyDefaultTextureCoordinatesSphere(rB3DPolygon, rCenter, bChangeX, bChangeY));
}
return aRetval;
@@ -445,10 +443,9 @@ namespace basegfx::utils
{
sal_Int32 nInsideCount(0);
- for(sal_uInt32 a(0); a < nPolygonCount; a++)
+ for(const auto& rPolygon : rCandidate )
{
- const B3DPolygon& aPolygon(rCandidate.getB3DPolygon(a));
- const bool bInside(isInside(aPolygon, rPoint, false/*bWithBorder*/));
+ const bool bInside(isInside(rPolygon, rPoint, false/*bWithBorder*/));
if(bInside)
{
diff --git a/basegfx/source/range/b2dpolyrange.cxx b/basegfx/source/range/b2dpolyrange.cxx
index beb506fc8e4d..42ee21ec0d64 100644
--- a/basegfx/source/range/b2dpolyrange.cxx
+++ b/basegfx/source/range/b2dpolyrange.cxx
@@ -109,11 +109,6 @@ namespace basegfx
return ((*mpImpl) == (*rRange.mpImpl));
}
- bool B2DPolyRange::operator!=(const B2DPolyRange& rRange) const
- {
- return !(*this == rRange);
- }
-
sal_uInt32 B2DPolyRange::count() const
{
return mpImpl->count();
diff --git a/basegfx/source/range/b2drange.cxx b/basegfx/source/range/b2drange.cxx
index be025cc64b1d..1f20cce90a48 100644
--- a/basegfx/source/range/b2drange.cxx
+++ b/basegfx/source/range/b2drange.cxx
@@ -23,12 +23,12 @@
namespace basegfx
{
- B2DRange::B2DRange( const B2IRange& rRange )
+ B2DRange::B2DRange(const B2IRange& rRange)
{
- if( !rRange.isEmpty() )
+ if (!rRange.isEmpty())
{
- maRangeX = MyBasicRange(rRange.getMinX());
- maRangeY = MyBasicRange(rRange.getMinY());
+ maRangeX = basegfx::BasicRange<ValueType, TraitsType>(rRange.getMinX());
+ maRangeY = basegfx::BasicRange<ValueType, TraitsType>(rRange.getMinY());
maRangeX.expand(rRange.getMaxX());
maRangeY.expand(rRange.getMaxY());
@@ -48,9 +48,9 @@ namespace basegfx
}
}
- B2DRange& B2DRange::operator*=( const ::basegfx::B2DHomMatrix& rMat )
+ B2DRange& B2DRange::operator*=(const basegfx::B2DHomMatrix& rMatrix)
{
- transform(rMat);
+ transform(rMatrix);
return *this;
}
diff --git a/basegfx/source/tools/b2dclipstate.cxx b/basegfx/source/tools/b2dclipstate.cxx
index 7b8309e0de1c..3eefdd8c5f12 100644
--- a/basegfx/source/tools/b2dclipstate.cxx
+++ b/basegfx/source/tools/b2dclipstate.cxx
@@ -26,6 +26,7 @@
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
+#include <utility>
namespace basegfx::utils
@@ -39,8 +40,8 @@ namespace basegfx::utils
mePendingOps(UNION)
{}
- explicit ImplB2DClipState( const B2DPolyPolygon& rPoly ) :
- maClipPoly(rPoly),
+ explicit ImplB2DClipState( B2DPolyPolygon aPoly ) :
+ maClipPoly(std::move(aPoly)),
mePendingOps(UNION)
{}
@@ -414,11 +415,6 @@ namespace basegfx::utils
return ((*mpImpl) == (*rRHS.mpImpl));
}
- bool B2DClipState::operator!=(const B2DClipState& rRHS) const
- {
- return !(*this == rRHS);
- }
-
void B2DClipState::unionRange(const B2DRange& rRange)
{
mpImpl->unionRange(rRange);
diff --git a/basegfx/source/tools/bgradient.cxx b/basegfx/source/tools/bgradient.cxx
new file mode 100644
index 000000000000..9f98c54cfc1c
--- /dev/null
+++ b/basegfx/source/tools/bgradient.cxx
@@ -0,0 +1,996 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <basegfx/utils/bgradient.hxx>
+#include <basegfx/utils/gradienttools.hxx>
+#include <com/sun/star/awt/Gradient2.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <map>
+
+typedef std::map<OUString, OUString> StringMap;
+
+namespace
+{
+css::awt::GradientStyle lcl_getStyleFromString(std::u16string_view rStyle)
+{
+ if (rStyle == u"LINEAR")
+ return css::awt::GradientStyle_LINEAR;
+ else if (rStyle == u"AXIAL")
+ return css::awt::GradientStyle_AXIAL;
+ else if (rStyle == u"RADIAL")
+ return css::awt::GradientStyle_RADIAL;
+ else if (rStyle == u"ELLIPTICAL")
+ return css::awt::GradientStyle_ELLIPTICAL;
+ else if (rStyle == u"SQUARE")
+ return css::awt::GradientStyle_SQUARE;
+ else if (rStyle == u"RECT")
+ return css::awt::GradientStyle_RECT;
+
+ return css::awt::GradientStyle_LINEAR;
+}
+
+StringMap lcl_jsonToStringMap(std::u16string_view rJSON)
+{
+ StringMap aArgs;
+ if (rJSON.size() && rJSON[0] != '\0')
+ {
+ std::stringstream aStream(std::string(OUStringToOString(rJSON, RTL_TEXTENCODING_ASCII_US)));
+ boost::property_tree::ptree aTree;
+ boost::property_tree::read_json(aStream, aTree);
+
+ for (const auto& rPair : aTree)
+ {
+ aArgs[OUString::fromUtf8(rPair.first)]
+ = OUString::fromUtf8(rPair.second.get_value<std::string>("."));
+ }
+ }
+ return aArgs;
+}
+
+basegfx::BGradient lcl_buildGradientFromStringMap(StringMap& rMap)
+{
+ basegfx::BGradient aGradient(
+ basegfx::BColorStops(ColorToBColorConverter(rMap["startcolor"].toInt32(16)).getBColor(),
+ ColorToBColorConverter(rMap["endcolor"].toInt32(16)).getBColor()));
+
+ aGradient.SetGradientStyle(lcl_getStyleFromString(rMap["style"]));
+ aGradient.SetAngle(Degree10(rMap["angle"].toInt32()));
+
+ return aGradient;
+}
+}
+
+namespace basegfx
+{
+// constructor with two colors to explicitly create a
+// BColorStops for a single StartColor @0.0 & EndColor @1.0
+BColorStops::BColorStops(const BColor& rStart, const BColor& rEnd)
+{
+ emplace_back(0.0, rStart);
+ emplace_back(1.0, rEnd);
+}
+
+/* Helper to grep the correct ColorStop out of
+ ColorStops and interpolate as needed for given
+ relative value in fPosition in the range of [0.0 .. 1.0].
+ It also takes care of evtl. given RequestedSteps.
+ */
+BColor BColorStops::getInterpolatedBColor(double fPosition, sal_uInt32 nRequestedSteps,
+ BColorStopRange& rLastColorStopRange) const
+{
+ // no color at all, done
+ if (empty())
+ return BColor();
+
+ // outside range -> at start
+ const double fMin(front().getStopOffset());
+ if (fPosition < fMin)
+ return front().getStopColor();
+
+ // outside range -> at end
+ const double fMax(back().getStopOffset());
+ if (fPosition > fMax)
+ return back().getStopColor();
+
+ // special case for the 'classic' case with just two colors:
+ // we can optimize that and keep the speed/resources low
+ // by avoiding some calculations and an O(log(N)) array access
+ if (2 == size())
+ {
+ // if same StopOffset use front color
+ if (fTools::equal(fMin, fMax))
+ return front().getStopColor();
+
+ const basegfx::BColor aCStart(front().getStopColor());
+ const basegfx::BColor aCEnd(back().getStopColor());
+
+ // if colors are equal just return one
+ if (aCStart == aCEnd)
+ return aCStart;
+
+ // calculate Steps
+ const sal_uInt32 nSteps(
+ basegfx::utils::calculateNumberOfSteps(nRequestedSteps, aCStart, aCEnd));
+
+ // we need to extend the interpolation to the local
+ // range of ColorStops. Despite having two ColorStops
+ // these are not necessarily at 0.0 and 1.0, so may be
+ // not the classical Start/EndColor (what is allowed)
+ fPosition = (fPosition - fMin) / (fMax - fMin);
+ return basegfx::interpolate(aCStart, aCEnd,
+ nSteps > 1 ? floor(fPosition * nSteps) / double(nSteps - 1)
+ : fPosition);
+ }
+
+ // check if we need to newly populate the needed interpolation data
+ // or if we can re-use from last time.
+ // If this scope is not entered, we do not need the binary search. It's
+ // only a single buffered entry, and only used when more than three
+ // ColorStops exist, but makes a huge difference compared with accessing
+ // the sorted ColorStop vector each time.
+ // NOTE: with this simple change I get very high hit rates, e.g. rotating
+ // a donut with gradient test '1' hit rate is at 0.99909440357755486
+ if (rLastColorStopRange.mfOffsetStart == rLastColorStopRange.mfOffsetEnd
+ || fPosition < rLastColorStopRange.mfOffsetStart
+ || fPosition > rLastColorStopRange.mfOffsetEnd)
+ {
+ // access needed spot in sorted array using binary search
+ // NOTE: This *seems* slow(er) when developing compared to just
+ // looping/accessing, but that's just due to the extensive
+ // debug test code created by the stl. In a pro version,
+ // all is good/fast as expected
+ const auto upperBound(std::upper_bound(begin(), end(), BColorStop(fPosition),
+ [](const BColorStop& x, const BColorStop& y) {
+ return x.getStopOffset() < y.getStopOffset();
+ }));
+
+ // no upper bound, done
+ if (end() == upperBound)
+ return back().getStopColor();
+
+ // lower bound is one entry back, access that
+ const auto lowerBound(upperBound - 1);
+
+ // no lower bound, done
+ if (end() == lowerBound)
+ return back().getStopColor();
+
+ // we have lower and upper bound, get colors and offsets
+ rLastColorStopRange.maColorStart = lowerBound->getStopColor();
+ rLastColorStopRange.maColorEnd = upperBound->getStopColor();
+ rLastColorStopRange.mfOffsetStart = lowerBound->getStopOffset();
+ rLastColorStopRange.mfOffsetEnd = upperBound->getStopOffset();
+ }
+
+ // when there are just two color steps this cannot happen, but when using
+ // a range of colors this *may* be used inside the range to represent
+ // single-colored regions inside a ColorRange. Use that color & done
+ if (rLastColorStopRange.maColorStart == rLastColorStopRange.maColorEnd)
+ return rLastColorStopRange.maColorStart;
+
+ // calculate number of steps and adapted proportional
+ // range for scaler in [0.0 .. 1.0]
+ const double fAdaptedScaler(
+ (fPosition - rLastColorStopRange.mfOffsetStart)
+ / (rLastColorStopRange.mfOffsetEnd - rLastColorStopRange.mfOffsetStart));
+ const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
+ nRequestedSteps, rLastColorStopRange.maColorStart, rLastColorStopRange.maColorEnd));
+
+ // interpolate & evtl. apply steps
+ return interpolate(rLastColorStopRange.maColorStart, rLastColorStopRange.maColorEnd,
+ nSteps > 1 ? floor(fAdaptedScaler * nSteps) / double(nSteps - 1)
+ : fAdaptedScaler);
+}
+
+/* Tooling method that allows to replace the StartColor in a
+ vector of ColorStops. A vector in 'ordered state' is expected,
+ so you may use/have used sortAndCorrect.
+ This method is for convenience & backwards compatibility, please
+ think about handling multi-colored gradients directly.
+ */
+void BColorStops::replaceStartColor(const BColor& rStart)
+{
+ BColorStops::iterator a1stNonStartColor(begin());
+
+ // search for highest existing non-StartColor - CAUTION,
+ // there might be none, one or multiple with StopOffset 0.0
+ while (a1stNonStartColor != end() && a1stNonStartColor->getStopOffset() <= 0.0)
+ a1stNonStartColor++;
+
+ // create new ColorStops by 1st adding new one and then all
+ // non-StartColor entries
+ BColorStops aNewColorStops;
+
+ aNewColorStops.reserve(size() + 1);
+ aNewColorStops.emplace_back(0.0, rStart);
+ aNewColorStops.insert(aNewColorStops.end(), a1stNonStartColor, end());
+
+ // assign & done
+ *this = aNewColorStops;
+}
+
+/* Tooling method that allows to replace the EndColor in a
+ vector of ColorStops. A vector in 'ordered state' is expected,
+ so you may use/have used sortAndCorrectColorStops.
+ This method is for convenience & backwards compatibility, please
+ think about handling multi-colored gradients directly.
+ */
+void BColorStops::replaceEndColor(const BColor& rEnd)
+{
+ // erase all evtl. existing EndColor(s)
+ while (!empty() && basegfx::fTools::moreOrEqual(back().getStopOffset(), 1.0))
+ pop_back();
+
+ // add at the end of existing ColorStops
+ emplace_back(1.0, rEnd);
+}
+
+/* Tooling method to linearly blend the Colors contained in
+ a given ColorStop vector against a given Color using the
+ given intensity values.
+ The intensity values fStartIntensity, fEndIntensity are
+ in the range of [0.0 .. 1.0] and describe how much the
+ blend is supposed to be done at the start color position
+ and the end color position respectively, where 0.0 means
+ to fully use the given BlendColor, 1.0 means to not change
+ the existing color in the ColorStop.
+ Every color entry in the given ColorStop is blended
+ relative to it's StopPosition, interpolating the
+ given intensities with the range [0.0 .. 1.0] to do so.
+ */
+void BColorStops::blendToIntensity(double fStartIntensity, double fEndIntensity,
+ const BColor& rBlendColor)
+{
+ // no entries, done
+ if (empty())
+ return;
+
+ // correct intensities (maybe assert when input was wrong)
+ fStartIntensity = std::max(std::min(1.0, fStartIntensity), 0.0);
+ fEndIntensity = std::max(std::min(1.0, fEndIntensity), 0.0);
+
+ // all 100%, no real blend, done
+ if (basegfx::fTools::equal(fStartIntensity, 1.0) && basegfx::fTools::equal(fEndIntensity, 1.0))
+ return;
+
+ // blend relative to StopOffset position
+ for (auto& candidate : *this)
+ {
+ const double fOffset(candidate.getStopOffset());
+ const double fIntensity((fStartIntensity * (1.0 - fOffset)) + (fEndIntensity * fOffset));
+ candidate = basegfx::BColorStop(
+ fOffset, basegfx::interpolate(rBlendColor, candidate.getStopColor(), fIntensity));
+ }
+}
+
+/* Tooling method to guarantee sort and correctness for
+ the given ColorStops vector.
+ A vector fulfilling these conditions is called to be
+ in 'ordered state'.
+
+ At return, the following conditions are guaranteed:
+ - contains no ColorStops with offset < 0.0 (will
+ be removed)
+ - contains no ColorStops with offset > 1.0 (will
+ be removed)
+ - ColorStops with identical offsets are now allowed
+ - will be sorted from lowest offset to highest
+
+ Some more notes:
+ - It can happen that the result is empty
+ - It is allowed to have consecutive entries with
+ the same color, this represents single-color
+ regions inside the gradient
+ - A entry with 0.0 is not required or forced, so
+ no 'StartColor' is technically required
+ - A entry with 1.0 is not required or forced, so
+ no 'EndColor' is technically required
+
+ All this is done in one run (sort + O(N)) without
+ creating a copy of the data in any form
+ */
+void BColorStops::sortAndCorrect()
+{
+ // no content, we are done
+ if (empty())
+ return;
+
+ if (1 == size())
+ {
+ // no gradient at all, but preserve given color
+ // evtl. correct offset to be in valid range [0.0 .. 1.0]
+ // NOTE: This does not move it to 0.0 or 1.0, it *can* still
+ // be somewhere in-between what is allowed
+ const BColorStop aEntry(front());
+ clear();
+ emplace_back(std::max(0.0, std::min(1.0, aEntry.getStopOffset())), aEntry.getStopColor());
+
+ // done
+ return;
+ }
+
+ // start with sorting the input data. Remember that
+ // this preserves the order of equal entries, where
+ // equal is defined here by offset (see use operator==)
+ std::sort(begin(), end());
+
+ // prepare status values
+ size_t write(0);
+
+ // use the paradigm of a band machine with two heads, read
+ // and write with write <= read all the time. Step over the
+ // data using read and check for valid entry. If valid, decide
+ // how to keep it
+ for (size_t read(0); read < size(); read++)
+ {
+ // get offset of entry at read position
+ double fOff((*this)[read].getStopOffset());
+
+ if (fOff < 0.0 && read + 1 < size())
+ {
+ // value < 0.0 and we have a next entry. check for gradient snippet
+ // containing 0.0 resp. StartColor
+ const double fOff2((*this)[read + 1].getStopOffset());
+
+ if (fOff2 > 0.0)
+ {
+ // read is the start of a gradient snippet containing 0.0. Correct
+ // entry to StartColor, interpolate to correct StartColor
+ (*this)[read]
+ = BColorStop(0.0, basegfx::interpolate((*this)[read].getStopColor(),
+ (*this)[read + 1].getStopColor(),
+ (0.0 - fOff) / (fOff2 - fOff)));
+
+ // adapt fOff
+ fOff = 0.0;
+ }
+ }
+
+ // step over < 0 values, these are outside and will be removed
+ if (fOff < 0.0)
+ {
+ continue;
+ }
+
+ if (basegfx::fTools::less(fOff, 1.0) && read + 1 < size())
+ {
+ // value < 1.0 and we have a next entry. check for gradient snippet
+ // containing 1.0 resp. EndColor
+ const double fOff2((*this)[read + 1].getStopOffset());
+
+ if (basegfx::fTools::more(fOff2, 1.0))
+ {
+ // read is the start of a gradient snippet containing 1.0. Correct
+ // next entry to EndColor, interpolate to correct EndColor
+ (*this)[read + 1]
+ = BColorStop(1.0, basegfx::interpolate((*this)[read].getStopColor(),
+ (*this)[read + 1].getStopColor(),
+ (1.0 - fOff) / (fOff2 - fOff)));
+
+ // adapt fOff
+ fOff = 1.0;
+ }
+ }
+
+ // step over > 1 values; even break, since all following
+ // entries will also be bigger due to being sorted, so done
+ if (basegfx::fTools::more(fOff, 1.0))
+ {
+ break;
+ }
+
+ // entry is valid value at read position
+ // copy if write target is empty (write at start) or when
+ // write target is different to read in color or offset
+ if (0 == write || !((*this)[read] == (*this)[write - 1]))
+ {
+ if (write != read)
+ {
+ // copy read to write backwards to close gaps
+ (*this)[write] = (*this)[read];
+ }
+
+ // always forward write position
+ write++;
+ }
+ }
+
+ // correct size when length is reduced. write is always at
+ // last used position + 1
+ if (size() > write)
+ {
+ if (0 == write)
+ {
+ // no valid entries at all, but not empty. This can only happen
+ // when all entries are below 0.0 or above 1.0 (else a gradient
+ // snippet spawning over both would have been detected)
+ if (back().getStopOffset() < 0.0)
+ {
+ // all outside too low, rescue last due to being closest to content
+ const BColor aBackColor(back().getStopColor());
+ clear();
+ emplace_back(0.0, aBackColor);
+ }
+ else // if (basegfx::fTools::more(front().getStopOffset(), 1.0))
+ {
+ // all outside too high, rescue first due to being closest to content
+ const BColor aFrontColor(front().getStopColor());
+ clear();
+ emplace_back(1.0, aFrontColor);
+ }
+ }
+ else
+ {
+ resize(write);
+ }
+ }
+}
+
+bool BColorStops::checkPenultimate() const
+{
+ // not needed when no ColorStops
+ if (empty())
+ return false;
+
+ // not needed when last ColorStop at the end or outside
+ if (basegfx::fTools::moreOrEqual(back().getStopOffset(), 1.0))
+ return false;
+
+ // get penultimate entry
+ const auto penultimate(rbegin() + 1);
+
+ // if there is none, we need no correction and are done
+ if (penultimate == rend())
+ return false;
+
+ // not needed when the last two ColorStops have different offset, then
+ // a visible range will be processed already
+ if (!basegfx::fTools::equal(back().getStopOffset(), penultimate->getStopOffset()))
+ return false;
+
+ // not needed when the last two ColorStops have the same Color, then the
+ // range before solves the problem
+ if (back().getStopColor() == penultimate->getStopColor())
+ return false;
+
+ return true;
+}
+
+/* Tooling method to check if a ColorStop vector is defined
+ by a single color. It returns true if this is the case.
+ If true is returned, rSingleColor contains that single
+ color for convenience.
+ NOTE: If no ColorStop is defined, a fallback to BColor-default
+ (which is black) and true will be returned
+ */
+bool BColorStops::isSingleColor(BColor& rSingleColor) const
+{
+ if (empty())
+ {
+ rSingleColor = BColor();
+ return true;
+ }
+
+ if (1 == size())
+ {
+ rSingleColor = front().getStopColor();
+ return true;
+ }
+
+ rSingleColor = front().getStopColor();
+
+ for (auto const& rCandidate : *this)
+ {
+ if (rCandidate.getStopColor() != rSingleColor)
+ return false;
+ }
+
+ return true;
+}
+
+/* Tooling method to reverse ColorStops, including offsets.
+ When also mirroring offsets a valid sort keeps valid.
+ */
+void BColorStops::reverseColorStops()
+{
+ // can use std::reverse, but also need to adapt offset(s)
+ std::reverse(begin(), end());
+ for (auto& candidate : *this)
+ candidate = BColorStop(1.0 - candidate.getStopOffset(), candidate.getStopColor());
+}
+
+// createSpaceAtStart creates fOffset space at start by
+// translating/scaling all entries to the right
+void BColorStops::createSpaceAtStart(double fOffset)
+{
+ // nothing to do if empty
+ if (empty())
+ return;
+
+ // correct offset to [0.0 .. 1.0]
+ fOffset = std::max(std::min(1.0, fOffset), 0.0);
+
+ // nothing to do if 0.0 == offset
+ if (basegfx::fTools::equalZero(fOffset))
+ return;
+
+ BColorStops aNewStops;
+
+ for (const auto& candidate : *this)
+ {
+ aNewStops.emplace_back(fOffset + (candidate.getStopOffset() * (1.0 - fOffset)),
+ candidate.getStopColor());
+ }
+
+ *this = aNewStops;
+}
+
+// removeSpaceAtStart removes fOffset space from start by
+// translating/scaling entries more or equal to fOffset
+// to the left. Entries less than fOffset will be removed
+void BColorStops::removeSpaceAtStart(double fOffset)
+{
+ // nothing to do if empty
+ if (empty())
+ return;
+
+ // correct factor to [0.0 .. 1.0]
+ fOffset = std::max(std::min(1.0, fOffset), 0.0);
+
+ // nothing to do if fOffset == 0.0
+ if (basegfx::fTools::equalZero(fOffset))
+ return;
+
+ BColorStops aNewStops;
+ const double fMul(basegfx::fTools::equal(fOffset, 1.0) ? 1.0 : 1.0 / (1.0 - fOffset));
+
+ for (const auto& candidate : *this)
+ {
+ if (basegfx::fTools::moreOrEqual(candidate.getStopOffset(), fOffset))
+ {
+ aNewStops.emplace_back((candidate.getStopOffset() - fOffset) * fMul,
+ candidate.getStopColor());
+ }
+ }
+
+ *this = aNewStops;
+}
+
+// try to detect if an empty/no-color-change area exists
+// at the start and return offset to it. Returns 0.0 if not.
+double BColorStops::detectPossibleOffsetAtStart() const
+{
+ BColor aSingleColor;
+ const bool bSingleColor(isSingleColor(aSingleColor));
+
+ // no useful offset for single color
+ if (bSingleColor)
+ return 0.0;
+
+ // here we know that we have at least two colors, so we have a
+ // color change. Find colors left and right of that first color change
+ BColorStops::const_iterator aColorR(begin());
+ BColorStops::const_iterator aColorL(aColorR++);
+
+ // aColorR would 1st get equal to end(), so no need to also check aColorL
+ // for end(). Loop as long as same color. Since we *have* a color change
+ // not even aColorR can get equal to end() before color inequality, but
+ // keep for safety
+ while (aColorR != end() && aColorL->getStopColor() == aColorR->getStopColor())
+ {
+ aColorL++;
+ aColorR++;
+ }
+
+ // also for safety: access values at aColorL below *only*
+ // if not equal to end(), but can theoretically not happen
+ if (aColorL == end())
+ {
+ return 0.0;
+ }
+
+ // return offset (maybe 0.0 what is OK)
+ return aColorL->getStopOffset();
+}
+
+// checks whether the color stops are symmetrical in color and offset.
+bool BColorStops::isSymmetrical() const
+{
+ if (empty())
+ return false;
+ if (1 == size())
+ return basegfx::fTools::equal(0.5, front().getStopOffset());
+
+ BColorStops::const_iterator aIter(begin()); // for going forward
+ BColorStops::const_iterator aRIter(end()); // for going backward
+ --aRIter;
+ // We have at least two elements, so aIter <= aRIter fails before iterators no longer point to
+ // an element.
+ while (aIter <= aRIter && aIter->getStopColor().equal(aRIter->getStopColor())
+ && basegfx::fTools::equal(aIter->getStopOffset(), 1.0 - aRIter->getStopOffset()))
+ {
+ ++aIter;
+ --aRIter;
+ }
+ return aIter > aRIter;
+}
+
+void BColorStops::doApplyAxial()
+{
+ // prepare new ColorStops
+ basegfx::BColorStops aNewColorStops;
+
+ // add gradient stops in reverse order, scaled to [0.0 .. 0.5]
+ basegfx::BColorStops::const_reverse_iterator aRevCurrColor(rbegin());
+
+ while (aRevCurrColor != rend())
+ {
+ aNewColorStops.emplace_back((1.0 - aRevCurrColor->getStopOffset()) * 0.5,
+ aRevCurrColor->getStopColor());
+ aRevCurrColor++;
+ }
+
+ // prepare non-reverse run
+ basegfx::BColorStops::const_iterator aCurrColor(begin());
+
+ if (basegfx::fTools::equalZero(aCurrColor->getStopOffset()))
+ {
+ // Caution: do not add 1st entry again, that would be double since it was
+ // already added as last element of the inverse run above. But only if
+ // the gradient has a start entry for 0.0 aka StartColor, else it is correct.
+ aCurrColor++;
+ }
+
+ // add gradient stops in non-reverse order, translated and scaled to [0.5 .. 1.0]
+ while (aCurrColor != end())
+ {
+ aNewColorStops.emplace_back((aCurrColor->getStopOffset() * 0.5) + 0.5,
+ aCurrColor->getStopColor());
+ aCurrColor++;
+ }
+
+ // apply color stops
+ *this = aNewColorStops;
+}
+
+void BColorStops::doApplySteps(sal_uInt16 nStepCount)
+{
+ // check for zero or invalid steps setting -> done
+ if (0 == nStepCount || nStepCount > 100)
+ return;
+
+ // no change needed if single color
+ BColor aSingleColor;
+ if (isSingleColor(aSingleColor))
+ return;
+
+ // prepare new color stops, get L/R iterators for segments
+ basegfx::BColorStops aNewColorStops;
+ basegfx::BColorStops::const_iterator aColorR(begin());
+ basegfx::BColorStops::const_iterator aColorL(aColorR++);
+
+ while (aColorR != end())
+ {
+ // get start/end color for segment
+ const double fStart(aColorL->getStopOffset());
+ const double fDelta(aColorR->getStopOffset() - fStart);
+
+ if (aNewColorStops.empty() || aNewColorStops.back() != *aColorL)
+ {
+ // add start color, but check if it is already there - which is the
+ // case from the 2nd segment on due to a new segment starting with
+ // the same color as the previous one ended
+ aNewColorStops.push_back(*aColorL);
+ }
+ if (!basegfx::fTools::equalZero(fDelta))
+ {
+ // create in-between steps, always two at the same position to
+ // define a 'hard' color stop. Get start/end color for the segment
+ const basegfx::BColor& rStartColor(aColorL->getStopColor());
+ const basegfx::BColor& rEndColor(aColorR->getStopColor());
+
+ if (rStartColor != rEndColor)
+ {
+ // get relative single-step width
+ // tdf155852 Use same method for the color as in rendering.
+ const double fSingleStep(1.0 / static_cast<double>(nStepCount - 1));
+ const double fOffsetStep(fDelta / static_cast<double>(nStepCount));
+
+ for (sal_uInt16 a(1); a < nStepCount; a++)
+ {
+ // calculate stop position since being used twice
+ const double fPosition(fStart + fOffsetStep * static_cast<double>(a));
+
+ // add end color of previous sub-segment
+ aNewColorStops.emplace_back(
+ fPosition, basegfx::interpolate(rStartColor, rEndColor,
+ static_cast<double>(a - 1) * fSingleStep));
+
+ // add start color of current sub-segment
+ aNewColorStops.emplace_back(
+ fPosition, basegfx::interpolate(rStartColor, rEndColor,
+ static_cast<double>(a) * fSingleStep));
+ }
+ }
+ }
+
+ // always add end color of segment
+ aNewColorStops.push_back(*aColorR);
+
+ // next segment
+ aColorL++;
+ aColorR++;
+ }
+
+ // apply the change to color stops
+ *this = aNewColorStops;
+}
+
+std::string BGradient::GradientStyleToString(css::awt::GradientStyle eStyle)
+{
+ switch (eStyle)
+ {
+ case css::awt::GradientStyle::GradientStyle_LINEAR:
+ return "LINEAR";
+
+ case css::awt::GradientStyle::GradientStyle_AXIAL:
+ return "AXIAL";
+
+ case css::awt::GradientStyle::GradientStyle_RADIAL:
+ return "RADIAL";
+
+ case css::awt::GradientStyle::GradientStyle_ELLIPTICAL:
+ return "ELLIPTICAL";
+
+ case css::awt::GradientStyle::GradientStyle_SQUARE:
+ return "SQUARE";
+
+ case css::awt::GradientStyle::GradientStyle_RECT:
+ return "RECT";
+
+ case css::awt::GradientStyle::GradientStyle_MAKE_FIXED_SIZE:
+ return "MAKE_FIXED_SIZE";
+ }
+
+ return "";
+}
+
+BGradient BGradient::fromJSON(std::u16string_view rJSON)
+{
+ StringMap aMap(lcl_jsonToStringMap(rJSON));
+ return lcl_buildGradientFromStringMap(aMap);
+}
+
+BGradient::BGradient()
+ : eStyle(css::awt::GradientStyle_LINEAR)
+ , aColorStops()
+ , nAngle(0)
+ , nBorder(0)
+ , nOfsX(50)
+ , nOfsY(50)
+ , nIntensStart(100)
+ , nIntensEnd(100)
+ , nStepCount(0)
+{
+ aColorStops.emplace_back(0.0, BColor(0.0, 0.0, 0.0)); // COL_BLACK
+ aColorStops.emplace_back(1.0, BColor(1.0, 1.0, 1.0)); // COL_WHITE
+}
+
+BGradient::BGradient(const basegfx::BColorStops& rColorStops, css::awt::GradientStyle eTheStyle,
+ Degree10 nTheAngle, sal_uInt16 nXOfs, sal_uInt16 nYOfs, sal_uInt16 nTheBorder,
+ sal_uInt16 nStartIntens, sal_uInt16 nEndIntens, sal_uInt16 nSteps)
+ : eStyle(eTheStyle)
+ , aColorStops(rColorStops)
+ , nAngle(nTheAngle)
+ , nBorder(nTheBorder)
+ , nOfsX(nXOfs)
+ , nOfsY(nYOfs)
+ , nIntensStart(nStartIntens)
+ , nIntensEnd(nEndIntens)
+ , nStepCount(nSteps)
+{
+ SetColorStops(aColorStops);
+}
+
+bool BGradient::operator==(const BGradient& rGradient) const
+{
+ return (eStyle == rGradient.eStyle && aColorStops == rGradient.aColorStops
+ && nAngle == rGradient.nAngle && nBorder == rGradient.nBorder
+ && nOfsX == rGradient.nOfsX && nOfsY == rGradient.nOfsY
+ && nIntensStart == rGradient.nIntensStart && nIntensEnd == rGradient.nIntensEnd
+ && nStepCount == rGradient.nStepCount);
+}
+
+void BGradient::SetColorStops(const basegfx::BColorStops& rSteps)
+{
+ aColorStops = rSteps;
+ aColorStops.sortAndCorrect();
+ if (aColorStops.empty())
+ aColorStops.emplace_back(0.0, basegfx::BColor());
+}
+
+namespace
+{
+OUString AsRGBHexString(const ColorToBColorConverter& rVal)
+{
+ std::stringstream ss;
+ ss << std::hex << std::setfill('0') << std::setw(6) << sal_uInt32(rVal);
+ return OUString::createFromAscii(ss.str());
+}
+}
+
+boost::property_tree::ptree BGradient::dumpAsJSON() const
+{
+ boost::property_tree::ptree aTree;
+
+ aTree.put("style", BGradient::GradientStyleToString(eStyle));
+ const ColorToBColorConverter aStart(GetColorStops().front().getStopColor());
+ aTree.put("startcolor", AsRGBHexString(aStart.GetRGBColor()));
+ const ColorToBColorConverter aEnd(GetColorStops().back().getStopColor());
+ aTree.put("endcolor", AsRGBHexString(aEnd.GetRGBColor()));
+ aTree.put("angle", std::to_string(nAngle.get()));
+ aTree.put("border", std::to_string(nBorder));
+ aTree.put("x", std::to_string(nOfsX));
+ aTree.put("y", std::to_string(nOfsY));
+ aTree.put("intensstart", std::to_string(nIntensStart));
+ aTree.put("intensend", std::to_string(nIntensEnd));
+ aTree.put("stepcount", std::to_string(nStepCount));
+
+ return aTree;
+}
+
+void BGradient::tryToRecreateBorder(basegfx::BColorStops* pAssociatedTransparencyStops)
+{
+ // border already set, do not try to recreate
+ if (0 != GetBorder())
+ return;
+
+ BColor aSingleColor;
+ const bool bSingleColor(GetColorStops().isSingleColor(aSingleColor));
+
+ // no need to recreate with single color
+ if (bSingleColor)
+ return;
+
+ const bool bIsAxial(css::awt::GradientStyle_AXIAL == GetGradientStyle());
+
+ if (bIsAxial)
+ {
+ // for axial due to reverse used gradient work reversed
+ aColorStops.reverseColorStops();
+ if (nullptr != pAssociatedTransparencyStops)
+ pAssociatedTransparencyStops->reverseColorStops();
+ }
+
+ // check if we have space at start of range [0.0 .. 1.0] that
+ // may be interpreted as 'border' -> same color. That may involve
+ // different scenarios, e.g. 1st index > 0.0, but also a non-zero
+ // number of same color entries, or a combination of both
+ const double fOffset(aColorStops.detectPossibleOffsetAtStart());
+
+ if (!basegfx::fTools::equalZero(fOffset))
+ {
+ // we have a border area, indeed re-create
+ aColorStops.removeSpaceAtStart(fOffset);
+ if (nullptr != pAssociatedTransparencyStops)
+ pAssociatedTransparencyStops->removeSpaceAtStart(fOffset);
+
+ // ...and create border value
+ SetBorder(static_cast<sal_uInt16>(std::lround(fOffset * 100.0)));
+ }
+
+ if (bIsAxial)
+ {
+ // take back reverse
+ aColorStops.reverseColorStops();
+ if (nullptr != pAssociatedTransparencyStops)
+ pAssociatedTransparencyStops->reverseColorStops();
+ }
+}
+
+void BGradient::tryToApplyBorder()
+{
+ // no border to apply, done
+ if (0 == GetBorder())
+ return;
+
+ // NOTE: no new start node is added. The new ColorStop
+ // mechanism does not need entries at 0.0 and 1.0.
+ // In case this is needed, do that in the caller
+ const double fOffset(GetBorder() * 0.01);
+
+ if (css::awt::GradientStyle_AXIAL == GetGradientStyle())
+ {
+ // for axial due to reverse used gradient work reversed
+ aColorStops.reverseColorStops();
+ aColorStops.createSpaceAtStart(fOffset);
+ aColorStops.reverseColorStops();
+ }
+ else
+ {
+ // apply border to GradientStops
+ aColorStops.createSpaceAtStart(fOffset);
+ }
+
+ // set changed values
+ SetBorder(0);
+}
+
+void BGradient::tryToApplyStartEndIntensity()
+{
+ // already on default, nothing to apply
+ if (100 == GetStartIntens() && 100 == GetEndIntens())
+ return;
+
+ // apply 'old' blend stuff, blend against black
+ aColorStops.blendToIntensity(GetStartIntens() * 0.01, GetEndIntens() * 0.01,
+ BColor()); // COL_BLACK
+
+ // set values to default
+ SetStartIntens(100);
+ SetEndIntens(100);
+}
+
+void BGradient::tryToConvertToAxial()
+{
+ if (css::awt::GradientStyle_LINEAR != GetGradientStyle() || 0 != GetBorder()
+ || GetColorStops().empty())
+ return;
+
+ if (!GetColorStops().isSymmetrical())
+ return;
+
+ SetGradientStyle(css::awt::GradientStyle_AXIAL);
+
+ // Stretch the first half of the color stops to double width
+ // and collect them in a new color stops vector.
+ BColorStops aAxialColorStops;
+ aAxialColorStops.reserve(std::ceil(GetColorStops().size() / 2.0));
+ BColorStops::const_iterator aIter(GetColorStops().begin());
+ while (basegfx::fTools::lessOrEqual(aIter->getStopOffset(), 0.5))
+ {
+ BColorStop aNextStop(std::clamp((*aIter).getStopOffset() * 2.0, 0.0, 1.0),
+ (*aIter).getStopColor());
+ aAxialColorStops.push_back(aNextStop);
+ ++aIter;
+ }
+ // Axial gradients have outmost color as last color stop.
+ aAxialColorStops.reverseColorStops();
+
+ SetColorStops(aAxialColorStops);
+}
+
+void BGradient::tryToApplyAxial()
+{
+ // only need to do something if css::awt::GradientStyle_AXIAL, else done
+ if (GetGradientStyle() != css::awt::GradientStyle_AXIAL)
+ return;
+
+ // apply the change to color stops
+ aColorStops.doApplyAxial();
+
+ // set style to GradientStyle_LINEAR
+ SetGradientStyle(css::awt::GradientStyle_LINEAR);
+}
+
+void BGradient::tryToApplySteps()
+{
+ // check for zero or invalid steps setting -> done
+ if (0 == GetSteps() || GetSteps() > 100)
+ return;
+
+ // do the action
+ aColorStops.doApplySteps(GetSteps());
+
+ // set value to default
+ SetSteps(0);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basegfx/source/tools/canvastools.cxx b/basegfx/source/tools/canvastools.cxx
index 11ebe70dec28..70f4787710ad 100644
--- a/basegfx/source/tools/canvastools.cxx
+++ b/basegfx/source/tools/canvastools.cxx
@@ -34,6 +34,8 @@
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/matrix/b3dhommatrix.hxx>
#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/vector/b2dsize.hxx>
+#include <basegfx/vector/b2ivector.hxx>
#include <basegfx/range/b3drange.hxx>
#include <basegfx/range/b2irange.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
@@ -373,10 +375,9 @@ namespace basegfx::unotools
return output;
}
- geometry::RealSize2D size2DFromB2DSize( const ::basegfx::B2DVector& rVec )
+ geometry::RealSize2D size2DFromB2DSize(const ::basegfx::B2DSize& rSize)
{
- return geometry::RealSize2D( rVec.getX(),
- rVec.getY() );
+ return geometry::RealSize2D(rSize.getWidth(), rSize.getHeight());
}
geometry::RealPoint2D point2DFromB2DPoint( const ::basegfx::B2DPoint& rPoint )
@@ -427,16 +428,15 @@ namespace basegfx::unotools
rRect.Z2);
}
- geometry::IntegerSize2D integerSize2DFromB2ISize( const ::basegfx::B2IVector& rSize )
+ geometry::IntegerSize2D integerSize2DFromB2ISize( const ::basegfx::B2ISize& rSize )
{
- return geometry::IntegerSize2D( rSize.getX(),
- rSize.getY() );
+ return geometry::IntegerSize2D( rSize.getWidth(),
+ rSize.getHeight() );
}
- ::basegfx::B2IVector b2ISizeFromIntegerSize2D( const geometry::IntegerSize2D& rSize )
+ basegfx::B2ISize b2ISizeFromIntegerSize2D( const geometry::IntegerSize2D& rSize )
{
- return ::basegfx::B2IVector( rSize.Width,
- rSize.Height );
+ return basegfx::B2ISize(rSize.Width, rSize.Height);
}
::basegfx::B2IRange b2IRectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D& rRectangle )
diff --git a/basegfx/source/tools/gradienttools.cxx b/basegfx/source/tools/gradienttools.cxx
index 3605d8fe0be0..8f3e8ae83c06 100644
--- a/basegfx/source/tools/gradienttools.cxx
+++ b/basegfx/source/tools/gradienttools.cxx
@@ -21,6 +21,11 @@
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <com/sun/star/awt/Gradient2.hpp>
+#include <osl/endian.h>
+
+#include <algorithm>
+#include <cmath>
namespace basegfx
{
@@ -28,7 +33,7 @@ namespace basegfx
{
return getTextureTransform() == rODFGradientInfo.getTextureTransform()
&& getAspectRatio() == rODFGradientInfo.getAspectRatio()
- && getSteps() == rODFGradientInfo.getSteps();
+ && getRequestedSteps() == rODFGradientInfo.getRequestedSteps();
}
const B2DHomMatrix& ODFGradientInfo::getBackTextureTransform() const
@@ -135,7 +140,7 @@ namespace basegfx
// add object expansion
if(bCircular)
{
- const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY)));
+ const double fOriginalDiag(std::hypot(fTargetSizeX, fTargetSizeY));
fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0;
fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0;
@@ -144,10 +149,10 @@ namespace basegfx
}
else
{
- fTargetOffsetX -= (0.4142 / 2.0 ) * fTargetSizeX;
- fTargetOffsetY -= (0.4142 / 2.0 ) * fTargetSizeY;
- fTargetSizeX = 1.4142 * fTargetSizeX;
- fTargetSizeY = 1.4142 * fTargetSizeY;
+ fTargetOffsetX -= ((M_SQRT2 - 1) / 2.0 ) * fTargetSizeX;
+ fTargetOffsetY -= ((M_SQRT2 - 1) / 2.0 ) * fTargetSizeY;
+ fTargetSizeX = M_SQRT2 * fTargetSizeX;
+ fTargetSizeY = M_SQRT2 * fTargetSizeY;
}
const double fHalfBorder((1.0 - fBorder) * 0.5);
@@ -260,6 +265,233 @@ namespace basegfx
namespace utils
{
+ /* Tooling method to extract data from given BGradient
+ to ColorStops, doing some corrections, partially based
+ on given SingleColor */
+ void prepareColorStops(
+ const basegfx::BGradient& rGradient,
+ BColorStops& rColorStops,
+ BColor& rSingleColor)
+ {
+ if (rGradient.GetColorStops().isSingleColor(rSingleColor))
+ {
+ // when single color, preserve value in rSingleColor
+ // and clear the ColorStops, done.
+ rColorStops.clear();
+ return;
+ }
+
+ const bool bAdaptStartEndIntensity(100 != rGradient.GetStartIntens() || 100 != rGradient.GetEndIntens());
+ const bool bAdaptBorder(0 != rGradient.GetBorder());
+
+ if (!bAdaptStartEndIntensity && !bAdaptBorder)
+ {
+ // copy unchanged ColorStops & done
+ rColorStops = rGradient.GetColorStops();
+ return;
+ }
+
+ // prepare a copy to work on
+ basegfx::BGradient aWorkCopy(rGradient);
+
+ if (bAdaptStartEndIntensity)
+ {
+ aWorkCopy.tryToApplyStartEndIntensity();
+
+ // this can again lead to single color (e.g. both zero, so
+ // all black), so check again for it
+ if (aWorkCopy.GetColorStops().isSingleColor(rSingleColor))
+ {
+ rColorStops.clear();
+ return;
+ }
+ }
+
+ if (bAdaptBorder)
+ {
+ aWorkCopy.tryToApplyBorder();
+ }
+
+ // extract ColorStops, that's all we need here
+ rColorStops = aWorkCopy.GetColorStops();
+ }
+
+ /* Tooling method to synchronize the given ColorStops.
+ The intention is that a color GradientStops and an
+ alpha/transparence GradientStops gets synchronized
+ for export. */
+ void synchronizeColorStops(
+ BColorStops& rColorStops,
+ BColorStops& rAlphaStops,
+ const BColor& rSingleColor,
+ const BColor& rSingleAlpha)
+ {
+ if (rColorStops.empty())
+ {
+ if (rAlphaStops.empty())
+ {
+ // no AlphaStops and no ColorStops
+ // create two-stop fallbacks for both
+ rColorStops = BColorStops {
+ BColorStop(0.0, rSingleColor),
+ BColorStop(1.0, rSingleColor) };
+ rAlphaStops = BColorStops {
+ BColorStop(0.0, rSingleAlpha),
+ BColorStop(1.0, rSingleAlpha) };
+ }
+ else
+ {
+ // AlphaStops but no ColorStops
+ // create fallback synched with existing AlphaStops
+ for (const auto& cand : rAlphaStops)
+ {
+ rColorStops.emplace_back(cand.getStopOffset(), rSingleColor);
+ }
+ }
+
+ // preparations complete, we are done
+ return;
+ }
+ else if (rAlphaStops.empty())
+ {
+ // ColorStops but no AlphaStops
+ // create fallback AlphaStops synched with existing ColorStops using SingleAlpha
+ for (const auto& cand : rColorStops)
+ {
+ rAlphaStops.emplace_back(cand.getStopOffset(), rSingleAlpha);
+ }
+
+ // preparations complete, we are done
+ return;
+ }
+
+ // here we have ColorStops and AlphaStops not empty. Check if we need to
+ // synchronize both or if they are already usable/in a synched state so
+ // that they have same count and same StopOffsets
+ bool bNeedToSyncronize(rColorStops.size() != rAlphaStops.size());
+
+ if (!bNeedToSyncronize)
+ {
+ // check for same StopOffsets
+ BColorStops::const_iterator aCurrColor(rColorStops.begin());
+ BColorStops::const_iterator aCurrAlpha(rAlphaStops.begin());
+
+ while (!bNeedToSyncronize &&
+ aCurrColor != rColorStops.end() &&
+ aCurrAlpha != rAlphaStops.end())
+ {
+ if (fTools::equal(aCurrColor->getStopOffset(), aCurrAlpha->getStopOffset()))
+ {
+ aCurrColor++;
+ aCurrAlpha++;
+ }
+ else
+ {
+ bNeedToSyncronize = true;
+ }
+ }
+ }
+
+ if (bNeedToSyncronize)
+ {
+ // synchronize sizes & StopOffsets
+ BColorStops::const_iterator aCurrColor(rColorStops.begin());
+ BColorStops::const_iterator aCurrAlpha(rAlphaStops.begin());
+ BColorStops aNewColor;
+ BColorStops aNewAlpha;
+ BColorStops::BColorStopRange aColorStopRange;
+ BColorStops::BColorStopRange aAlphaStopRange;
+ bool bRealChange(false);
+
+ do {
+ const bool bColor(aCurrColor != rColorStops.end());
+ const bool bAlpha(aCurrAlpha != rAlphaStops.end());
+
+ if (bColor && bAlpha)
+ {
+ const double fColorOff(aCurrColor->getStopOffset());
+ const double fAlphaOff(aCurrAlpha->getStopOffset());
+
+ if (fTools::less(fColorOff, fAlphaOff))
+ {
+ // copy color, create alpha
+ aNewColor.emplace_back(fColorOff, aCurrColor->getStopColor());
+ aNewAlpha.emplace_back(fColorOff, rAlphaStops.getInterpolatedBColor(fColorOff, 0, aAlphaStopRange));
+ bRealChange = true;
+ aCurrColor++;
+ }
+ else if (fTools::more(fColorOff, fAlphaOff))
+ {
+ // copy alpha, create color
+ aNewColor.emplace_back(fAlphaOff, rColorStops.getInterpolatedBColor(fAlphaOff, 0, aColorStopRange));
+ aNewAlpha.emplace_back(fAlphaOff, aCurrAlpha->getStopColor());
+ bRealChange = true;
+ aCurrAlpha++;
+ }
+ else
+ {
+ // equal: copy both, advance
+ aNewColor.emplace_back(fColorOff, aCurrColor->getStopColor());
+ aNewAlpha.emplace_back(fAlphaOff, aCurrAlpha->getStopColor());
+ aCurrColor++;
+ aCurrAlpha++;
+ }
+ }
+ else if (bColor)
+ {
+ const double fColorOff(aCurrColor->getStopOffset());
+ aNewAlpha.emplace_back(fColorOff, rAlphaStops.getInterpolatedBColor(fColorOff, 0, aAlphaStopRange));
+ aNewColor.emplace_back(fColorOff, aCurrColor->getStopColor());
+ bRealChange = true;
+ aCurrColor++;
+ }
+ else if (bAlpha)
+ {
+ const double fAlphaOff(aCurrAlpha->getStopOffset());
+ aNewColor.emplace_back(fAlphaOff, rColorStops.getInterpolatedBColor(fAlphaOff, 0, aColorStopRange));
+ aNewAlpha.emplace_back(fAlphaOff, aCurrAlpha->getStopColor());
+ bRealChange = true;
+ aCurrAlpha++;
+ }
+ else
+ {
+ // no more input, break do..while loop
+ break;
+ }
+ }
+ while(true);
+
+ if (bRealChange)
+ {
+ // copy on 'real' change, that means data was added.
+ // This should always be the cease and should have been
+ // detected as such above, see bNeedToSyncronize
+ rColorStops = aNewColor;
+ rAlphaStops = aNewAlpha; // MCGR: tdf#155537 used wrong result here
+ }
+ }
+ }
+
+ sal_uInt32 calculateNumberOfSteps(
+ sal_uInt32 nRequestedSteps,
+ const BColor& rStart,
+ const BColor& rEnd)
+ {
+ const sal_uInt32 nMaxSteps(sal_uInt32((rStart.getMaximumDistance(rEnd) * 127.5) + 0.5));
+
+ if (0 == nRequestedSteps)
+ {
+ nRequestedSteps = nMaxSteps;
+ }
+
+ if(nRequestedSteps > nMaxSteps)
+ {
+ nRequestedSteps = nMaxSteps;
+ }
+
+ return std::max(sal_uInt32(1), nRequestedSteps);
+ }
+
ODFGradientInfo createLinearODFGradientInfo(
const B2DRange& rTargetArea,
sal_uInt32 nSteps,
@@ -355,7 +587,7 @@ namespace basegfx
{
const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
- // Ignore Y, this is not needed at all for Y-Oriented gradients
+ // Ignore X, this is not needed at all for Y-Oriented gradients
// if(aCoor.getX() < 0.0 || aCoor.getX() > 1.0)
// {
// return 0.0;
@@ -371,13 +603,6 @@ namespace basegfx
return 1.0; // end value for outside
}
- const sal_uInt32 nSteps(rGradInfo.getSteps());
-
- if(nSteps)
- {
- return floor(aCoor.getY() * nSteps) / double(nSteps - 1);
- }
-
return aCoor.getY();
}
@@ -385,7 +610,7 @@ namespace basegfx
{
const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
- // Ignore Y, this is not needed at all for Y-Oriented gradients
+ // Ignore X, this is not needed at all for Y-Oriented gradients
//if(aCoor.getX() < 0.0 || aCoor.getX() > 1.0)
//{
// return 0.0;
@@ -398,17 +623,22 @@ namespace basegfx
return 1.0; // use end value when outside in Y
}
- const sal_uInt32 nSteps(rGradInfo.getSteps());
+ return fAbsY;
+ }
- if(nSteps)
+ double getRadialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+ {
+ const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
+
+ if(aCoor.getX() < -1.0 || aCoor.getX() > 1.0 || aCoor.getY() < -1.0 || aCoor.getY() > 1.0)
{
- return floor(fAbsY * nSteps) / double(nSteps - 1);
+ return 0.0;
}
- return fAbsY;
+ return 1.0 - std::hypot(aCoor.getX(), aCoor.getY());
}
- double getRadialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+ double getEllipticalGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
{
const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
@@ -417,22 +647,26 @@ namespace basegfx
return 0.0;
}
- const double t(1.0 - sqrt(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY()));
- const sal_uInt32 nSteps(rGradInfo.getSteps());
+ double fAspectRatio(rGradInfo.getAspectRatio());
+ double t(1.0);
- if(nSteps && t < 1.0)
+ // MCGR: Similar to getRectangularGradientAlpha (please
+ // see there) we need to use aspect ratio here. Due to
+ // initEllipticalGradientInfo using M_SQRT2 to make this
+ // gradient look 'nicer' this correction seems not 100%
+ // correct, but is close enough for now
+ if(fAspectRatio > 1.0)
+ {
+ t = 1.0 - std::hypot(aCoor.getX() / fAspectRatio, aCoor.getY());
+ }
+ else if(fAspectRatio > 0.0)
{
- return floor(t * nSteps) / double(nSteps - 1);
+ t = 1.0 - std::hypot(aCoor.getX(), aCoor.getY() * fAspectRatio);
}
return t;
}
- double getEllipticalGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
- {
- return getRadialGradientAlpha(rUV, rGradInfo); // only matrix setup differs
- }
-
double getSquareGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
{
const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
@@ -450,20 +684,71 @@ namespace basegfx
return 0.0;
}
- const double t(1.0 - std::max(fAbsX, fAbsY));
- const sal_uInt32 nSteps(rGradInfo.getSteps());
+ return 1.0 - std::max(fAbsX, fAbsY);
+ }
+
+ double getRectangularGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+ {
+ const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
+ double fAbsX(fabs(aCoor.getX()));
- if(nSteps && t < 1.0)
+ if(fAbsX >= 1.0)
{
- return floor(t * nSteps) / double(nSteps - 1);
+ return 0.0;
}
- return t;
- }
+ double fAbsY(fabs(aCoor.getY()));
- double getRectangularGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
- {
- return getSquareGradientAlpha(rUV, rGradInfo); // only matrix setup differs
+ if(fAbsY >= 1.0)
+ {
+ return 0.0;
+ }
+
+ // MCGR: Visualizations using the texturing method for
+ // displaying gradients (getBackTextureTransform is
+ // involved) show wrong results for GradientElliptical
+ // and GradientRect, this can be best seen when using
+ // less steps, e.g. just four. This thus has influence
+ // on cppcanvas (slideshow) and 3D textures, so needs
+ // to be corrected.
+ // Missing is to use the aspect ratio of the object
+ // in this [-1, -1, 1, 1] unified coordinate space
+ // after getBackTextureTransform is applied. Optically
+ // in the larger direction of the texturing the color
+ // step distances are too big *because* we are in that
+ // unit range now.
+ // To correct that, a kind of 'limo stretching' needs to
+ // be applied, adding space around the center
+ // proportional to the aspect ratio, so the intuitive
+ // idea would be to do
+ //
+ // fAbsX' = ((fAspectRatio - 1) + fAbsX) / fAspectRatio
+ //
+ // which scales from the center. This does not work, and
+ // after some thoughts it's clear why: It's not the
+ // position that needs to be moved (this cannot be
+ // changed), but the position *before* that scale has
+ // to be determined to get the correct, shifted color
+ // for the already 'new' position. Thus, turn around
+ // the expression as
+ //
+ // fAbsX' * fAspectRatio = fAspectRatio - 1 + fAbsX
+ // fAbsX' * fAspectRatio - fAspectRatio + 1 = fAbsX
+ // fAbsX = (fAbsX' - 1) * fAspectRatio + 1
+ //
+ // This works and can even be simply adapted for
+ // fAspectRatio < 1.0 aka vertical is bigger.
+ double fAspectRatio(rGradInfo.getAspectRatio());
+ if(fAspectRatio > 1.0)
+ {
+ fAbsX = ((fAbsX - 1) * fAspectRatio) + 1;
+ }
+ else if(fAspectRatio > 0.0)
+ {
+ fAbsY = ((fAbsY - 1) / fAspectRatio) + 1;
+ }
+
+ return 1.0 - std::max(fAbsX, fAbsY);
}
} // namespace utils
} // namespace basegfx
diff --git a/basegfx/source/tools/stringconversiontools.cxx b/basegfx/source/tools/stringconversiontools.cxx
index d9f7df14cf50..79b6d604662e 100644
--- a/basegfx/source/tools/stringconversiontools.cxx
+++ b/basegfx/source/tools/stringconversiontools.cxx
@@ -46,70 +46,66 @@ namespace basegfx::internal
static bool getDoubleChar(double& o_fRetval,
sal_Int32& io_rPos,
- const OUString& rStr)
+ std::u16string_view rStr)
{
- sal_Unicode aChar = io_rPos < rStr.getLength() ? rStr[io_rPos] : 0;
- OUStringBuffer sNumberString;
+ const sal_Int64 nStrSize = rStr.size();
+ sal_Unicode aChar = io_rPos < nStrSize ? rStr[io_rPos] : 0;
+ const sal_Int32 nStartPos = io_rPos;
// sign
if(aChar == '+' || aChar == '-')
{
- sNumberString.append(rStr[io_rPos]);
aChar = rStr[++io_rPos];
}
// numbers before point
while('0' <= aChar && '9' >= aChar)
{
- sNumberString.append(rStr[io_rPos]);
io_rPos++;
- aChar = io_rPos < rStr.getLength() ? rStr[io_rPos] : 0;
+ aChar = io_rPos < nStrSize ? rStr[io_rPos] : 0;
}
// point
if(aChar == '.')
{
- sNumberString.append(rStr[io_rPos]);
io_rPos++;
- aChar = io_rPos < rStr.getLength() ? rStr[io_rPos] : 0;
+ aChar = io_rPos < nStrSize ? rStr[io_rPos] : 0;
}
// numbers after point
while ('0' <= aChar && '9' >= aChar)
{
- sNumberString.append(rStr[io_rPos]);
io_rPos++;
- aChar = io_rPos < rStr.getLength() ? rStr[io_rPos] : 0;
+ aChar = io_rPos < nStrSize ? rStr[io_rPos] : 0;
}
// 'e'
if(aChar == 'e' || aChar == 'E')
{
- sNumberString.append(rStr[io_rPos]);
io_rPos++;
- aChar = io_rPos < rStr.getLength() ? rStr[io_rPos] : 0;
+ aChar = io_rPos < nStrSize ? rStr[io_rPos] : 0;
// sign for 'e'
if(aChar == '+' || aChar == '-')
{
- sNumberString.append(rStr[io_rPos]);
io_rPos++;
- aChar = io_rPos < rStr.getLength() ? rStr[io_rPos] : 0;
+ aChar = io_rPos < nStrSize ? rStr[io_rPos] : 0;
}
// number for 'e'
while('0' <= aChar && '9' >= aChar)
{
- sNumberString.append(rStr[io_rPos]);
io_rPos++;
- aChar = io_rPos < rStr.getLength() ? rStr[io_rPos] : 0;
+ aChar = io_rPos < nStrSize ? rStr[io_rPos] : 0;
}
}
- if(sNumberString.getLength())
+ const sal_Int32 nLen = io_rPos - nStartPos;
+ if(nLen)
{
+ rStr = rStr.substr(nStartPos, nLen);
rtl_math_ConversionStatus eStatus;
- o_fRetval = ::rtl::math::stringToDouble( sNumberString.makeStringAndClear(),
+ o_fRetval = ::rtl::math::stringToDouble( rStr,
'.',
',',
&eStatus );
@@ -121,7 +117,7 @@ namespace basegfx::internal
bool importDoubleAndSpaces(double& o_fRetval,
sal_Int32& io_rPos,
- const OUString& rStr,
+ std::u16string_view rStr,
const sal_Int32 nLen )
{
if( !getDoubleChar(o_fRetval, io_rPos, rStr) )
diff --git a/basegfx/source/tools/systemdependentdata.cxx b/basegfx/source/tools/systemdependentdata.cxx
index 106124f57389..0d64d9982cef 100644
--- a/basegfx/source/tools/systemdependentdata.cxx
+++ b/basegfx/source/tools/systemdependentdata.cxx
@@ -8,6 +8,7 @@
*/
#include <basegfx/utils/systemdependentdata.hxx>
+#include <config_fuzzers.h>
#include <math.h>
namespace basegfx
@@ -36,6 +37,10 @@ namespace basegfx
sal_uInt32 SystemDependentData::calculateCombinedHoldCyclesInSeconds() const
{
+#if ENABLE_FUZZERS
+ return 0;
+#endif
+
if(0 == mnCalculatedCycles)
{
const sal_Int64 nBytes(estimateUsageInBytes());
@@ -47,7 +52,8 @@ namespace basegfx
// For the future, a more sophisticated differentiation may be added
if(nBytes > 450)
{
- const sal_uInt32 nSeconds = 60; // HoldCyclesInSeconds
+ // HoldCyclesInSeconds
+ const sal_uInt32 nSeconds = 60;
// default is Seconds (minimal is one)
sal_uInt32 nResult(0 == nSeconds ? 1 : nSeconds);
diff --git a/basegfx/source/tools/unopolypolygon.cxx b/basegfx/source/tools/unopolypolygon.cxx
index 48b3372d5526..323e06a96f18 100644
--- a/basegfx/source/tools/unopolypolygon.cxx
+++ b/basegfx/source/tools/unopolypolygon.cxx
@@ -28,17 +28,16 @@
#include <basegfx/utils/unopolypolygon.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <utility>
using namespace ::com::sun::star;
namespace basegfx::unotools
{
- UnoPolyPolygon::UnoPolyPolygon( const B2DPolyPolygon& rPolyPoly ) :
- maPolyPoly( rPolyPoly ),
+ UnoPolyPolygon::UnoPolyPolygon( B2DPolyPolygon aPolyPoly ) :
+ maPolyPoly(std::move( aPolyPoly )),
meFillRule( rendering::FillRule_EVEN_ODD )
{
- // or else races will haunt us.
- maPolyPoly.makeUnique();
}
void SAL_CALL UnoPolyPolygon::addPolyPolygon(
@@ -98,7 +97,7 @@ namespace basegfx::unotools
throw lang::IllegalArgumentException(
"UnoPolyPolygon::addPolyPolygon(): Invalid input "
"poly-polygon, cannot retrieve vertex data",
- static_cast<cppu::OWeakObject*>(this), 1);
+ getXWeak(), 1);
aSrcPoly = unotools::polyPolygonFromPoint2DSequenceSequence(
xLinePoly->getPoints( 0,
@@ -229,7 +228,7 @@ namespace basegfx::unotools
const B2DPolygon& rPoly( maPolyPoly.getB2DPolygon( nPolygonIndex ) );
- if( nPointIndex < 0 || nPointIndex >= static_cast<sal_Int32>(rPoly.count()) )
+ if( nPointIndex < 0 || o3tl::make_unsigned(nPointIndex) >= rPoly.count() )
throw lang::IndexOutOfBoundsException();
return unotools::point2DFromB2DPoint( rPoly.getB2DPoint( nPointIndex ) );
@@ -246,7 +245,7 @@ namespace basegfx::unotools
B2DPolygon aPoly( maPolyPoly.getB2DPolygon( nPolygonIndex ) );
- if( nPointIndex < 0 || nPointIndex >= static_cast<sal_Int32>(aPoly.count()) )
+ if( nPointIndex < 0 || o3tl::make_unsigned(nPointIndex) >= aPoly.count() )
throw lang::IndexOutOfBoundsException();
aPoly.setB2DPoint( nPointIndex,
@@ -297,7 +296,7 @@ namespace basegfx::unotools
const B2DPolygon& rPoly( maPolyPoly.getB2DPolygon( nPolygonIndex ) );
const sal_uInt32 nPointCount(rPoly.count());
- if( nPointIndex < 0 || nPointIndex >= static_cast<sal_Int32>(nPointCount) )
+ if( nPointIndex < 0 || o3tl::make_unsigned(nPointIndex) >= nPointCount )
throw lang::IndexOutOfBoundsException();
const B2DPoint& rPt( rPoly.getB2DPoint( nPointIndex ) );
@@ -323,7 +322,7 @@ namespace basegfx::unotools
B2DPolygon aPoly( maPolyPoly.getB2DPolygon( nPolygonIndex ) );
const sal_uInt32 nPointCount(aPoly.count());
- if( nPointIndex < 0 || nPointIndex >= static_cast<sal_Int32>(nPointCount) )
+ if( nPointIndex < 0 || o3tl::make_unsigned(nPointIndex) >= nPointCount )
throw lang::IndexOutOfBoundsException();
aPoly.setB2DPoint( nPointIndex,
@@ -422,7 +421,7 @@ namespace basegfx::unotools
OUString SAL_CALL UnoPolyPolygon::getImplementationName()
{
- return "gfx::internal::UnoPolyPolygon";
+ return u"gfx::internal::UnoPolyPolygon"_ustr;
}
sal_Bool SAL_CALL UnoPolyPolygon::supportsService( const OUString& ServiceName )
@@ -432,17 +431,14 @@ namespace basegfx::unotools
uno::Sequence< OUString > SAL_CALL UnoPolyPolygon::getSupportedServiceNames()
{
- return { "com.sun.star.rendering.PolyPolygon2D" };
+ return { u"com.sun.star.rendering.PolyPolygon2D"_ustr };
}
B2DPolyPolygon UnoPolyPolygon::getPolyPolygon() const
{
std::unique_lock const guard( m_aMutex );
- // detach result from us
- B2DPolyPolygon aRet( maPolyPoly );
- aRet.makeUnique();
- return aRet;
+ return maPolyPoly;
}
}
diff --git a/basegfx/source/tools/zoomtools.cxx b/basegfx/source/tools/zoomtools.cxx
index 4fedb8ee848c..dd4c7a6cbbd3 100644
--- a/basegfx/source/tools/zoomtools.cxx
+++ b/basegfx/source/tools/zoomtools.cxx
@@ -26,7 +26,7 @@ const double ZOOM_FACTOR = 1.12246205;
* @param nCurrent current value
* @param nMultiple multiple against which the current value is rounded
*/
-static tools::Long roundMultiple(tools::Long nCurrent, int nMultiple)
+static sal_uInt16 roundMultiple(sal_uInt16 nCurrent, int nMultiple)
{
// round zoom to a multiple of nMultiple
return (( nCurrent + nMultiple / 2 ) - ( nCurrent + nMultiple / 2 ) % nMultiple);
@@ -39,10 +39,10 @@ static tools::Long roundMultiple(tools::Long nCurrent, int nMultiple)
*
* @param nCurrent current zoom factor
*/
-static tools::Long roundZoom(double nCurrent)
+static sal_uInt16 roundZoom(double nCurrent)
{
// convert nCurrent properly to int
- tools::Long nNew = nCurrent + 0.5;
+ sal_uInt16 nNew = nCurrent + 0.5;
// round to more common numbers above 50
if (nNew > 1000) {
@@ -66,7 +66,7 @@ static tools::Long roundZoom(double nCurrent)
* @param nPrevious previous zoom factor
* @param nStep step which shouldn't be skipped
*/
-static tools::Long enforceStep(tools::Long nCurrent, tools::Long nPrevious, int nStep)
+static sal_uInt16 enforceStep(sal_uInt16 nCurrent, sal_uInt16 nPrevious, unsigned int nStep)
{
if ((( nCurrent > nStep ) && ( nPrevious < nStep ))
|| (( nCurrent < nStep ) && ( nPrevious > nStep )))
@@ -80,9 +80,9 @@ static tools::Long enforceStep(tools::Long nCurrent, tools::Long nPrevious, int
*
* @param nCurrent current zoom factor
*/
-tools::Long zoomIn(tools::Long nCurrent)
+sal_uInt16 zoomIn(sal_uInt16 nCurrent)
{
- tools::Long nNew = roundZoom( nCurrent * ZOOM_FACTOR );
+ sal_uInt16 nNew = roundZoom( nCurrent * ZOOM_FACTOR );
// make sure some values are not skipped
nNew = enforceStep(nNew, nCurrent, 200);
nNew = enforceStep(nNew, nCurrent, 100);
@@ -97,9 +97,9 @@ tools::Long zoomIn(tools::Long nCurrent)
*
* @param nCurrent current zoom factor
*/
-tools::Long zoomOut(tools::Long nCurrent)
+sal_uInt16 zoomOut(sal_uInt16 nCurrent)
{
- tools::Long nNew = roundZoom( nCurrent / ZOOM_FACTOR );
+ sal_uInt16 nNew = roundZoom( nCurrent / ZOOM_FACTOR );
// make sure some values are not skipped
nNew = enforceStep(nNew, nCurrent, 200);
nNew = enforceStep(nNew, nCurrent, 100);
diff --git a/basegfx/source/vector/b2dvector.cxx b/basegfx/source/vector/b2dvector.cxx
index 1ad51a9b5a4c..1f696237fecf 100644
--- a/basegfx/source/vector/b2dvector.cxx
+++ b/basegfx/source/vector/b2dvector.cxx
@@ -25,57 +25,45 @@ namespace basegfx
{
B2DVector& B2DVector::normalize()
{
- double fLen(scalar(*this));
+ double fLen(std::hypot(mnX, mnY));
- if(fTools::equalZero(fLen))
- {
- mfX = 0.0;
- mfY = 0.0;
- }
- else
+ if(!fTools::equalZero(fLen))
{
const double fOne(1.0);
if(!fTools::equal(fOne, fLen))
{
- fLen = sqrt(fLen);
-
- if(!fTools::equalZero(fLen))
- {
- mfX /= fLen;
- mfY /= fLen;
- }
+ mnX /= fLen;
+ mnY /= fLen;
}
}
+ else
+ {
+ mnX = 0.0;
+ mnY = 0.0;
+ }
return *this;
}
- B2DVector& B2DVector::operator=( const B2DTuple& rVec )
- {
- mfX = rVec.getX();
- mfY = rVec.getY();
- return *this;
- }
-
double B2DVector::getLength() const
{
- if(fTools::equalZero(mfX))
+ if(fTools::equalZero(mnX))
{
- return fabs(mfY);
+ return fabs(mnY);
}
- else if(fTools::equalZero(mfY))
+ else if(fTools::equalZero(mnY))
{
- return fabs(mfX);
+ return fabs(mnX);
}
- return hypot( mfX, mfY );
+ return hypot( mnX, mnY );
}
double B2DVector::angle( const B2DVector& rVec ) const
{
- return atan2(mfX * rVec.getY() - mfY * rVec.getX(),
- mfX * rVec.getX() + mfY * rVec.getY());
+ return atan2(mnX * rVec.getY() - mnY * rVec.getX(),
+ mnX * rVec.getX() + mnY * rVec.getY());
}
const B2DVector& B2DVector::getEmptyVector()
@@ -85,19 +73,19 @@ namespace basegfx
B2DVector& B2DVector::operator*=( const B2DHomMatrix& rMat )
{
- const double fTempX( rMat.get(0,0)*mfX +
- rMat.get(0,1)*mfY );
- const double fTempY( rMat.get(1,0)*mfX +
- rMat.get(1,1)*mfY );
- mfX = fTempX;
- mfY = fTempY;
+ const double fTempX( rMat.get(0,0)*mnX +
+ rMat.get(0,1)*mnY );
+ const double fTempY( rMat.get(1,0)*mnX +
+ rMat.get(1,1)*mnY );
+ mnX = fTempX;
+ mnY = fTempY;
return *this;
}
B2DVector& B2DVector::setLength(double fLen)
{
- double fLenNow(scalar(*this));
+ double fLenNow(std::hypot(mnX, mnY));
if(!fTools::equalZero(fLenNow))
{
@@ -105,11 +93,11 @@ namespace basegfx
if(!fTools::equal(fOne, fLenNow))
{
- fLen /= sqrt(fLenNow);
+ fLen /= fLenNow;
}
- mfX *= fLen;
- mfY *= fLen;
+ mnX *= fLen;
+ mnY *= fLen;
}
return *this;
diff --git a/basegfx/source/vector/b2ivector.cxx b/basegfx/source/vector/b2ivector.cxx
index 5b45871a39cf..6d618facf48f 100644
--- a/basegfx/source/vector/b2ivector.cxx
+++ b/basegfx/source/vector/b2ivector.cxx
@@ -42,7 +42,7 @@ namespace basegfx
B2IVector& B2IVector::setLength(double fLen)
{
- double fLenNow(scalar(*this));
+ double fLenNow(std::hypot(mnX, mnY));
if(!::basegfx::fTools::equalZero(fLenNow))
{
@@ -50,7 +50,7 @@ namespace basegfx
if(!::basegfx::fTools::equal(fOne, fLenNow))
{
- fLen /= sqrt(fLenNow);
+ fLen /= fLenNow;
}
mnX = fround( mnX*fLen );
diff --git a/basegfx/source/vector/b3dvector.cxx b/basegfx/source/vector/b3dvector.cxx
index 002ee330f9f4..68e3fcf205c4 100644
--- a/basegfx/source/vector/b3dvector.cxx
+++ b/basegfx/source/vector/b3dvector.cxx
@@ -24,7 +24,7 @@ namespace basegfx
{
B3DVector& B3DVector::normalize()
{
- double fLen(scalar(*this));
+ double fLen(std::hypot(mnX, mnY, mnZ));
if(!::basegfx::fTools::equalZero(fLen))
{
@@ -32,13 +32,17 @@ namespace basegfx
if(!::basegfx::fTools::equal(fOne, fLen))
{
- fLen = sqrt(fLen);
-
- mfX /= fLen;
- mfY /= fLen;
- mfZ /= fLen;
+ mnX /= fLen;
+ mnY /= fLen;
+ mnZ /= fLen;
}
}
+ else
+ {
+ mnX = 0.0;
+ mnY = 0.0;
+ mnZ = 0.0;
+ }
return *this;
}
@@ -52,12 +56,12 @@ namespace basegfx
B3DVector& B3DVector::operator*=( const ::basegfx::B3DHomMatrix& rMat )
{
- const double fTempX( rMat.get(0,0)*mfX + rMat.get(0,1)*mfY + rMat.get(0,2)*mfZ );
- const double fTempY( rMat.get(1,0)*mfX + rMat.get(1,1)*mfY + rMat.get(1,2)*mfZ );
- const double fTempZ( rMat.get(2,0)*mfX + rMat.get(2,1)*mfY + rMat.get(2,2)*mfZ );
- mfX = fTempX;
- mfY = fTempY;
- mfZ = fTempZ;
+ const double fTempX( rMat.get(0,0)*mnX + rMat.get(0,1)*mnY + rMat.get(0,2)*mnZ );
+ const double fTempY( rMat.get(1,0)*mnX + rMat.get(1,1)*mnY + rMat.get(1,2)*mnZ );
+ const double fTempZ( rMat.get(2,0)*mnX + rMat.get(2,1)*mnY + rMat.get(2,2)*mnZ );
+ mnX = fTempX;
+ mnY = fTempY;
+ mnZ = fTempZ;
return *this;
}
diff --git a/basegfx/source/workbench/Makefile b/basegfx/source/workbench/Makefile
index 21dfc1400d11..6218141da1c8 100644
--- a/basegfx/source/workbench/Makefile
+++ b/basegfx/source/workbench/Makefile
@@ -16,19 +16,8 @@
# the License at http://www.apache.org/licenses/LICENSE-2.0 .
#
-# Testbuild
-
-#test : bezierclip.cxx convexhull.cxx
-# g++ -Wall -g \
-# -I. -I. -I../inc -I./inc -I./unx/inc -I./unxlngi4/inc -I. -I/develop4/update/SRX644/unxlngi4/inc.m4/stl -I/develop4/update/SRX644/unxlngi4/inc.m4/external -I/develop4/update/SRX644/unxlngi4/inc.m4 -I/develop4/update/SRX644/src.m4/solenv/unxlngi4/inc -I/net/grande/develop6/update/dev/gcc_3.0.1_linux_libc2.11_turbolinux/include -I/develop4/update/SRX644/src.m4/solenv/inc -I/develop4/update/SRX644/unxlngi4/inc.m4/stl -I/net/grande.germany/develop6/update/dev/gcc_3.0.1_linux_libc2.11_turbolinux/redhat60/usr/include -I/net/grande.germany/develop6/update/dev/gcc_3.0.1_linux_libc2.11_turbolinux/redhat60/usr/include/X11 -I/develop4/update/SRX644/src.m4/res -I/net/grande/develop6/update/dev/Linux_JDK_1.4.0/include -I/net/grande/develop6/update/dev/Linux_JDK_1.4.0/include/linux -I. -I./res -I. \
-# -include preinclude.h -D_USE_NAMESPACE -DGLIBC=2 -D_USE_NAMESPACE=1 -D_DEBUG_RUNTIME \
-# bezierclip.cxx convexhull.cxx -o bezierclip
-
prog : bezierclip.cxx convexhull.cxx
- g++ -Wall -g bezierclip.cxx convexhull.cxx -o bezierclip
-
-test : testconvexhull.cxx
- g++ -Wall -g testconvexhull.cxx -o testhull
+ g++ -I. -Wall -g bezierclip.cxx convexhull.cxx -o bezierclip
.cxx.o:
g++ -c $(LOCALDEFINES) $(CCFLAGS) $<
diff --git a/basegfx/source/workbench/bezierclip.cxx b/basegfx/source/workbench/bezierclip.cxx
index 1f16ed37c05c..676f239efd10 100644
--- a/basegfx/source/workbench/bezierclip.cxx
+++ b/basegfx/source/workbench/bezierclip.cxx
@@ -17,6 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <iostream>
+#include <cassert>
#include <algorithm>
#include <iterator>
#include <vector>
@@ -85,7 +87,7 @@ void Impl_calcFatLine( FatLine& line, const Bezier& c )
line.b = (c.p0.x - c.p3.x);
// normalize
- const double len( sqrt( line.a*line.a + line.b*line.b ) );
+ const double len(std::hypot(line.a, line.b));
if( !tolZero(len) )
{
line.a /= len;
@@ -287,9 +289,9 @@ bool Impl_calcSafeParams_clip( double& t1,
Polygon2D convHull( convexHull( poly ) );
- cout << "# convex hull testing" << endl
+ std::cout << "# convex hull testing" << std::endl
<< "plot [t=0:1] ";
- cout << " bez("
+ std::cout << " bez("
<< poly[0].x << ","
<< poly[1].x << ","
<< poly[2].x << ","
@@ -303,22 +305,22 @@ bool Impl_calcSafeParams_clip( double& t1,
<< t1 << ", t, "
<< t2 << ", t, "
<< "'-' using ($1):($2) title \"control polygon\" with lp, "
- << "'-' using ($1):($2) title \"convex hull\" with lp" << endl;
+ << "'-' using ($1):($2) title \"convex hull\" with lp" << std::endl;
unsigned int k;
for( k=0; k<poly.size(); ++k )
{
- cout << poly[k].x << " " << poly[k].y << endl;
+ std::cout << poly[k].x << " " << poly[k].y << std::endl;
}
- cout << poly[0].x << " " << poly[0].y << endl;
- cout << "e" << endl;
+ std::cout << poly[0].x << " " << poly[0].y << std::endl;
+ std::cout << "e" << std::endl;
for( k=0; k<convHull.size(); ++k )
{
- cout << convHull[k].x << " " << convHull[k].y << endl;
+ std::cout << convHull[k].x << " " << convHull[k].y << std::endl;
}
- cout << convHull[0].x << " " << convHull[0].y << endl;
- cout << "e" << endl;
+ std::cout << convHull[0].x << " " << convHull[0].y << std::endl;
+ std::cout << "e" << std::endl;
return bRet;
#endif
@@ -376,7 +378,7 @@ void printCurvesWithSafeRange( const Bezier& c1, const Bezier& c2, double t1_c1,
{
static int offset = 0;
- cout << "# safe param range testing" << endl
+ std::cout << "# safe param range testing" << std::endl
<< "plot [t=0.0:1.0] ";
// clip safe ranges off c1
@@ -391,7 +393,7 @@ void printCurvesWithSafeRange( const Bezier& c1, const Bezier& c2, double t1_c1,
// output remaining segment (c1_part1)
- cout << "bez("
+ std::cout << "bez("
<< c1.p0.x+offset << ","
<< c1.p1.x+offset << ","
<< c1.p2.x+offset << ","
@@ -448,7 +450,7 @@ void printCurvesWithSafeRange( const Bezier& c1, const Bezier& c2, double t1_c1,
<< bounds_c2.c-bounds_c2.dMax << ",t)+" << offset << ", liney("
<< bounds_c2.a << ","
<< bounds_c2.b << ","
- << bounds_c2.c-bounds_c2.dMax << ",t) title \"fat line (max) \"" << endl;
+ << bounds_c2.c-bounds_c2.dMax << ",t) title \"fat line (max) \"" << std::endl;
offset += 1;
}
@@ -459,10 +461,10 @@ void printResultWithFinalCurves( const Bezier& c1, const Bezier& c1_part,
{
static int offset = 0;
- cout << "# final result" << endl
+ std::cout << "# final result" << std::endl
<< "plot [t=0.0:1.0] ";
- cout << "bez("
+ std::cout << "bez("
<< c1.p0.x+offset << ","
<< c1.p1.x+offset << ","
<< c1.p2.x+offset << ","
@@ -521,7 +523,7 @@ void printResultWithFinalCurves( const Bezier& c1, const Bezier& c1_part,
<< c2_part.p0.y << ","
<< c2_part.p1.y << ","
<< c2_part.p2.y << ","
- << c2_part.p3.y << ",t)" << endl;
+ << c2_part.p3.y << ",t)" << std::endl;
offset += 1;
}
@@ -682,7 +684,7 @@ void Impl_calcFocus( Bezier& res, const Bezier& c )
fRes[0] = 0.0;
fRes[1] = 1.0;
- cerr << "Matrix singular!" << endl;
+ std::cerr << "Matrix singular!" << std::endl;
}
// now, the reordered and per-coefficient collected focus curve is
@@ -842,25 +844,25 @@ bool Impl_calcSafeParams_focus( double& t1,
Polygon2D convHull( convexHull( controlPolygon ) );
- cout << "# convex hull testing (focus)" << endl
+ std::cout << "# convex hull testing (focus)" << std::endl
<< "plot [t=0:1] ";
- cout << "'-' using ($1):($2) title \"control polygon\" with lp, "
- << "'-' using ($1):($2) title \"convex hull\" with lp" << endl;
+ std::cout << "'-' using ($1):($2) title \"control polygon\" with lp, "
+ << "'-' using ($1):($2) title \"convex hull\" with lp" << std::endl;
unsigned int count;
for( count=0; count<controlPolygon.size(); ++count )
{
- cout << controlPolygon[count].x << " " << controlPolygon[count].y << endl;
+ std::cout << controlPolygon[count].x << " " << controlPolygon[count].y << std::endl;
}
- cout << controlPolygon[0].x << " " << controlPolygon[0].y << endl;
- cout << "e" << endl;
+ std::cout << controlPolygon[0].x << " " << controlPolygon[0].y << std::endl;
+ std::cout << "e" << std::endl;
for( count=0; count<convHull.size(); ++count )
{
- cout << convHull[count].x << " " << convHull[count].y << endl;
+ std::cout << convHull[count].x << " " << convHull[count].y << std::endl;
}
- cout << convHull[0].x << " " << convHull[0].y << endl;
- cout << "e" << endl;
+ std::cout << convHull[0].x << " " << convHull[0].y << std::endl;
+ std::cout << "e" << std::endl;
return bRet;
#endif
@@ -922,24 +924,24 @@ template <class Functor> void Impl_applySafeRanges_rec( std::back_insert_iterato
// tangency, and justifies to return a single intersection
// point. Otherwise, inside/outside test might fail here.
- for( int i=0; i<recursionLevel; ++i ) cerr << " ";
+ for( int i=0; i<recursionLevel; ++i ) std::cerr << " ";
if( recursionLevel % 2 )
{
- cerr << "level: " << recursionLevel
+ std::cerr << std::endl << "level: " << recursionLevel
<< " t: "
<< last_t1_c2 + (last_t2_c2 - last_t1_c2)/2.0
<< ", c1: " << last_t1_c2 << " " << last_t2_c2
<< ", c2: " << last_t1_c1 << " " << last_t2_c1
- << endl;
+ << std::endl;
}
else
{
- cerr << "level: " << recursionLevel
+ std::cerr << std::endl << "level: " << recursionLevel
<< " t: "
<< last_t1_c1 + (last_t2_c1 - last_t1_c1)/2.0
<< ", c1: " << last_t1_c1 << " " << last_t2_c1
<< ", c2: " << last_t1_c2 << " " << last_t2_c2
- << endl;
+ << std::endl;
}
// refine solution
@@ -1141,7 +1143,7 @@ struct BezierTangencyFunctor
c1_orig, // use orig curve here, need t's on original curve
focus ) );
- cerr << "range: " << t2_c1 - t1_c1 << ", ret: " << bRet << endl;
+ std::cerr << "range: " << t2_c1 - t1_c1 << ", ret: " << bRet << std::endl;
return bRet;
}
@@ -1299,24 +1301,24 @@ int main(int argc, const char *argv[])
};
// output gnuplot setup
- cout << "#!/usr/bin/gnuplot -persist" << endl
- << "#" << endl
- << "# automatically generated by bezierclip, don't change!" << endl
- << "#" << endl
- << "set parametric" << endl
- << "bez(p,q,r,s,t) = p*(1-t)**3+q*3*(1-t)**2*t+r*3*(1-t)*t**2+s*t**3" << endl
- << "bezd(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2" << endl
- << "pointmarkx(c,t) = c-0.03*t" << endl
- << "pointmarky(c,t) = c+0.03*t" << endl
- << "linex(a,b,c,t) = a*-c + t*-b" << endl
- << "liney(a,b,c,t) = b*-c + t*a" << endl << endl
- << "# end of setup" << endl << endl;
+ std::cout << "#!/usr/bin/gnuplot -persist" << std::endl
+ << "#" << std::endl
+ << "# automatically generated by bezierclip, don't change!" << std::endl
+ << "#" << std::endl
+ << "set parametric" << std::endl
+ << "bez(p,q,r,s,t) = p*(1-t)**3+q*3*(1-t)**2*t+r*3*(1-t)*t**2+s*t**3" << std::endl
+ << "bezd(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2" << std::endl
+ << "pointmarkx(c,t) = c-0.03*t" << std::endl
+ << "pointmarky(c,t) = c+0.03*t" << std::endl
+ << "linex(a,b,c,t) = a*-c + t*-b" << std::endl
+ << "liney(a,b,c,t) = b*-c + t*a" << std::endl << std::endl
+ << "# end of setup" << std::endl << std::endl;
#ifdef WITH_CONVEXHULL_TEST
// test convex hull algorithm
const double convHull_xOffset( curr_Offset );
curr_Offset += 20;
- cout << "# convex hull testing" << endl
+ std::cout << "# convex hull testing" << std::endl
<< "plot [t=0:1] ";
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1331,7 +1333,7 @@ int main(int argc, const char *argv[])
aTestPoly[2].x += convHull_xOffset;
aTestPoly[3].x += convHull_xOffset;
- cout << " bez("
+ std::cout << " bez("
<< aTestPoly[0].x << ","
<< aTestPoly[1].x << ","
<< aTestPoly[2].x << ","
@@ -1342,9 +1344,9 @@ int main(int argc, const char *argv[])
<< aTestPoly[3].y << ",t), '-' using ($1):($2) title \"convex hull " << i << "\" with lp";
if( i+1<sizeof(someCurves)/sizeof(Bezier) )
- cout << ",\\" << endl;
+ std::cout << ",\\" << std::endl;
else
- cout << endl;
+ std::cout << std::endl;
}
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1363,10 +1365,10 @@ int main(int argc, const char *argv[])
for( k=0; k<convHull.size(); ++k )
{
- cout << convHull[k].x << " " << convHull[k].y << endl;
+ std::cout << convHull[k].x << " " << convHull[k].y << std::endl;
}
- cout << convHull[0].x << " " << convHull[0].y << endl;
- cout << "e" << endl;
+ std::cout << convHull[0].x << " " << convHull[0].y << std::endl;
+ std::cout << "e" << std::endl;
}
#endif
@@ -1374,7 +1376,7 @@ int main(int argc, const char *argv[])
// test convex hull algorithm
const double multiSubdivide_xOffset( curr_Offset );
curr_Offset += 20;
- cout << "# multi subdivide testing" << endl
+ std::cout << "# multi subdivide testing" << std::endl
<< "plot [t=0:1] ";
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1406,7 +1408,7 @@ int main(int argc, const char *argv[])
// subdivide at t2
Impl_deCasteljauAt( c1_part3, c1_part2, c, t2 );
- cout << " bez("
+ std::cout << " bez("
<< c1_part1.p0.x << ","
<< c1_part1.p1.x << ","
<< c1_part1.p2.x << ","
@@ -1435,9 +1437,9 @@ int main(int argc, const char *argv[])
<< c1_part3.p3.y << ",t) title \"left " << i << "\"";
if( i+1<sizeof(someCurves)/sizeof(Bezier) )
- cout << ",\\" << endl;
+ std::cout << ",\\" << std::endl;
else
- cout << endl;
+ std::cout << std::endl;
}
#endif
@@ -1445,7 +1447,7 @@ int main(int argc, const char *argv[])
// test fatline algorithm
const double fatLine_xOffset( curr_Offset );
curr_Offset += 20;
- cout << "# fat line testing" << endl
+ std::cout << "# fat line testing" << std::endl
<< "plot [t=0:1] ";
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1460,7 +1462,7 @@ int main(int argc, const char *argv[])
Impl_calcFatLine(line, c);
- cout << " bez("
+ std::cout << " bez("
<< c.p0.x << ","
<< c.p1.x << ","
<< c.p2.x << ","
@@ -1489,9 +1491,9 @@ int main(int argc, const char *argv[])
<< line.c-line.dMax << ",t) title \"fat line (max) on " << i << "\"";
if( i+1<sizeof(someCurves)/sizeof(Bezier) )
- cout << ",\\" << endl;
+ std::cout << ",\\" << std::endl;
else
- cout << endl;
+ std::cout << std::endl;
}
#endif
@@ -1499,7 +1501,7 @@ int main(int argc, const char *argv[])
// test focus curve algorithm
const double focus_xOffset( curr_Offset );
curr_Offset += 20;
- cout << "# focus line testing" << endl
+ std::cout << "# focus line testing" << std::endl
<< "plot [t=0:1] ";
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1514,7 +1516,7 @@ int main(int argc, const char *argv[])
Bezier focus;
Impl_calcFocus(focus, c);
- cout << " bez("
+ std::cout << " bez("
<< c.p0.x << ","
<< c.p1.x << ","
<< c.p2.x << ","
@@ -1533,16 +1535,16 @@ int main(int argc, const char *argv[])
<< focus.p3.y << ",t) title \"focus " << i << "\"";
if( i+1<sizeof(someCurves)/sizeof(Bezier) )
- cout << ",\\" << endl;
+ std::cout << ",\\" << std::endl;
else
- cout << endl;
+ std::cout << std::endl;
}
#endif
#ifdef WITH_SAFEPARAMBASE_TEST
// test safe params base method
double safeParamsBase_xOffset( curr_Offset );
- cout << "# safe param base method testing" << endl
+ std::cout << "# safe param base method testing" << std::endl
<< "plot [t=0:1] ";
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1565,7 +1567,7 @@ int main(int argc, const char *argv[])
Polygon2D convHull( convexHull( poly ) );
- cout << " bez("
+ std::cout << " bez("
<< poly[0].x << ","
<< poly[1].x << ","
<< poly[2].x << ","
@@ -1578,16 +1580,16 @@ int main(int argc, const char *argv[])
<< "t+" << safeParamsBase_xOffset << ", 1, ";
if( bRet )
{
- cout << t1+safeParamsBase_xOffset << ", t, "
+ std::cout << t1+safeParamsBase_xOffset << ", t, "
<< t2+safeParamsBase_xOffset << ", t, ";
}
- cout << "'-' using ($1):($2) title \"control polygon\" with lp, "
+ std::cout << "'-' using ($1):($2) title \"control polygon\" with lp, "
<< "'-' using ($1):($2) title \"convex hull\" with lp";
if( i+1<sizeof(someCurves)/sizeof(Bezier) )
- cout << ",\\" << endl;
+ std::cout << ",\\" << std::endl;
else
- cout << endl;
+ std::cout << std::endl;
safeParamsBase_xOffset += 2;
}
@@ -1617,17 +1619,17 @@ int main(int argc, const char *argv[])
unsigned int k;
for( k=0; k<poly.size(); ++k )
{
- cout << poly[k].x << " " << poly[k].y << endl;
+ std::cout << poly[k].x << " " << poly[k].y << std::endl;
}
- cout << poly[0].x << " " << poly[0].y << endl;
- cout << "e" << endl;
+ std::cout << poly[0].x << " " << poly[0].y << std::endl;
+ std::cout << "e" << std::endl;
for( k=0; k<convHull.size(); ++k )
{
- cout << convHull[k].x << " " << convHull[k].y << endl;
+ std::cout << convHull[k].x << " " << convHull[k].y << std::endl;
}
- cout << convHull[0].x << " " << convHull[0].y << endl;
- cout << "e" << endl;
+ std::cout << convHull[0].x << " " << convHull[0].y << std::endl;
+ std::cout << "e" << std::endl;
safeParamsBase_xOffset += 2;
}
@@ -1638,7 +1640,7 @@ int main(int argc, const char *argv[])
// test safe parameter range algorithm
const double safeParams_xOffset( curr_Offset );
curr_Offset += 20;
- cout << "# safe param range testing" << endl
+ std::cout << "# safe param range testing" << std::endl
<< "plot [t=0.0:1.0] ";
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1672,7 +1674,7 @@ int main(int argc, const char *argv[])
// output remaining segment (c1_part1)
- cout << " bez("
+ std::cout << " bez("
<< c1.p0.x << ","
<< c1.p1.x << ","
<< c1.p2.x << ","
@@ -1699,9 +1701,9 @@ int main(int argc, const char *argv[])
<< c1_part1.p3.y << ",t)";
if( i+2<sizeof(someCurves)/sizeof(Bezier) )
- cout << ",\\" << endl;
+ std::cout << ",\\" << std::endl;
else
- cout << endl;
+ std::cout << std::endl;
}
}
}
@@ -1736,7 +1738,7 @@ int main(int argc, const char *argv[])
// test safe parameter range from focus algorithm
const double safeParamsFocus_xOffset( curr_Offset );
curr_Offset += 20;
- cout << "# safe param range from focus testing" << endl
+ std::cout << "# safe param range from focus testing" << std::endl
<< "plot [t=0.0:1.0] ";
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1790,7 +1792,7 @@ int main(int argc, const char *argv[])
bool bRet( Impl_calcSafeParams_focus( t1, t2,
c1, focus ) );
- cerr << "t1: " << t1 << ", t2: " << t2 << endl;
+ std::cerr << "t1: " << t1 << ", t2: " << t2 << std::endl;
// clip safe ranges off c1
Bezier c1_part1;
@@ -1804,7 +1806,7 @@ int main(int argc, const char *argv[])
// output remaining segment (c1_part1)
- cout << " bez("
+ std::cout << " bez("
<< c1.p0.x << ","
<< c1.p1.x << ","
<< c1.p2.x << ","
@@ -1845,7 +1847,7 @@ int main(int argc, const char *argv[])
#endif
if( bRet )
{
- cout << ", bez("
+ std::cout << ", bez("
<< c1_part1.p0.x << ","
<< c1_part1.p1.x << ","
<< c1_part1.p2.x << ","
@@ -1857,9 +1859,9 @@ int main(int argc, const char *argv[])
}
if( i+2<sizeof(someCurves)/sizeof(Bezier) )
- cout << ",\\" << endl;
+ std::cout << ",\\" << std::endl;
else
- cout << endl;
+ std::cout << std::endl;
}
}
#endif
@@ -1903,7 +1905,7 @@ int main(int argc, const char *argv[])
// test full bezier clipping
const double bezierClip_xOffset( curr_Offset );
- cout << endl << endl << "# bezier clip testing" << endl
+ std::cout << std::endl << std::endl << "# bezier clip testing" << std::endl
<< "plot [t=0:1] ";
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
{
@@ -1921,7 +1923,7 @@ int main(int argc, const char *argv[])
c2.p2.x += bezierClip_xOffset;
c2.p3.x += bezierClip_xOffset;
- cout << " bez("
+ std::cout << " bez("
<< c1.p0.x << ","
<< c1.p1.x << ","
<< c1.p2.x << ","
@@ -1959,9 +1961,9 @@ int main(int argc, const char *argv[])
<< c2.p3.y << ",$1)) title \"bezier " << i << " clipped against " << j << " (t on " << j << ")\"";
if( i+2<sizeof(someCurves)/sizeof(Bezier) )
- cout << ",\\" << endl;
+ std::cout << ",\\" << std::endl;
else
- cout << endl;
+ std::cout << std::endl;
}
}
for( i=0; i<sizeof(someCurves)/sizeof(Bezier); ++i )
@@ -1985,15 +1987,15 @@ int main(int argc, const char *argv[])
for( k=0; k<result.size(); ++k )
{
- cout << result[k].first << endl;
+ std::cout << result[k].first << std::endl;
}
- cout << "e" << endl;
+ std::cout << "e" << std::endl;
for( k=0; k<result.size(); ++k )
{
- cout << result[k].second << endl;
+ std::cout << result[k].second << std::endl;
}
- cout << "e" << endl;
+ std::cout << "e" << std::endl;
}
}
#endif
diff --git a/basegfx/source/workbench/gauss.hxx b/basegfx/source/workbench/gauss.hxx
index 3605c1cac9bd..4ef050ccbc52 100644
--- a/basegfx/source/workbench/gauss.hxx
+++ b/basegfx/source/workbench/gauss.hxx
@@ -47,8 +47,6 @@ bool eliminate( Matrix& matrix,
int cols,
const BaseType& minPivot )
{
- BaseType temp;
-
/* i, j, k *must* be signed, when looping like: j>=0 ! */
/* eliminate below main diagonal */
for(int i=0; i<cols-1; ++i)
@@ -66,9 +64,7 @@ bool eliminate( Matrix& matrix,
/* interchange rows 'max' and 'i' */
for(int k=0; k<cols; ++k)
{
- temp = matrix[ i*cols + k ];
- matrix[ i*cols + k ] = matrix[ max*cols + k ];
- matrix[ max*cols + k ] = temp;
+ std::swap(matrix[ i*cols + k ], matrix[ max*cols + k ]);
}
/* eliminate column */