1ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved. 2ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be 3ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// found in the LICENSE file. 4ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 5ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "pre.h" 8ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "fx_path_generator.h" 9ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCFX_PathGenerator::CFX_PathGenerator() { 10ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData = NULL; 11ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 12ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::Create() { 13ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData = new CFX_PathData; 14ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 15ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. MoltmannCFX_PathGenerator::~CFX_PathGenerator() { 16ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_pPathData) { 17ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann delete m_pPathData; 18ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData = NULL; 19ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 20ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 21ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::AddPathData(CFX_PathData* pPathData) { 22ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (pPathData && pPathData->GetPointCount() > 0) { 23ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int nCount = pPathData->GetPointCount(); 24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_PATHPOINT* pPoints = pPathData->GetPoints(); 25ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddPathData(pPoints, nCount); 26ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 27ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::AddPathData(FX_PATHPOINT* pPoints, int nCount) { 29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (pPoints && nCount > 0) { 30ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int nOldCount = m_pPathData->GetPointCount(); 31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(nCount); 32ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_PATHPOINT* pDstPoints = m_pPathData->GetPoints(); 33ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXSYS_memcpy(pDstPoints + nOldCount, pPoints, 34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann sizeof(FX_PATHPOINT) * nCount); 35ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 36ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 37ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::MoveTo(FX_FLOAT x, FX_FLOAT y) { 38ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(1); 39ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, FXPT_MOVETO); 40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::LineTo(FX_FLOAT x, FX_FLOAT y) { 42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(1); 43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, FXPT_LINETO); 44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 45ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::BezierTo(FX_FLOAT ctrl_x1, 46ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT ctrl_y1, 47ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT ctrl_x2, 48ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT ctrl_y2, 49ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT to_x, 50ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT to_y) { 51ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int old_count = m_pPathData->GetPointCount(); 52ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(3); 53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count, ctrl_x1, ctrl_y1, FXPT_BEZIERTO); 54ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 1, ctrl_x2, ctrl_y2, FXPT_BEZIERTO); 55ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 2, to_x, to_y, FXPT_BEZIERTO); 56ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 57ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::Close() { 58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (m_pPathData->GetPointCount() > 0) { 59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int index = m_pPathData->GetPointCount() - 1; 60ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_PATHPOINT* pPoints = m_pPathData->GetPoints(); 61ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann pPoints[index].m_Flag |= FXPT_CLOSEFIGURE; 62ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 63ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 64ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::AddLine(FX_FLOAT x1, 65ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y1, 66ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT x2, 67ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y2) { 68ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int old_count = m_pPathData->GetPointCount(); 69ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(2); 70ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count, x1, y1, FXPT_MOVETO); 71ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 1, x2, y2, FXPT_LINETO); 72ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 73ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::AddBezier(FX_FLOAT start_x, 74ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT start_y, 75ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT ctrl_x1, 76ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT ctrl_y1, 77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT ctrl_x2, 78ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT ctrl_y2, 79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT end_x, 80ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT end_y) { 81ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int old_count = m_pPathData->GetPointCount(); 82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(4); 83ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count, start_x, start_y, FXPT_MOVETO); 84ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 1, ctrl_x1, ctrl_y1, FXPT_BEZIERTO); 85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 2, ctrl_x2, ctrl_y2, FXPT_BEZIERTO); 86ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 3, end_x, end_y, FXPT_BEZIERTO); 87ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 88ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::AddRectangle(FX_FLOAT x1, 89ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y1, 90ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT x2, 91ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y2) { 92ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AppendRect(x1, y1, x2, y2); 93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 94ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::AddEllipse(FX_FLOAT x, 95ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y, 96ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT width, 97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT height) { 98ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#if 0 99ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FIXFLOAT16 k; 100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann k = fix16_to_8(fixsqrt_32_to_16(fixmul_8_8_to_32(width, width) + fixmul_8_8_to_32(height, height)) / 2); 101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int old_count = m_pPathData->GetPointCount(); 102ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(7); 103ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count, x, y - height / 2, FXPT_MOVETO); 104ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 1, x + k, y - height / 2, FXPT_BEZIERTO); 105ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 2, x + k, y + height / 2, FXPT_BEZIERTO); 106ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 3, x, y + height / 2, FXPT_BEZIERTO); 107ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 4, x - k, y + height / 2, FXPT_BEZIERTO); 108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 5, x - k, y - height / 2, FXPT_BEZIERTO); 109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 6, x, y - height / 2, FXPT_BEZIERTO); 110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#else 111ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddArc(x, y, width, height, 0, FX_PI * 2); 112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#endif 113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::ArcTo(FX_FLOAT x, 115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y, 116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT width, 117ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT height, 118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT start_angle, 119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT sweep_angle) { 120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT x0 = FXSYS_cos(sweep_angle / 2); 121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y0 = FXSYS_sin(sweep_angle / 2); 122ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT tx = FXSYS_Div((1.0f - x0) * 4, 3 * 1.0f); 123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT ty = y0 - FXSYS_Div(FXSYS_Mul(tx, x0), y0); 124ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT px[3], py[3]; 125ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann px[0] = x0 + tx; 126ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann py[0] = -ty; 127ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann px[1] = x0 + tx; 128ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann py[1] = ty; 129ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2); 130ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2); 131ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int old_count = m_pPathData->GetPointCount(); 132ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(3); 133ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT bezier_x, bezier_y; 134ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bezier_x = x + FXSYS_Mul(width, FXSYS_Mul(px[0], cs) - FXSYS_Mul(py[0], sn)); 135ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bezier_y = y + FXSYS_Mul(height, FXSYS_Mul(px[0], sn) + FXSYS_Mul(py[0], cs)); 136ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count, bezier_x, bezier_y, FXPT_BEZIERTO); 137ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bezier_x = x + FXSYS_Mul(width, FXSYS_Mul(px[1], cs) - FXSYS_Mul(py[1], sn)); 138ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bezier_y = y + FXSYS_Mul(height, FXSYS_Mul(px[1], sn) + FXSYS_Mul(py[1], cs)); 139ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 1, bezier_x, bezier_y, FXPT_BEZIERTO); 140ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bezier_x = x + FXSYS_Mul(width, FXSYS_cos(start_angle + sweep_angle)), 141ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bezier_y = y + FXSYS_Mul(height, FXSYS_sin(start_angle + sweep_angle)); 142ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count + 2, bezier_x, bezier_y, FXPT_BEZIERTO); 143ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 144ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::AddArc(FX_FLOAT x, 145ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y, 146ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT width, 147ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT height, 148ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT start_angle, 149ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT sweep_angle) { 150ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#if 0 151ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FIXFLOAT32 sweep = sweep_angle; 152ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (sweep > FIXFLOAT32_PI * 2) { 153ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann sweep -= FIXFLOAT32_PI * 2; 154ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 155ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (sweep == 0) { 156ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 157ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 158ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(1); 159ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, 160ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann x + fixmul_8_32_to_8(width, fixcos(start_angle)), 161ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann y + fixmul_8_32_to_8(height, fixsin(start_angle)), FXPT_MOVETO); 162ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FIXFLOAT32 angle1 = 0, angle2; 163ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_BOOL bDone = FALSE; 164ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann do { 165ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann angle2 = angle1 + FIXFLOAT32_PI / 2; 166ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (angle2 >= sweep) { 167ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann angle2 = sweep; 168ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann bDone = TRUE; 169ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 170ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ArcTo(x, y, width, height, start_angle + angle1, angle2 - angle1); 171ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann angle1 = angle2; 172ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } while (!bDone); 173ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#else 174ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (sweep_angle == 0) { 175ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 176ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 177ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann static const FX_FLOAT bezier_arc_angle_epsilon = (FX_FLOAT)(0.01f); 178ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (start_angle > FX_PI * 2) { 179ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann start_angle -= FX_PI * 2; 180ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 181ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann while (start_angle < 0) { 182ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann start_angle += FX_PI * 2; 183ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 184ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (sweep_angle >= FX_PI * 2) { 185ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann sweep_angle = FX_PI * 2; 186ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 187ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (sweep_angle <= -FX_PI * 2) { 188ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann sweep_angle = -FX_PI * 2; 189ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 190ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(1); 191ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, 192ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann x + FXSYS_Mul(width, FXSYS_cos(start_angle)), 193ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann y + FXSYS_Mul(height, FXSYS_sin(start_angle)), 194ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXPT_MOVETO); 195ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT total_sweep = 0, local_sweep = 0, prev_sweep = 0; 196ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_BOOL done = FALSE; 197ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann do { 198ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (sweep_angle < 0) { 199ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann prev_sweep = total_sweep; 200ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann local_sweep = -FX_PI / 2; 201ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann total_sweep -= FX_PI / 2; 202ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) { 203ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann local_sweep = sweep_angle - prev_sweep; 204ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann done = TRUE; 205ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 206ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } else { 207ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann prev_sweep = total_sweep; 208ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann local_sweep = FX_PI / 2; 209ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann total_sweep += FX_PI / 2; 210ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) { 211ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann local_sweep = sweep_angle - prev_sweep; 212ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann done = TRUE; 213ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 214ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 215ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ArcTo(x, y, width, height, start_angle, local_sweep); 216ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann start_angle += local_sweep; 217ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } while (!done); 218ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#endif 219ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 220ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmannvoid CFX_PathGenerator::AddPie(FX_FLOAT x, 221ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT y, 222ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT width, 223ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT height, 224ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT start_angle, 225ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FX_FLOAT sweep_angle) { 226ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if (sweep_angle == 0) { 227ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int old_count = m_pPathData->GetPointCount(); 228ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(2); 229ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(old_count, x, y, FXPT_MOVETO); 230ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint( 231ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann old_count + 1, x + FXSYS_Mul(width, FXSYS_cos(start_angle)), 232ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann y + FXSYS_Mul(height, FXSYS_sin(start_angle)), FXPT_LINETO); 233ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann return; 234ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } 235ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann AddArc(x, y, width, height, start_angle, sweep_angle); 236ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->AddPointCount(1); 237ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, 238ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FXPT_LINETO | FXPT_CLOSEFIGURE); 239ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann} 240