add appendQuadraticBezierSegment to B2DPolygon
This adds a convenience method to B2DPolygon to add a quadratic bezier segment, which converts its one control point to two control points of a cubic bezier segment. The SVG path import is also modified to use this new method instead of converting inside the importer itself. Change-Id: I96e9b306066d9ccf2542b17a117db01fa235f405 Reviewed-on: https://gerrit.libreoffice.org/74809 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
parent
3aa02e11e4
commit
80eb3fd393
4 changed files with 50 additions and 10 deletions
|
@ -1330,6 +1330,28 @@ namespace basegfx
|
|||
}
|
||||
}
|
||||
|
||||
void B2DPolygon::appendQuadraticBezierSegment(const B2DPoint& rControlPoint, const B2DPoint& rPoint)
|
||||
{
|
||||
if (mpPolygon->count() == 0)
|
||||
{
|
||||
mpPolygon->append(rPoint);
|
||||
const double nX((rControlPoint.getX() * 2.0 + rPoint.getX()) / 3.0);
|
||||
const double nY((rControlPoint.getY() * 2.0 + rPoint.getY()) / 3.0);
|
||||
setPrevControlPoint(0, B2DPoint(nX, nY));
|
||||
}
|
||||
else
|
||||
{
|
||||
const B2DPoint aPreviousPoint(mpPolygon->getPoint(mpPolygon->count() - 1));
|
||||
|
||||
const double nX1((rControlPoint.getX() * 2.0 + aPreviousPoint.getX()) / 3.0);
|
||||
const double nY1((rControlPoint.getY() * 2.0 + aPreviousPoint.getY()) / 3.0);
|
||||
const double nX2((rControlPoint.getX() * 2.0 + rPoint.getX()) / 3.0);
|
||||
const double nY2((rControlPoint.getY() * 2.0 + rPoint.getY()) / 3.0);
|
||||
|
||||
appendBezierSegment(B2DPoint(nX1, nY1), B2DPoint(nX2, nY2), rPoint);
|
||||
}
|
||||
}
|
||||
|
||||
bool B2DPolygon::areControlPointsUsed() const
|
||||
{
|
||||
return mpPolygon->areControlPointsUsed();
|
||||
|
|
|
@ -375,12 +375,6 @@ namespace basegfx
|
|||
nY += nLastY;
|
||||
}
|
||||
|
||||
// calculate the cubic bezier coefficients from the quadratic ones
|
||||
const double nX1Prime((nX1 * 2.0 + nLastX) / 3.0);
|
||||
const double nY1Prime((nY1 * 2.0 + nLastY) / 3.0);
|
||||
const double nX2Prime((nX1 * 2.0 + nX) / 3.0);
|
||||
const double nY2Prime((nY1 * 2.0 + nY) / 3.0);
|
||||
|
||||
// ensure existence of start point
|
||||
if(!aCurrPoly.count())
|
||||
{
|
||||
|
@ -388,7 +382,7 @@ namespace basegfx
|
|||
}
|
||||
|
||||
// append curved edge
|
||||
aCurrPoly.appendBezierSegment(B2DPoint(nX1Prime, nY1Prime), B2DPoint(nX2Prime, nY2Prime), B2DPoint(nX, nY));
|
||||
aCurrPoly.appendQuadraticBezierSegment(B2DPoint(nX1, nY1), B2DPoint(nX, nY));
|
||||
|
||||
// set last position
|
||||
nLastX = nX;
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace basegfx
|
|||
class b2dpolygon : public CppUnit::TestFixture
|
||||
{
|
||||
public:
|
||||
void testBasics()
|
||||
void testCubicBezier()
|
||||
{
|
||||
B2DPolygon aPoly;
|
||||
|
||||
|
@ -78,12 +78,29 @@ public:
|
|||
aPoly.getB2DPoint(1));
|
||||
}
|
||||
|
||||
void testQuadraticBezier()
|
||||
{
|
||||
B2DPolygon aPoly;
|
||||
|
||||
aPoly.appendQuadraticBezierSegment(B2DPoint(0, 0), B2DPoint(3, 3));
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("polygon size is wrong", sal_uInt32(1), aPoly.count());
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("first polygon point wrong", B2DPoint(3, 3),
|
||||
aPoly.getB2DPoint(0));
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("first control point wrong", B2DPoint(1, 1),
|
||||
aPoly.getPrevControlPoint(0));
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE("second control point wrong", B2DPoint(3, 3),
|
||||
aPoly.getNextControlPoint(0));
|
||||
CPPUNIT_ASSERT_MESSAGE("next control point not used", !aPoly.isNextControlPointUsed(0));
|
||||
}
|
||||
|
||||
// Change the following lines only, if you add, remove or rename
|
||||
// member functions of the current class,
|
||||
// because these macros are need by auto register mechanism.
|
||||
|
||||
CPPUNIT_TEST_SUITE(b2dpolygon);
|
||||
CPPUNIT_TEST(testBasics);
|
||||
CPPUNIT_TEST(testCubicBezier);
|
||||
CPPUNIT_TEST(testQuadraticBezier);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
}; // class b2dpolygon
|
||||
|
||||
|
|
|
@ -99,7 +99,14 @@ namespace basegfx
|
|||
void resetControlPoints();
|
||||
|
||||
/// Bezier segment append with control points. The current last polygon point is implicitly taken as start point.
|
||||
void appendBezierSegment(const basegfx::B2DPoint& rNextControlPoint, const basegfx::B2DPoint& rPrevControlPoint, const basegfx::B2DPoint& rPoint);
|
||||
void appendBezierSegment(const basegfx::B2DPoint& rNextControlPoint,
|
||||
const basegfx::B2DPoint& rPrevControlPoint,
|
||||
const basegfx::B2DPoint& rPoint);
|
||||
|
||||
/// This is a shortcut to append a quadratic bezier segment. The current last polygon point is implicitly taken as start point.
|
||||
/// Note that the quadratic bezier control points will be converted to cubic bezier with 2 control points.
|
||||
void appendQuadraticBezierSegment(const basegfx::B2DPoint& rQuadControlPoint,
|
||||
const basegfx::B2DPoint& rPoint);
|
||||
|
||||
/// ControlPoint checks
|
||||
bool areControlPointsUsed() const;
|
||||
|
|
Loading…
Reference in a new issue