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