void CFDE_Path::AddCurve(const CFX_PointsF& points, FX_BOOL bClosed, FX_FLOAT fTension) { int32_t iLast = points.GetUpperBound(); if (iLast < 1) return; CFX_PointsF tangents; GetCurveTangents(points, tangents, bClosed, fTension); const CFX_PointF* pPoints = points.GetData(); CFX_PointF* pTangents = tangents.GetData(); MoveTo(pPoints[0]); for (int32_t i = 0; i < iLast; ++i) { BezierTo(CFX_PointF(pPoints[i].x + pTangents[i].x, pPoints[i].y + pTangents[i].y), CFX_PointF(pPoints[i + 1].x - pTangents[i + 1].x, pPoints[i + 1].y - pTangents[i + 1].y), CFX_PointF(pPoints[i + 1].x, pPoints[i + 1].y)); } if (bClosed) { BezierTo(CFX_PointF(pPoints[iLast].x + pTangents[iLast].x, pPoints[iLast].y + pTangents[iLast].y), CFX_PointF(pPoints[0].x - pTangents[0].x, pPoints[0].y - pTangents[0].y), CFX_PointF(pPoints[0].x, pPoints[0].y)); CloseFigure(); } }
void CFDE_Path::ArcTo(FX_BOOL bStart, const CFX_RectF& rect, FX_FLOAT startAngle, FX_FLOAT endAngle) { FX_FLOAT rx = rect.width / 2; FX_FLOAT ry = rect.height / 2; FX_FLOAT cx = rect.left + rx; FX_FLOAT cy = rect.top + ry; FX_FLOAT alpha = FXSYS_atan2(rx * FXSYS_sin(startAngle), ry * FXSYS_cos(startAngle)); FX_FLOAT beta = FXSYS_atan2(rx * FXSYS_sin(endAngle), ry * FXSYS_cos(endAngle)); if (FXSYS_fabs(beta - alpha) > FX_PI) { if (beta > alpha) beta -= 2 * FX_PI; else alpha -= 2 * FX_PI; } FX_FLOAT half_delta = (beta - alpha) / 2; FX_FLOAT bcp = 4.0f / 3 * (1 - FXSYS_cos(half_delta)) / FXSYS_sin(half_delta); FX_FLOAT sin_alpha = FXSYS_sin(alpha); FX_FLOAT sin_beta = FXSYS_sin(beta); FX_FLOAT cos_alpha = FXSYS_cos(alpha); FX_FLOAT cos_beta = FXSYS_cos(beta); if (bStart) MoveTo(CFX_PointF(cx + rx * cos_alpha, cy + ry * sin_alpha)); BezierTo(CFX_PointF(cx + rx * (cos_alpha - bcp * sin_alpha), cy + ry * (sin_alpha + bcp * cos_alpha)), CFX_PointF(cx + rx * (cos_beta + bcp * sin_beta), cy + ry * (sin_beta - bcp * cos_beta)), CFX_PointF(cx + rx * cos_beta, cy + ry * sin_beta)); }
void CFDE_Path::AddBezier(const CFX_PointsF& points) { if (points.GetSize() != 4) return; const CFX_PointF* p = points.GetData(); MoveTo(p[0]); BezierTo(p[1], p[2], p[3]); }
void CFDE_Path::AddBeziers(const CFX_PointsF& points) { int32_t iCount = points.GetSize(); if (iCount < 4) return; const CFX_PointF* p = points.GetData(); const CFX_PointF* pEnd = p + iCount; MoveTo(p[0]); for (++p; p <= pEnd - 3; p += 3) BezierTo(p[0], p[1], p[2]); }
void Path::InsertBezierTo(Geom::Point const &iPt, int iNb, int at) { if ( at < 0 || at > int(descr_cmd.size()) ) { return; } if ( at == int(descr_cmd.size()) ) { BezierTo(iPt); return; } descr_cmd.insert(descr_cmd.begin() + at, new PathDescrBezierTo(iPt, iNb)); }
void FlattenedPath::QuadraticBezierTo(const Point &aCP1, const Point &aCP2) { MOZ_ASSERT(!mCalculatedLength); // We need to elevate the degree of this quadratic Bézier to cubic, so we're // going to add an intermediate control point, and recompute control point 1. // The first and last control points remain the same. // This formula can be found on http://fontforge.sourceforge.net/bezier.html Point CP0 = CurrentPoint(); Point CP1 = (CP0 + aCP1 * 2.0) / 3.0; Point CP2 = (aCP2 + aCP1 * 2.0) / 3.0; Point CP3 = aCP2; BezierTo(CP1, CP2, CP3); }
status_t BShape::BezierTo(BPoint controlPoints[3]) { return BezierTo(controlPoints[0], controlPoints[1], controlPoints[2]); }