gecko-dev/gfx/2d/BezierUtils.h

186 lines
5.3 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#ifndef mozilla_BezierUtils_h_
#define mozilla_BezierUtils_h_
#include "mozilla/gfx/2D.h"
#include "gfxRect.h"
namespace mozilla {
namespace gfx {
// Control points for bezier curve
//
// mPoints[2]
// +-----___---+ mPoints[3]
// __--
// _--
// /
// /
// mPoints[1] + |
// | |
// ||
// ||
// |
// |
// |
// |
// mPoints[0] +
struct Bezier {
Point mPoints[4];
};
// Calculate a point or it's differential of a bezier curve formed by
// aBezier and parameter t.
//
// GetBezierPoint = P(t)
// GetBezierDifferential = P'(t)
// GetBezierDifferential2 = P''(t)
//
// mPoints[2]
// +-----___---+ mPoints[3]
// __-- P(1)
// _--
// +
// / P(t)
// mPoints[1] + |
// | |
// ||
// ||
// |
// |
// |
// |
// mPoints[0] + P(0)
Point GetBezierPoint(const Bezier& aBezier, Float t);
Point GetBezierDifferential(const Bezier& aBezier, Float t);
Point GetBezierDifferential2(const Bezier& aBezier, Float t);
// Calculate length of a simple bezier curve formed by aBezier and range [a, b].
Float GetBezierLength(const Bezier& aBezier, Float a, Float b);
// Split bezier curve formed by aBezier into [0,t1], [t1,t2], [t2,1] parts, and
// stores control points for [t1,t2] to aSubBezier.
//
// ___---+
// __+- P(1)
// _-- P(t2)
// -
// / <-- aSubBezier
// |
// |
// +
// | P(t1)
// |
// |
// |
// |
// + P(0)
void GetSubBezier(Bezier* aSubBezier, const Bezier& aBezier,
Float t1, Float t2);
// Find a nearest point on bezier curve formed by aBezier to a point aTarget.
// aInitialT is a hint to find the parameter t for the nearest point.
// If aT is non-null, parameter for the nearest point is stored to *aT.
// This function expects a bezier curve to be an approximation of elliptic arc.
// Otherwise it will return wrong point.
//
// aTarget
// + ___---+
// __--
// _--
// +
// / nearest point = P(t = *aT)
// |
// |
// |
// + P(aInitialT)
// |
// |
// |
// |
// +
Point FindBezierNearestPoint(const Bezier& aBezier, const Point& aTarget,
Float aInitialT, Float* aT=nullptr);
// Calculate control points for a bezier curve that is an approximation of
// an elliptic arc.
//
// aCornerSize.width
// |<----------------->|
// | |
// aCornerPoint| mPoints[2] |
// -------------+-------+-----___---+ mPoints[3]
// ^ | __--
// | | _--
// | | -
// | | /
// aCornerSize.height | mPoints[1] + |
// | | |
// | ||
// | ||
// | |
// | |
// | |
// v mPoints[0] |
// -------------+
void GetBezierPointsForCorner(Bezier* aBezier, mozilla::css::Corner aCorner,
const Point& aCornerPoint,
const Size& aCornerSize);
// Calculate the approximate length of a quarter elliptic arc formed by radii
// (a, b).
//
// a
// |<----------------->|
// | |
// ---+-------------___---+
// ^ | __--
// | | _--
// | | -
// | | /
// b | | |
// | | |
// | ||
// | ||
// | |
// | |
// | |
// v |
// ---+
Float GetQuarterEllipticArcLength(Float a, Float b);
// Calculate the distance between an elliptic arc formed by (origin, width,
// height), and a point P, along a line formed by |P + n * normal|.
// P should be outside of the ellipse, and the line should cross with the
// ellipse twice at n > 0 points.
//
// width
// |<----------------->|
// origin | |
// -----------+-------------___---+
// ^ normal | __--
// | P +->__ | _--
// | --__ -
// | | --+
// height | | |
// | | |
// | ||
// | ||
// | |
// | |
// | |
// v |
// -----------+
Float CalculateDistanceToEllipticArc(const Point& P, const Point& normal,
const Point& origin,
Float width, Float height);
} // namespace gfx
} // namespace mozilla
#endif /* mozilla_BezierUtils_h_ */