7#include "xfa/fgas/graphics/cfgas_gepath.h"
11#include "core/fxcrt/fx_system.h"
12#include "core/fxge/cfx_path.h"
26void CFGAS_GEPath::
MoveTo(
const CFX_PointF& point) {
27 path_.AppendPoint(point, CFX_Path::Point::Type::kMove);
30void CFGAS_GEPath::
LineTo(
const CFX_PointF& point) {
31 path_.AppendPoint(point, CFX_Path::Point::Type::kLine);
34void CFGAS_GEPath::
BezierTo(
const CFX_PointF& c1,
36 const CFX_PointF& to) {
37 path_.AppendPoint(c1, CFX_Path::Point::Type::kBezier);
38 path_.AppendPoint(c2, CFX_Path::Point::Type::kBezier);
39 path_.AppendPoint(to, CFX_Path::Point::Type::kBezier);
42void CFGAS_GEPath::
ArcTo(
const CFX_PointF& pos,
43 const CFX_SizeF& size,
46 CFX_SizeF new_size = size / 2.0f;
47 ArcToInternal(CFX_PointF(pos.x + new_size.width, pos.y + new_size.height),
48 new_size, start_angle, sweep_angle);
51void CFGAS_GEPath::ArcToInternal(
const CFX_PointF& pos,
52 const CFX_SizeF& size,
55 float x0 = cos(sweep_angle / 2);
56 float y0 = sin(sweep_angle / 2);
57 float tx = ((1.0f - x0) * 4) / (3 * 1.0f);
58 float ty = y0 - ((tx * x0) / y0);
60 CFX_PointF points[] = {CFX_PointF(x0 + tx, -ty), CFX_PointF(x0 + tx, ty)};
61 float sn = sin(start_angle + sweep_angle / 2);
62 float cs = cos(start_angle + sweep_angle / 2);
65 bezier.x = pos.x + (size.width * ((points[0].x * cs) - (points[0].y * sn)));
66 bezier.y = pos.y + (size.height * ((points[0].x * sn) + (points[0].y * cs)));
67 path_.AppendPoint(bezier, CFX_Path::Point::Type::kBezier);
69 bezier.x = pos.x + (size.width * ((points[1].x * cs) - (points[1].y * sn)));
70 bezier.y = pos.y + (size.height * ((points[1].x * sn) + (points[1].y * cs)));
71 path_.AppendPoint(bezier, CFX_Path::Point::Type::kBezier);
73 bezier.x = pos.x + (size.width * cos(start_angle + sweep_angle));
74 bezier.y = pos.y + (size.height * sin(start_angle + sweep_angle));
75 path_.AppendPoint(bezier, CFX_Path::Point::Type::kBezier);
78void CFGAS_GEPath::
AddLine(
const CFX_PointF& p1,
const CFX_PointF& p2) {
79 path_.AppendPoint(p1, CFX_Path::Point::Type::kMove);
80 path_.AppendPoint(p2, CFX_Path::Point::Type::kLine);
87 path_.AppendRect(left, top, left + width, top + height);
94void CFGAS_GEPath::
AddArc(
const CFX_PointF& original_pos,
95 const CFX_SizeF& original_size,
101 const float bezier_arc_angle_epsilon = 0.01f;
104 while (start_angle < 0)
111 CFX_SizeF size = original_size / 2;
112 CFX_PointF pos(original_pos.x + size.width, original_pos.y + size.height);
113 path_.AppendPoint(pos + CFX_PointF(size.width * cos(start_angle),
114 size.height * sin(start_angle)),
115 CFX_Path::Point::Type::kMove);
117 float total_sweep = 0;
118 float local_sweep = 0;
119 float prev_sweep = 0;
122 if (sweep_angle < 0) {
123 prev_sweep = total_sweep;
126 if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) {
127 local_sweep = sweep_angle - prev_sweep;
131 prev_sweep = total_sweep;
134 if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) {
135 local_sweep = sweep_angle - prev_sweep;
140 ArcToInternal(pos, size, start_angle, local_sweep);
141 start_angle += local_sweep;
146 path_.Append(path.path_,
nullptr);
void TransformBy(const CFX_Matrix &mt)
void AddLine(const CFX_PointF &p1, const CFX_PointF &p2)
void MoveTo(const CFX_PointF &point)
void ArcTo(const CFX_PointF &pos, const CFX_SizeF &size, float startAngle, float sweepAngle)
void BezierTo(const CFX_PointF &c1, const CFX_PointF &c2, const CFX_PointF &to)
void AddRectangle(float left, float top, float width, float height)
void AddEllipse(const CFX_RectF &rect)
void AddArc(const CFX_PointF &pos, const CFX_SizeF &size, float startAngle, float sweepAngle)
void LineTo(const CFX_PointF &point)
void AddSubpath(const CFGAS_GEPath &path)