diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2017-02-23 13:29:56 -0500 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-02-23 18:52:03 +0000 |
commit | efcf362b6658346ae0f8f3cdb73d871fdd82c8af (patch) | |
tree | 035759c5ba63c89600b5c9e88a2c3120de0e6ff9 /xfa/fxgraphics/cfx_path.cpp | |
parent | c6dc69fb69e5d9974aa451d590194d568b78131b (diff) | |
download | pdfium-efcf362b6658346ae0f8f3cdb73d871fdd82c8af.tar.xz |
Merge CFX_PathGenerator into CFX_Path.
The CFX_Path was the only user of the CFX_PathGenerator which in turn just
proxied to the CFX_PathData. This CL removes the CFX_PathGenerator and merges
the code up into CFX_Path.
Change-Id: I9e1a3921c987830f29b2ff5bd4aceacd2082e8f0
Reviewed-on: https://pdfium-review.googlesource.com/2825
Reviewed-by: Nicolás Peña <npm@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'xfa/fxgraphics/cfx_path.cpp')
-rw-r--r-- | xfa/fxgraphics/cfx_path.cpp | 267 |
1 files changed, 128 insertions, 139 deletions
diff --git a/xfa/fxgraphics/cfx_path.cpp b/xfa/fxgraphics/cfx_path.cpp index 3072df2475..d56eb13f67 100644 --- a/xfa/fxgraphics/cfx_path.cpp +++ b/xfa/fxgraphics/cfx_path.cpp @@ -8,155 +8,144 @@ #include "core/fxge/cfx_pathdata.h" #include "third_party/base/ptr_util.h" -#include "xfa/fxgraphics/cfx_path_generator.h" CFX_Path::CFX_Path() {} -FWL_Error CFX_Path::Create() { - if (m_generator) - return FWL_Error::PropertyInvalid; - - m_generator = pdfium::MakeUnique<CFX_PathGenerator>(); - return FWL_Error::Succeeded; -} - CFX_Path::~CFX_Path() {} -FWL_Error CFX_Path::MoveTo(const CFX_PointF& point) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->MoveTo(point); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::LineTo(const CFX_PointF& point) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->LineTo(point); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::BezierTo(const CFX_PointF& c1, - const CFX_PointF& c2, - const CFX_PointF& to) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->BezierTo(c1, c2, to); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::ArcTo(const CFX_PointF& pos, - const CFX_SizeF& size, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - CFX_SizeF newSize = size / 2.0f; - m_generator->ArcTo(CFX_PointF(pos.x + newSize.width, pos.y + newSize.height), - newSize, startAngle, sweepAngle); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::Close() { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->Close(); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddLine(const CFX_PointF& p1, const CFX_PointF& p2) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddLine(p1, p2); - return FWL_Error::Succeeded; +void CFX_Path::Clear() { + data_.Clear(); } -FWL_Error CFX_Path::AddBezier(const CFX_PointF& p1, - const CFX_PointF& c1, - const CFX_PointF& c2, - const CFX_PointF& p2) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddBezier(p1, c1, c2, p2); - return FWL_Error::Succeeded; +void CFX_Path::Close() { + data_.ClosePath(); } -FWL_Error CFX_Path::AddRectangle(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddRectangle(left, top, left + width, top + height); - return FWL_Error::Succeeded; +void CFX_Path::MoveTo(const CFX_PointF& point) { + data_.AppendPoint(point, FXPT_TYPE::MoveTo, false); } -FWL_Error CFX_Path::AddEllipse(const CFX_PointF& pos, const CFX_SizeF& size) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - CFX_SizeF newSize = size / 2.0f; - m_generator->AddEllipse( - CFX_PointF(pos.x + newSize.width, pos.y + newSize.height), newSize); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddEllipse(const CFX_RectF& rect) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddEllipse( - CFX_PointF(rect.left + rect.Width() / 2, rect.top + rect.Height() / 2), - CFX_SizeF(rect.Width() / 2, rect.Height() / 2)); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddArc(const CFX_PointF& pos, - const CFX_SizeF& size, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - CFX_SizeF newSize = size / 2; - m_generator->AddArc(CFX_PointF(pos.x + newSize.width, pos.y + newSize.height), - newSize, startAngle, sweepAngle); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddPie(const CFX_PointF& pos, - const CFX_SizeF& size, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - CFX_SizeF newSize = size / 2; - m_generator->AddPie(CFX_PointF(pos.x + newSize.width, pos.y + newSize.height), - newSize, startAngle, sweepAngle); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddSubpath(CFX_Path* path) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddPathData(path->GetPathData()); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::Clear() { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->GetPathData()->Clear(); - return FWL_Error::Succeeded; -} - -bool CFX_Path::IsEmpty() const { - if (!m_generator) - return false; - if (m_generator->GetPathData()->GetPoints().empty()) - return true; - return false; -} +void CFX_Path::LineTo(const CFX_PointF& point) { + data_.AppendPoint(point, FXPT_TYPE::LineTo, false); +} + +void CFX_Path::BezierTo(const CFX_PointF& c1, + const CFX_PointF& c2, + const CFX_PointF& to) { + data_.AppendPoint(c1, FXPT_TYPE::BezierTo, false); + data_.AppendPoint(c2, FXPT_TYPE::BezierTo, false); + data_.AppendPoint(to, FXPT_TYPE::BezierTo, false); +} + +void CFX_Path::ArcTo(const CFX_PointF& pos, + const CFX_SizeF& size, + FX_FLOAT start_angle, + FX_FLOAT sweep_angle) { + CFX_SizeF new_size = size / 2.0f; + ArcToInternal(CFX_PointF(pos.x + new_size.width, pos.y + new_size.height), + new_size, start_angle, sweep_angle); +} -CFX_PathData* CFX_Path::GetPathData() const { - if (!m_generator) - return nullptr; - return m_generator->GetPathData(); +void CFX_Path::ArcToInternal(const CFX_PointF& pos, + const CFX_SizeF& size, + FX_FLOAT start_angle, + FX_FLOAT sweep_angle) { + FX_FLOAT x0 = FXSYS_cos(sweep_angle / 2); + FX_FLOAT y0 = FXSYS_sin(sweep_angle / 2); + FX_FLOAT tx = ((1.0f - x0) * 4) / (3 * 1.0f); + FX_FLOAT ty = y0 - ((tx * x0) / y0); + + CFX_PointF points[] = {CFX_PointF(x0 + tx, -ty), CFX_PointF(x0 + tx, ty)}; + FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2); + FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2); + + CFX_PointF bezier; + bezier.x = pos.x + (size.width * ((points[0].x * cs) - (points[0].y * sn))); + bezier.y = pos.y + (size.height * ((points[0].x * sn) + (points[0].y * cs))); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); + + bezier.x = pos.x + (size.width * ((points[1].x * cs) - (points[1].y * sn))); + bezier.y = pos.y + (size.height * ((points[1].x * sn) + (points[1].y * cs))); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); + + bezier.x = pos.x + (size.width * FXSYS_cos(start_angle + sweep_angle)); + bezier.y = pos.y + (size.height * FXSYS_sin(start_angle + sweep_angle)); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); +} + +void CFX_Path::AddLine(const CFX_PointF& p1, const CFX_PointF& p2) { + data_.AppendPoint(p1, FXPT_TYPE::MoveTo, false); + data_.AppendPoint(p2, FXPT_TYPE::LineTo, false); +} + +void CFX_Path::AddRectangle(FX_FLOAT left, + FX_FLOAT top, + FX_FLOAT width, + FX_FLOAT height) { + data_.AppendRect(left, top, left + width, top + height); +} + +void CFX_Path::AddEllipse(const CFX_RectF& rect) { + AddArc(rect.TopLeft(), rect.Size(), 0, FX_PI * 2); +} + +void CFX_Path::AddArc(const CFX_PointF& original_pos, + const CFX_SizeF& original_size, + FX_FLOAT start_angle, + FX_FLOAT sweep_angle) { + if (sweep_angle == 0) + return; + + const FX_FLOAT bezier_arc_angle_epsilon = 0.01f; + while (start_angle > FX_PI * 2) + start_angle -= FX_PI * 2; + while (start_angle < 0) + start_angle += FX_PI * 2; + if (sweep_angle >= FX_PI * 2) + sweep_angle = FX_PI * 2; + if (sweep_angle <= -FX_PI * 2) + sweep_angle = -FX_PI * 2; + + CFX_SizeF size = original_size / 2; + CFX_PointF pos(original_pos.x + size.width, original_pos.y + size.height); + data_.AppendPoint(pos + CFX_PointF(size.width * FXSYS_cos(start_angle), + size.height * FXSYS_sin(start_angle)), + FXPT_TYPE::MoveTo, false); + + FX_FLOAT total_sweep = 0; + FX_FLOAT local_sweep = 0; + FX_FLOAT prev_sweep = 0; + bool done = false; + do { + if (sweep_angle < 0) { + prev_sweep = total_sweep; + local_sweep = -FX_PI / 2; + total_sweep -= FX_PI / 2; + if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } else { + prev_sweep = total_sweep; + local_sweep = FX_PI / 2; + total_sweep += FX_PI / 2; + if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } + + ArcToInternal(pos, size, start_angle, local_sweep); + start_angle += local_sweep; + } while (!done); +} + +void CFX_Path::AddSubpath(CFX_Path* path) { + if (!path) + return; + data_.Append(&path->data_, nullptr); +} + +void CFX_Path::TransformBy(const CFX_Matrix& mt) { + data_.Transform(&mt); } |