/* * (C) 2014 see Authors.txt * * This file is part of MPC-HC. * * MPC-HC is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * MPC-HC is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #pragma once #include #include #include class CEllipse { public: enum { NO_INTERSECT_OUTER = INT_MIN, NO_INTERSECT_INNER = INT_MAX, }; private: static int const NOT_CACHED = NO_INTERSECT_OUTER + 1; int m_rx = -1, m_ry = -1; int m_2rx, m_2ry; std::vector m_arc; std::vector m_intersectCache; size_t nIntersectCacheLineSize; public: CEllipse(int rx, int ry); int GetXRadius() const { return m_rx; } int GetYRadius() const { return m_ry; } int GetArc(int dy) const { return m_arc[m_ry + dy]; } int GetLeftIntersect(int dx, int dy); int GetRightIntersect(int dx, int dy) { return GetLeftIntersect(-dx, dy); } }; typedef std::shared_ptr CEllipseSharedPtr; struct EllipseCenter { int x, y; int yStopDrawing; }; struct SpanEndPoint { int x; bool bEnd; SpanEndPoint(int x, bool bEnd) : x(x) , bEnd(bEnd) {} bool operator<(const SpanEndPoint& right) const { if (x == right.x) { return (!bEnd && right.bEnd); } else { return x < right.x; } } }; class CEllipseCenterGroup { const CEllipseSharedPtr& m_pEllipse; CAtlList m_leftCenters, m_rightCenters; template void AddPoint(CAtlList& centers, IntersectFunction intersect, int x, int y); public: enum Position { BEFORE, INSIDE, AFTER }; CEllipseCenterGroup(const CEllipseSharedPtr& pEllipse) : m_pEllipse(pEllipse) {} CEllipseCenterGroup(const CEllipseCenterGroup& ellipseGroup) : m_pEllipse(ellipseGroup.m_pEllipse) { m_leftCenters.AddHeadList(&ellipseGroup.m_leftCenters); m_rightCenters.AddHeadList(&ellipseGroup.m_rightCenters); } bool IsEmpty() const { ASSERT(m_leftCenters.IsEmpty() == m_rightCenters.IsEmpty()); return m_leftCenters.IsEmpty(); } Position GetRelativePosition(int xLeft, int y); void AddSpan(int y, int xLeft, int xRight); void FlushLine(int y, std::vector& wideSpanEndPoints); };