Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: core/src/fxge/ge/fx_ge_path.cpp

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "../../../../third_party/base/numerics/safe_math.h" 7 #include "../../../../third_party/base/numerics/safe_math.h"
8 #include "../../../include/fxcrt/fx_system.h" 8 #include "../../../include/fxcrt/fx_system.h"
9 #include "../../../include/fxge/fx_ge.h" 9 #include "../../../include/fxge/fx_ge.h"
10 10
11 CFX_ClipRgn::CFX_ClipRgn(int width, int height) 11 CFX_ClipRgn::CFX_ClipRgn(int width, int height) {
12 { 12 m_Type = RectI;
13 m_Box.left = m_Box.top = 0;
14 m_Box.right = width;
15 m_Box.bottom = height;
16 }
17 CFX_ClipRgn::CFX_ClipRgn(const FX_RECT& rect) {
18 m_Type = RectI;
19 m_Box = rect;
20 }
21 CFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src) {
22 m_Type = src.m_Type;
23 m_Box = src.m_Box;
24 m_Mask = src.m_Mask;
25 }
26 CFX_ClipRgn::~CFX_ClipRgn() {}
27 void CFX_ClipRgn::Reset(const FX_RECT& rect) {
28 m_Type = RectI;
29 m_Box = rect;
30 m_Mask.SetNull();
31 }
32 void CFX_ClipRgn::IntersectRect(const FX_RECT& rect) {
33 if (m_Type == RectI) {
34 m_Box.Intersect(rect);
35 return;
36 }
37 if (m_Type == MaskF) {
38 IntersectMaskRect(rect, m_Box, m_Mask);
39 return;
40 }
41 }
42 void CFX_ClipRgn::IntersectMaskRect(FX_RECT rect,
43 FX_RECT mask_rect,
44 CFX_DIBitmapRef Mask) {
45 const CFX_DIBitmap* mask_dib = Mask;
46 m_Type = MaskF;
47 m_Box = rect;
48 m_Box.Intersect(mask_rect);
49 if (m_Box.IsEmpty()) {
13 m_Type = RectI; 50 m_Type = RectI;
14 m_Box.left = m_Box.top = 0; 51 return;
15 m_Box.right = width; 52 }
16 m_Box.bottom = height; 53 if (m_Box == mask_rect) {
17 } 54 m_Mask = Mask;
18 CFX_ClipRgn::CFX_ClipRgn(const FX_RECT& rect) 55 return;
19 { 56 }
20 m_Type = RectI; 57 CFX_DIBitmap* new_dib = m_Mask.New();
21 m_Box = rect; 58 if (!new_dib) {
22 } 59 return;
23 CFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src) 60 }
24 { 61 new_dib->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask);
25 m_Type = src.m_Type; 62 for (int row = m_Box.top; row < m_Box.bottom; row++) {
26 m_Box = src.m_Box; 63 uint8_t* dest_scan =
27 m_Mask = src.m_Mask; 64 new_dib->GetBuffer() + new_dib->GetPitch() * (row - m_Box.top);
28 } 65 uint8_t* src_scan =
29 CFX_ClipRgn::~CFX_ClipRgn() 66 mask_dib->GetBuffer() + mask_dib->GetPitch() * (row - mask_rect.top);
30 { 67 for (int col = m_Box.left; col < m_Box.right; col++) {
31 } 68 dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left];
32 void CFX_ClipRgn::Reset(const FX_RECT& rect) 69 }
33 { 70 }
34 m_Type = RectI; 71 }
35 m_Box = rect; 72 void CFX_ClipRgn::IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask) {
36 m_Mask.SetNull(); 73 const CFX_DIBitmap* mask_dib = Mask;
37 } 74 ASSERT(mask_dib->GetFormat() == FXDIB_8bppMask);
38 void CFX_ClipRgn::IntersectRect(const FX_RECT& rect) 75 FX_RECT mask_box(left, top, left + mask_dib->GetWidth(),
39 { 76 top + mask_dib->GetHeight());
40 if (m_Type == RectI) { 77 if (m_Type == RectI) {
41 m_Box.Intersect(rect); 78 IntersectMaskRect(m_Box, mask_box, Mask);
42 return; 79 return;
43 } 80 }
44 if (m_Type == MaskF) { 81 if (m_Type == MaskF) {
45 IntersectMaskRect(rect, m_Box, m_Mask); 82 FX_RECT new_box = m_Box;
46 return; 83 new_box.Intersect(mask_box);
47 } 84 if (new_box.IsEmpty()) {
48 } 85 m_Type = RectI;
49 void CFX_ClipRgn::IntersectMaskRect(FX_RECT rect, FX_RECT mask_rect, CFX_DIBitma pRef Mask) 86 m_Mask.SetNull();
50 { 87 m_Box = new_box;
51 const CFX_DIBitmap* mask_dib = Mask; 88 return;
52 m_Type = MaskF; 89 }
53 m_Box = rect; 90 CFX_DIBitmapRef new_mask;
54 m_Box.Intersect(mask_rect); 91 CFX_DIBitmap* new_dib = new_mask.New();
55 if (m_Box.IsEmpty()) {
56 m_Type = RectI;
57 return;
58 }
59 if (m_Box == mask_rect) {
60 m_Mask = Mask;
61 return;
62 }
63 CFX_DIBitmap* new_dib = m_Mask.New();
64 if (!new_dib) { 92 if (!new_dib) {
65 return; 93 return;
66 } 94 }
67 new_dib->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask); 95 new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask);
68 for (int row = m_Box.top; row < m_Box.bottom; row ++) { 96 const CFX_DIBitmap* old_dib = m_Mask;
69 uint8_t* dest_scan = new_dib->GetBuffer() + new_dib->GetPitch() * (row - m_Box.top); 97 for (int row = new_box.top; row < new_box.bottom; row++) {
70 uint8_t* src_scan = mask_dib->GetBuffer() + mask_dib->GetPitch() * (row - mask_rect.top); 98 uint8_t* old_scan =
71 for (int col = m_Box.left; col < m_Box.right; col ++) { 99 old_dib->GetBuffer() + (row - m_Box.top) * old_dib->GetPitch();
72 dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left]; 100 uint8_t* mask_scan =
101 mask_dib->GetBuffer() + (row - top) * mask_dib->GetPitch();
102 uint8_t* new_scan =
103 new_dib->GetBuffer() + (row - new_box.top) * new_dib->GetPitch();
104 for (int col = new_box.left; col < new_box.right; col++) {
105 new_scan[col - new_box.left] =
106 old_scan[col - m_Box.left] * mask_scan[col - left] / 255;
107 }
108 }
109 m_Box = new_box;
110 m_Mask = new_mask;
111 return;
112 }
113 ASSERT(FALSE);
114 }
115 CFX_PathData::CFX_PathData() {
116 m_PointCount = m_AllocCount = 0;
117 m_pPoints = NULL;
118 }
119 CFX_PathData::~CFX_PathData() {
120 if (m_pPoints) {
121 FX_Free(m_pPoints);
122 }
123 }
124 void CFX_PathData::SetPointCount(int nPoints) {
125 m_PointCount = nPoints;
126 if (m_AllocCount < nPoints) {
127 if (m_pPoints) {
128 FX_Free(m_pPoints);
129 m_pPoints = NULL;
130 }
131 m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints);
132 m_AllocCount = nPoints;
133 }
134 }
135 void CFX_PathData::AllocPointCount(int nPoints) {
136 if (m_AllocCount < nPoints) {
137 FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints);
138 if (m_PointCount) {
139 FXSYS_memcpy(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT));
140 }
141 if (m_pPoints) {
142 FX_Free(m_pPoints);
143 }
144 m_pPoints = pNewBuf;
145 m_AllocCount = nPoints;
146 }
147 }
148 CFX_PathData::CFX_PathData(const CFX_PathData& src) {
149 m_PointCount = m_AllocCount = src.m_PointCount;
150 m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount);
151 FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
152 }
153 void CFX_PathData::TrimPoints(int nPoints) {
154 if (m_PointCount <= nPoints) {
155 return;
156 }
157 SetPointCount(nPoints);
158 }
159 void CFX_PathData::AddPointCount(int addPoints) {
160 pdfium::base::CheckedNumeric<int> safe_new_count = m_PointCount;
161 safe_new_count += addPoints;
162 int new_count = safe_new_count.ValueOrDie();
163 AllocPointCount(new_count);
164 m_PointCount = new_count;
165 }
166 void CFX_PathData::Append(const CFX_PathData* pSrc,
167 const CFX_AffineMatrix* pMatrix) {
168 int old_count = m_PointCount;
169 AddPointCount(pSrc->m_PointCount);
170 FXSYS_memcpy(m_pPoints + old_count, pSrc->m_pPoints,
171 pSrc->m_PointCount * sizeof(FX_PATHPOINT));
172 if (pMatrix) {
173 for (int i = 0; i < pSrc->m_PointCount; i++) {
174 pMatrix->Transform(m_pPoints[old_count + i].m_PointX,
175 m_pPoints[old_count + i].m_PointY);
176 }
177 }
178 }
179 void CFX_PathData::SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag) {
180 ASSERT(index < m_PointCount);
181 m_pPoints[index].m_PointX = x;
182 m_pPoints[index].m_PointY = y;
183 m_pPoints[index].m_Flag = flag;
184 }
185 void CFX_PathData::AppendRect(FX_FLOAT left,
186 FX_FLOAT bottom,
187 FX_FLOAT right,
188 FX_FLOAT top) {
189 int old_count = m_PointCount;
190 AddPointCount(5);
191 FX_PATHPOINT* pPoints = m_pPoints + old_count;
192 pPoints[0].m_PointX = pPoints[1].m_PointX = pPoints[4].m_PointX = left;
193 pPoints[2].m_PointX = pPoints[3].m_PointX = right;
194 pPoints[0].m_PointY = pPoints[3].m_PointY = pPoints[4].m_PointY = bottom;
195 pPoints[1].m_PointY = pPoints[2].m_PointY = top;
196 pPoints[0].m_Flag = FXPT_MOVETO;
197 pPoints[1].m_Flag = pPoints[2].m_Flag = pPoints[3].m_Flag = FXPT_LINETO;
198 pPoints[4].m_Flag = FXPT_LINETO | FXPT_CLOSEFIGURE;
199 }
200 CFX_FloatRect CFX_PathData::GetBoundingBox() const {
201 CFX_FloatRect rect;
202 if (m_PointCount) {
203 rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY);
204 for (int i = 1; i < m_PointCount; i++) {
205 rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
206 }
207 }
208 return rect;
209 }
210 static void _UpdateLineEndPoints(CFX_FloatRect& rect,
211 FX_FLOAT start_x,
212 FX_FLOAT start_y,
213 FX_FLOAT end_x,
214 FX_FLOAT end_y,
215 FX_FLOAT hw) {
216 if (start_x == end_x) {
217 if (start_y == end_y) {
218 rect.UpdateRect(end_x + hw, end_y + hw);
219 rect.UpdateRect(end_x - hw, end_y - hw);
220 return;
221 }
222 FX_FLOAT point_y;
223 if (end_y < start_y) {
224 point_y = end_y - hw;
225 } else {
226 point_y = end_y + hw;
227 }
228 rect.UpdateRect(end_x + hw, point_y);
229 rect.UpdateRect(end_x - hw, point_y);
230 return;
231 }
232 if (start_y == end_y) {
233 FX_FLOAT point_x;
234 if (end_x < start_x) {
235 point_x = end_x - hw;
236 } else {
237 point_x = end_x + hw;
238 }
239 rect.UpdateRect(point_x, end_y + hw);
240 rect.UpdateRect(point_x, end_y - hw);
241 return;
242 }
243 FX_FLOAT dx = end_x - start_x;
244 FX_FLOAT dy = end_y - start_y;
245 FX_FLOAT ll = FXSYS_sqrt2(dx, dy);
246 FX_FLOAT mx = end_x + hw * dx / ll;
247 FX_FLOAT my = end_y + hw * dy / ll;
248 FX_FLOAT dx1 = hw * dy / ll;
249 FX_FLOAT dy1 = hw * dx / ll;
250 rect.UpdateRect(mx - dx1, my + dy1);
251 rect.UpdateRect(mx + dx1, my - dy1);
252 }
253 static void _UpdateLineJoinPoints(CFX_FloatRect& rect,
254 FX_FLOAT start_x,
255 FX_FLOAT start_y,
256 FX_FLOAT middle_x,
257 FX_FLOAT middle_y,
258 FX_FLOAT end_x,
259 FX_FLOAT end_y,
260 FX_FLOAT half_width,
261 FX_FLOAT miter_limit) {
262 FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0,
263 start_dc = 0, end_len = 0, end_dc = 0;
264 FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20;
265 FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20;
266 if (bStartVert && bEndVert) {
267 int start_dir = middle_y > start_y ? 1 : -1;
268 FX_FLOAT point_y = middle_y + half_width * start_dir;
269 rect.UpdateRect(middle_x + half_width, point_y);
270 rect.UpdateRect(middle_x - half_width, point_y);
271 return;
272 }
273 if (!bStartVert) {
274 start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x);
275 start_c = middle_y - FXSYS_Mul(start_k, middle_x);
276 start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y);
277 start_dc = (FX_FLOAT)FXSYS_fabs(
278 FXSYS_MulDiv(half_width, start_len, start_x - middle_x));
279 }
280 if (!bEndVert) {
281 end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x);
282 end_c = middle_y - FXSYS_Mul(end_k, middle_x);
283 end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y);
284 end_dc = (FX_FLOAT)FXSYS_fabs(
285 FXSYS_MulDiv(half_width, end_len, end_x - middle_x));
286 }
287 if (bStartVert) {
288 FX_FLOAT outside_x = start_x;
289 if (end_x < start_x) {
290 outside_x += half_width;
291 } else {
292 outside_x -= half_width;
293 }
294 FX_FLOAT outside_y;
295 if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
296 outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc;
297 } else {
298 outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc;
299 }
300 rect.UpdateRect(outside_x, outside_y);
301 return;
302 }
303 if (bEndVert) {
304 FX_FLOAT outside_x = end_x;
305 if (start_x < end_x) {
306 outside_x += half_width;
307 } else {
308 outside_x -= half_width;
309 }
310 FX_FLOAT outside_y;
311 if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
312 outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc;
313 } else {
314 outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc;
315 }
316 rect.UpdateRect(outside_x, outside_y);
317 return;
318 }
319 if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) {
320 int start_dir = middle_x > start_x ? 1 : -1;
321 int end_dir = end_x > middle_x ? 1 : -1;
322 if (start_dir == end_dir) {
323 _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width);
324 } else {
325 _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y,
326 half_width);
327 }
328 return;
329 }
330 FX_FLOAT start_outside_c = start_c;
331 if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
332 start_outside_c += start_dc;
333 } else {
334 start_outside_c -= start_dc;
335 }
336 FX_FLOAT end_outside_c = end_c;
337 if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
338 end_outside_c += end_dc;
339 } else {
340 end_outside_c -= end_dc;
341 }
342 FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k);
343 FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c;
344 rect.UpdateRect(join_x, join_y);
345 }
346 CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width,
347 FX_FLOAT miter_limit) const {
348 CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f,
349 -100000 * 1.0f);
350 int iPoint = 0;
351 FX_FLOAT half_width = line_width;
352 int iStartPoint, iEndPoint, iMiddlePoint;
353 FX_BOOL bJoin;
354 while (iPoint < m_PointCount) {
355 if (m_pPoints[iPoint].m_Flag == FXPT_MOVETO) {
356 iStartPoint = iPoint + 1;
357 iEndPoint = iPoint;
358 bJoin = FALSE;
359 } else {
360 if (m_pPoints[iPoint].m_Flag == FXPT_BEZIERTO) {
361 rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_PointY);
362 rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX,
363 m_pPoints[iPoint + 1].m_PointY);
364 iPoint += 2;
365 }
366 if (iPoint == m_PointCount - 1 ||
367 m_pPoints[iPoint + 1].m_Flag == FXPT_MOVETO) {
368 iStartPoint = iPoint - 1;
369 iEndPoint = iPoint;
370 bJoin = FALSE;
371 } else {
372 iStartPoint = iPoint - 1;
373 iMiddlePoint = iPoint;
374 iEndPoint = iPoint + 1;
375 bJoin = TRUE;
376 }
377 }
378 FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX;
379 FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY;
380 FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX;
381 FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY;
382 if (bJoin) {
383 FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX;
384 FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY;
385 _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, end_x,
386 end_y, half_width, miter_limit);
387 } else {
388 _UpdateLineEndPoints(rect, start_x, start_y, end_x, end_y, half_width);
389 }
390 iPoint++;
391 }
392 return rect;
393 }
394 void CFX_PathData::Transform(const CFX_AffineMatrix* pMatrix) {
395 if (pMatrix == NULL) {
396 return;
397 }
398 for (int i = 0; i < m_PointCount; i++) {
399 pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
400 }
401 }
402 FX_BOOL CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath,
403 CFX_AffineMatrix* pMatrix,
404 FX_BOOL& bThin,
405 FX_BOOL bAdjust) const {
406 if (m_PointCount < 3) {
407 return FALSE;
408 }
409 if (m_PointCount == 3 && (m_pPoints[0].m_Flag & FXPT_TYPE) == FXPT_MOVETO &&
410 (m_pPoints[1].m_Flag & FXPT_TYPE) == FXPT_LINETO &&
411 (m_pPoints[2].m_Flag & FXPT_TYPE) == FXPT_LINETO &&
412 m_pPoints[0].m_PointX == m_pPoints[2].m_PointX &&
413 m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) {
414 NewPath.AddPointCount(2);
415 if (bAdjust) {
416 if (pMatrix) {
417 FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY;
418 pMatrix->TransformPoint(x, y);
419 x = (int)x + 0.5f;
420 y = (int)y + 0.5f;
421 NewPath.SetPoint(0, x, y, FXPT_MOVETO);
422 x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY;
423 pMatrix->TransformPoint(x, y);
424 x = (int)x + 0.5f;
425 y = (int)y + 0.5f;
426 NewPath.SetPoint(1, x, y, FXPT_LINETO);
427 pMatrix->SetIdentity();
428 } else {
429 FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f,
430 y = (int)m_pPoints[0].m_PointY + 0.5f;
431 NewPath.SetPoint(0, x, y, FXPT_MOVETO);
432 x = (int)m_pPoints[1].m_PointX + 0.5f,
433 y = (int)m_pPoints[1].m_PointY + 0.5f;
434 NewPath.SetPoint(1, x, y, FXPT_LINETO);
435 }
436 } else {
437 NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY,
438 FXPT_MOVETO);
439 NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY,
440 FXPT_LINETO);
441 }
442 if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX &&
443 m_pPoints[0].m_PointY != m_pPoints[1].m_PointY) {
444 bThin = TRUE;
445 }
446 return TRUE;
447 }
448 if (((m_PointCount > 3) && (m_PointCount % 2))) {
449 int mid = m_PointCount / 2;
450 FX_BOOL bZeroArea = FALSE;
451 CFX_PathData t_path;
452 for (int i = 0; i < mid; i++) {
453 if (!(m_pPoints[mid - i - 1].m_PointX ==
454 m_pPoints[mid + i + 1].m_PointX &&
455 m_pPoints[mid - i - 1].m_PointY ==
456 m_pPoints[mid + i + 1].m_PointY &&
457 ((m_pPoints[mid - i - 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO &&
458 (m_pPoints[mid + i + 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO))) {
459 bZeroArea = TRUE;
460 break;
461 }
462 int new_count = t_path.GetPointCount();
463 t_path.AddPointCount(2);
464 t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX,
465 m_pPoints[mid - i].m_PointY, FXPT_MOVETO);
466 t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX,
467 m_pPoints[mid - i - 1].m_PointY, FXPT_LINETO);
468 }
469 if (!bZeroArea) {
470 NewPath.Append(&t_path, NULL);
471 bThin = TRUE;
472 return TRUE;
473 }
474 }
475 int stratPoint = 0;
476 int next = 0, i;
477 for (i = 0; i < m_PointCount; i++) {
478 int point_type = m_pPoints[i].m_Flag & FXPT_TYPE;
479 if (point_type == FXPT_MOVETO) {
480 stratPoint = i;
481 } else if (point_type == FXPT_LINETO) {
482 next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoint;
483 if ((m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO &&
484 (m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_MOVETO) {
485 if ((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX &&
486 m_pPoints[i].m_PointX == m_pPoints[next].m_PointX) &&
487 ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) *
488 (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) >
489 0)) {
490 int pre = i;
491 if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) <
492 FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next].m_PointY)) {
493 pre--;
494 next--;
495 }
496 int new_count = NewPath.GetPointCount();
497 NewPath.AddPointCount(2);
498 NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX,
499 m_pPoints[pre].m_PointY, FXPT_MOVETO);
500 NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX,
501 m_pPoints[next].m_PointY, FXPT_LINETO);
502 } else if ((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY &&
503 m_pPoints[i].m_PointY == m_pPoints[next].m_PointY) &&
504 ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) *
505 (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) >
506 0)) {
507 int pre = i;
508 if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) <
509 FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next].m_PointX)) {
510 pre--;
511 next--;
512 }
513 int new_count = NewPath.GetPointCount();
514 NewPath.AddPointCount(2);
515 NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX,
516 m_pPoints[pre].m_PointY, FXPT_MOVETO);
517 NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX,
518 m_pPoints[next].m_PointY, FXPT_LINETO);
519 } else if ((m_pPoints[i - 1].m_Flag & FXPT_TYPE) == FXPT_MOVETO &&
520 (m_pPoints[next].m_Flag & FXPT_TYPE) == FXPT_LINETO &&
521 m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX &&
522 m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY &&
523 m_pPoints[next].m_Flag & FXPT_CLOSEFIGURE) {
524 int new_count = NewPath.GetPointCount();
525 NewPath.AddPointCount(2);
526 NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX,
527 m_pPoints[i - 1].m_PointY, FXPT_MOVETO);
528 NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX,
529 m_pPoints[i].m_PointY, FXPT_LINETO);
530 bThin = TRUE;
73 } 531 }
74 } 532 }
75 } 533 } else if (point_type == FXPT_BEZIERTO) {
76 void CFX_ClipRgn::IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask) 534 i += 2;
77 { 535 continue;
78 const CFX_DIBitmap* mask_dib = Mask; 536 }
79 ASSERT(mask_dib->GetFormat() == FXDIB_8bppMask); 537 }
80 FX_RECT mask_box(left, top, left + mask_dib->GetWidth(), top + mask_dib->Get Height()); 538 if (m_PointCount > 3 && NewPath.GetPointCount()) {
81 if (m_Type == RectI) { 539 bThin = TRUE;
82 IntersectMaskRect(m_Box, mask_box, Mask); 540 }
83 return; 541 if (NewPath.GetPointCount() == 0) {
84 } 542 return FALSE;
85 if (m_Type == MaskF) { 543 }
86 FX_RECT new_box = m_Box; 544 return TRUE;
87 new_box.Intersect(mask_box); 545 }
88 if (new_box.IsEmpty()) { 546 FX_BOOL CFX_PathData::IsRect() const {
89 m_Type = RectI; 547 if (m_PointCount != 5 && m_PointCount != 4) {
90 m_Mask.SetNull(); 548 return FALSE;
91 m_Box = new_box; 549 }
92 return; 550 if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX ||
93 } 551 m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
94 CFX_DIBitmapRef new_mask; 552 (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX &&
95 CFX_DIBitmap* new_dib = new_mask.New(); 553 m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) ||
96 if (!new_dib) { 554 (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX &&
97 return; 555 m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
98 } 556 return FALSE;
99 new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask); 557 }
100 const CFX_DIBitmap* old_dib = m_Mask; 558 if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX &&
101 for (int row = new_box.top; row < new_box.bottom; row ++) { 559 m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
102 uint8_t* old_scan = old_dib->GetBuffer() + (row - m_Box.top) * old_d ib->GetPitch(); 560 return FALSE;
103 uint8_t* mask_scan = mask_dib->GetBuffer() + (row - top) * mask_dib- >GetPitch(); 561 }
104 uint8_t* new_scan = new_dib->GetBuffer() + (row - new_box.top) * new _dib->GetPitch(); 562 for (int i = 1; i < 4; i++) {
105 for (int col = new_box.left; col < new_box.right; col ++) { 563 if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) {
106 new_scan[col - new_box.left] = old_scan[col - m_Box.left] * mask _scan[col - left] / 255; 564 return FALSE;
107 } 565 }
108 } 566 if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX &&
109 m_Box = new_box; 567 m_pPoints[i].m_PointY != m_pPoints[i - 1].m_PointY) {
110 m_Mask = new_mask; 568 return FALSE;
111 return; 569 }
112 } 570 }
113 ASSERT(FALSE); 571 return m_PointCount == 5 || (m_pPoints[3].m_Flag & FXPT_CLOSEFIGURE);
114 } 572 }
115 CFX_PathData::CFX_PathData() 573 FX_BOOL CFX_PathData::IsRect(const CFX_AffineMatrix* pMatrix,
116 { 574 CFX_FloatRect* pRect) const {
117 m_PointCount = m_AllocCount = 0; 575 if (pMatrix == NULL) {
118 m_pPoints = NULL; 576 if (!IsRect()) {
119 } 577 return FALSE;
120 CFX_PathData::~CFX_PathData() 578 }
121 { 579 if (pRect) {
122 if (m_pPoints) { 580 pRect->left = m_pPoints[0].m_PointX;
123 FX_Free(m_pPoints); 581 pRect->right = m_pPoints[2].m_PointX;
124 } 582 pRect->bottom = m_pPoints[0].m_PointY;
125 } 583 pRect->top = m_pPoints[2].m_PointY;
126 void CFX_PathData::SetPointCount(int nPoints) 584 pRect->Normalize();
127 { 585 }
128 m_PointCount = nPoints; 586 return TRUE;
129 if (m_AllocCount < nPoints) { 587 }
130 if (m_pPoints) { 588 if (m_PointCount != 5 && m_PointCount != 4) {
131 FX_Free(m_pPoints); 589 return FALSE;
132 m_pPoints = NULL; 590 }
133 } 591 if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX ||
134 m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints); 592 m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
135 m_AllocCount = nPoints; 593 (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX &&
136 } 594 m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
137 } 595 return FALSE;
138 void CFX_PathData::AllocPointCount(int nPoints) 596 }
139 { 597 if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX &&
140 if (m_AllocCount < nPoints) { 598 m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
141 FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints); 599 return FALSE;
142 if (m_PointCount) { 600 }
143 FXSYS_memcpy(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT) ); 601 FX_FLOAT x[5], y[5];
144 } 602 for (int i = 0; i < m_PointCount; i++) {
145 if (m_pPoints) { 603 pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, x[i],
146 FX_Free(m_pPoints); 604 y[i]);
147 } 605 if (i) {
148 m_pPoints = pNewBuf; 606 if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) {
149 m_AllocCount = nPoints;
150 }
151 }
152 CFX_PathData::CFX_PathData(const CFX_PathData& src)
153 {
154 m_PointCount = m_AllocCount = src.m_PointCount;
155 m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount);
156 FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
157 }
158 void CFX_PathData::TrimPoints(int nPoints)
159 {
160 if (m_PointCount <= nPoints) {
161 return;
162 }
163 SetPointCount(nPoints);
164 }
165 void CFX_PathData::AddPointCount(int addPoints)
166 {
167 pdfium::base::CheckedNumeric<int> safe_new_count = m_PointCount;
168 safe_new_count += addPoints;
169 int new_count = safe_new_count.ValueOrDie();
170 AllocPointCount(new_count);
171 m_PointCount = new_count;
172 }
173 void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_AffineMatrix* pMat rix)
174 {
175 int old_count = m_PointCount;
176 AddPointCount(pSrc->m_PointCount);
177 FXSYS_memcpy(m_pPoints + old_count, pSrc->m_pPoints, pSrc->m_PointCount * si zeof(FX_PATHPOINT));
178 if (pMatrix) {
179 for (int i = 0; i < pSrc->m_PointCount; i ++) {
180 pMatrix->Transform(m_pPoints[old_count + i].m_PointX, m_pPoints[old_ count + i].m_PointY);
181 }
182 }
183 }
184 void CFX_PathData::SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag)
185 {
186 ASSERT(index < m_PointCount);
187 m_pPoints[index].m_PointX = x;
188 m_pPoints[index].m_PointY = y;
189 m_pPoints[index].m_Flag = flag;
190 }
191 void CFX_PathData::AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX _FLOAT top)
192 {
193 int old_count = m_PointCount;
194 AddPointCount(5);
195 FX_PATHPOINT* pPoints = m_pPoints + old_count;
196 pPoints[0].m_PointX = pPoints[1].m_PointX = pPoints[4].m_PointX = left;
197 pPoints[2].m_PointX = pPoints[3].m_PointX = right;
198 pPoints[0].m_PointY = pPoints[3].m_PointY = pPoints[4].m_PointY = bottom;
199 pPoints[1].m_PointY = pPoints[2].m_PointY = top;
200 pPoints[0].m_Flag = FXPT_MOVETO;
201 pPoints[1].m_Flag = pPoints[2].m_Flag = pPoints[3].m_Flag = FXPT_LINETO;
202 pPoints[4].m_Flag = FXPT_LINETO | FXPT_CLOSEFIGURE;
203 }
204 CFX_FloatRect CFX_PathData::GetBoundingBox() const
205 {
206 CFX_FloatRect rect;
207 if (m_PointCount) {
208 rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY);
209 for (int i = 1; i < m_PointCount; i ++) {
210 rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
211 }
212 }
213 return rect;
214 }
215 static void _UpdateLineEndPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y, FX_FLOAT end_x, FX_FLOAT end_y,
216 FX_FLOAT hw)
217 {
218 if (start_x == end_x) {
219 if (start_y == end_y) {
220 rect.UpdateRect(end_x + hw, end_y + hw);
221 rect.UpdateRect(end_x - hw, end_y - hw);
222 return;
223 }
224 FX_FLOAT point_y;
225 if (end_y < start_y) {
226 point_y = end_y - hw;
227 } else {
228 point_y = end_y + hw;
229 }
230 rect.UpdateRect(end_x + hw, point_y);
231 rect.UpdateRect(end_x - hw, point_y);
232 return;
233 }
234 if (start_y == end_y) {
235 FX_FLOAT point_x;
236 if (end_x < start_x) {
237 point_x = end_x - hw;
238 } else {
239 point_x = end_x + hw;
240 }
241 rect.UpdateRect(point_x, end_y + hw);
242 rect.UpdateRect(point_x, end_y - hw);
243 return;
244 }
245 FX_FLOAT dx = end_x - start_x;
246 FX_FLOAT dy = end_y - start_y;
247 FX_FLOAT ll = FXSYS_sqrt2(dx, dy);
248 FX_FLOAT mx = end_x + hw * dx / ll;
249 FX_FLOAT my = end_y + hw * dy / ll;
250 FX_FLOAT dx1 = hw * dy / ll;
251 FX_FLOAT dy1 = hw * dx / ll;
252 rect.UpdateRect(mx - dx1, my + dy1);
253 rect.UpdateRect(mx + dx1, my - dy1);
254 }
255 static void _UpdateLineJoinPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOA T start_y,
256 FX_FLOAT middle_x, FX_FLOAT middle_y, FX_FLOAT end_x, FX_FLOAT end_y,
257 FX_FLOAT half_width, FX_FLOAT miter_limit)
258 {
259 FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0, star t_dc = 0, end_len = 0, end_dc = 0;
260 FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20;
261 FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20;
262 if (bStartVert && bEndVert) {
263 int start_dir = middle_y > start_y ? 1 : -1;
264 FX_FLOAT point_y = middle_y + half_width * start_dir;
265 rect.UpdateRect(middle_x + half_width, point_y);
266 rect.UpdateRect(middle_x - half_width, point_y);
267 return;
268 }
269 if (!bStartVert) {
270 start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x);
271 start_c = middle_y - FXSYS_Mul(start_k, middle_x);
272 start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y);
273 start_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, start_len, star t_x - middle_x));
274 }
275 if (!bEndVert) {
276 end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x);
277 end_c = middle_y - FXSYS_Mul(end_k, middle_x);
278 end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y);
279 end_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, end_len, end_x - middle_x));
280 }
281 if (bStartVert) {
282 FX_FLOAT outside_x = start_x;
283 if (end_x < start_x) {
284 outside_x += half_width;
285 } else {
286 outside_x -= half_width;
287 }
288 FX_FLOAT outside_y;
289 if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
290 outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc;
291 } else {
292 outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc;
293 }
294 rect.UpdateRect(outside_x, outside_y);
295 return;
296 }
297 if (bEndVert) {
298 FX_FLOAT outside_x = end_x;
299 if (start_x < end_x) {
300 outside_x += half_width;
301 } else {
302 outside_x -= half_width;
303 }
304 FX_FLOAT outside_y;
305 if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
306 outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc;
307 } else {
308 outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc;
309 }
310 rect.UpdateRect(outside_x, outside_y);
311 return;
312 }
313 if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) {
314 int start_dir = middle_x > start_x ? 1 : -1;
315 int end_dir = end_x > middle_x ? 1 : -1;
316 if (start_dir == end_dir) {
317 _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_wi dth);
318 } else {
319 _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y, hal f_width);
320 }
321 return;
322 }
323 FX_FLOAT start_outside_c = start_c;
324 if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
325 start_outside_c += start_dc;
326 } else {
327 start_outside_c -= start_dc;
328 }
329 FX_FLOAT end_outside_c = end_c;
330 if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
331 end_outside_c += end_dc;
332 } else {
333 end_outside_c -= end_dc;
334 }
335 FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k );
336 FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c;
337 rect.UpdateRect(join_x, join_y);
338 }
339 CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_l imit) const
340 {
341 CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f, -100000 * 1 .0f);
342 int iPoint = 0;
343 FX_FLOAT half_width = line_width;
344 int iStartPoint, iEndPoint, iMiddlePoint;
345 FX_BOOL bJoin;
346 while (iPoint < m_PointCount) {
347 if (m_pPoints[iPoint].m_Flag == FXPT_MOVETO) {
348 iStartPoint = iPoint + 1;
349 iEndPoint = iPoint;
350 bJoin = FALSE;
351 } else {
352 if (m_pPoints[iPoint].m_Flag == FXPT_BEZIERTO) {
353 rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_ PointY);
354 rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX, m_pPoints[iPoint + 1].m_PointY);
355 iPoint += 2;
356 }
357 if (iPoint == m_PointCount - 1 || m_pPoints[iPoint + 1].m_Flag == FX PT_MOVETO) {
358 iStartPoint = iPoint - 1;
359 iEndPoint = iPoint;
360 bJoin = FALSE;
361 } else {
362 iStartPoint = iPoint - 1;
363 iMiddlePoint = iPoint;
364 iEndPoint = iPoint + 1;
365 bJoin = TRUE;
366 }
367 }
368 FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX;
369 FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY;
370 FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX;
371 FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY;
372 if (bJoin) {
373 FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX;
374 FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY;
375 _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, en d_x, end_y, half_width, miter_limit);
376 } else {
377 _UpdateLineEndPoints(rect, start_x, start_y, end_x, end_y, half_widt h);
378 }
379 iPoint ++;
380 }
381 return rect;
382 }
383 void CFX_PathData::Transform(const CFX_AffineMatrix* pMatrix)
384 {
385 if (pMatrix == NULL) {
386 return;
387 }
388 for (int i = 0; i < m_PointCount; i ++) {
389 pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
390 }
391 }
392 FX_BOOL CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath, CFX_AffineMatrix* p Matrix, FX_BOOL&bThin, FX_BOOL bAdjust) const
393 {
394 if (m_PointCount < 3) {
395 return FALSE; 607 return FALSE;
396 } 608 }
397 if (m_PointCount == 3 && (m_pPoints[0].m_Flag & FXPT_TYPE) == FXPT_MOVETO && 609 if (x[i] != x[i - 1] && y[i] != y[i - 1]) {
398 (m_pPoints[1].m_Flag & FXPT_TYPE) == FXPT_LINETO && (m_pPoints[2].m_ Flag & FXPT_TYPE) == FXPT_LINETO
399 && m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_ PointY == m_pPoints[2].m_PointY) {
400 NewPath.AddPointCount(2);
401 if (bAdjust) {
402 if (pMatrix) {
403 FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY;
404 pMatrix->TransformPoint(x, y);
405 x = (int)x + 0.5f;
406 y = (int)y + 0.5f;
407 NewPath.SetPoint(0, x, y, FXPT_MOVETO);
408 x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY;
409 pMatrix->TransformPoint(x, y);
410 x = (int)x + 0.5f;
411 y = (int)y + 0.5f;
412 NewPath.SetPoint(1, x, y, FXPT_LINETO);
413 pMatrix->SetIdentity();
414 } else {
415 FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f, y = (int)m_pPoin ts[0].m_PointY + 0.5f;
416 NewPath.SetPoint(0, x, y, FXPT_MOVETO);
417 x = (int)m_pPoints[1].m_PointX + 0.5f, y = (int)m_pPoints[1].m_P ointY + 0.5f;
418 NewPath.SetPoint(1, x, y, FXPT_LINETO);
419 }
420 } else {
421 NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY, FX PT_MOVETO);
422 NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY, FX PT_LINETO);
423 }
424 if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX && m_pPoints[0].m_Poi ntY != m_pPoints[1].m_PointY) {
425 bThin = TRUE;
426 }
427 return TRUE;
428 }
429 if (((m_PointCount > 3) && (m_PointCount % 2))) {
430 int mid = m_PointCount / 2;
431 FX_BOOL bZeroArea = FALSE;
432 CFX_PathData t_path;
433 for (int i = 0; i < mid; i++) {
434 if (!(m_pPoints[mid - i - 1].m_PointX == m_pPoints[mid + i + 1].m_Po intX
435 && m_pPoints[mid - i - 1].m_PointY == m_pPoints[mid + i + 1] .m_PointY &&
436 ((m_pPoints[mid - i - 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERT O && (m_pPoints[mid + i + 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO))) {
437 bZeroArea = TRUE;
438 break;
439 }
440 int new_count = t_path.GetPointCount();
441 t_path.AddPointCount(2);
442 t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX, m_pPoints[mi d - i].m_PointY, FXPT_MOVETO);
443 t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX, m_pP oints[mid - i - 1].m_PointY, FXPT_LINETO);
444 }
445 if (!bZeroArea) {
446 NewPath.Append(&t_path, NULL);
447 bThin = TRUE;
448 return TRUE;
449 }
450 }
451 int stratPoint = 0;
452 int next = 0, i;
453 for (i = 0; i < m_PointCount; i++) {
454 int point_type = m_pPoints[i].m_Flag & FXPT_TYPE;
455 if (point_type == FXPT_MOVETO) {
456 stratPoint = i;
457 } else if (point_type == FXPT_LINETO) {
458 next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoi nt;
459 if ((m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoi nts[next].m_Flag & FXPT_TYPE) != FXPT_MOVETO) {
460 if((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX && m_pPoi nts[i].m_PointX == m_pPoints[next].m_PointX)
461 && ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) * (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) > 0)) {
462 int pre = i;
463 if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_Po intY)
464 < FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next] .m_PointY)) {
465 pre --;
466 next--;
467 }
468 int new_count = NewPath.GetPointCount();
469 NewPath.AddPointCount(2);
470 NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoin ts[pre].m_PointY, FXPT_MOVETO);
471 NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_ pPoints[next].m_PointY, FXPT_LINETO);
472 } else if((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY && m_pPoints[i].m_PointY == m_pPoints[next].m_PointY)
473 && ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX ) * (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) > 0)) {
474 int pre = i;
475 if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_Po intX)
476 < FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next] .m_PointX)) {
477 pre --;
478 next--;
479 }
480 int new_count = NewPath.GetPointCount();
481 NewPath.AddPointCount(2);
482 NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoin ts[pre].m_PointY, FXPT_MOVETO);
483 NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_ pPoints[next].m_PointY, FXPT_LINETO);
484 } else if ((m_pPoints[i - 1].m_Flag & FXPT_TYPE) == FXPT_MOVETO && (m_pPoints[next].m_Flag & FXPT_TYPE) == FXPT_LINETO &&
485 m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX && m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY
486 && m_pPoints[next].m_Flag & FXPT_CLOSEFIGURE) {
487 int new_count = NewPath.GetPointCount();
488 NewPath.AddPointCount(2);
489 NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX, m_pPo ints[i - 1].m_PointY, FXPT_MOVETO);
490 NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX, m_pPo ints[i].m_PointY, FXPT_LINETO);
491 bThin = TRUE;
492 }
493 }
494 } else if (point_type == FXPT_BEZIERTO) {
495 i += 2;
496 continue;
497 }
498 }
499 if (m_PointCount > 3 && NewPath.GetPointCount()) {
500 bThin = TRUE;
501 }
502 if (NewPath.GetPointCount() == 0) {
503 return FALSE; 610 return FALSE;
504 } 611 }
505 return TRUE; 612 }
506 } 613 }
507 FX_BOOL CFX_PathData::IsRect() const 614 if (pRect) {
508 { 615 pRect->left = x[0];
509 if (m_PointCount != 5 && m_PointCount != 4) { 616 pRect->right = x[2];
510 return FALSE; 617 pRect->bottom = y[0];
511 } 618 pRect->top = y[2];
512 if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || 619 pRect->Normalize();
513 m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) || 620 }
514 (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_Po intY == m_pPoints[2].m_PointY) || 621 return TRUE;
515 (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_Po intY == m_pPoints[3].m_PointY)) { 622 }
516 return FALSE; 623 void CFX_PathData::Copy(const CFX_PathData& src) {
517 } 624 SetPointCount(src.m_PointCount);
518 if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) { 625 FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
519 return FALSE; 626 }
520 } 627 CFX_GraphStateData::CFX_GraphStateData() {
521 for (int i = 1; i < 4; i ++) { 628 m_LineCap = LineCapButt;
522 if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) { 629 m_DashCount = 0;
523 return FALSE; 630 m_DashArray = NULL;
524 } 631 m_DashPhase = 0;
525 if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX && m_pPoints[i].m _PointY != m_pPoints[i - 1].m_PointY) { 632 m_LineJoin = LineJoinMiter;
526 return FALSE; 633 m_MiterLimit = 10 * 1.0f;
527 } 634 m_LineWidth = 1.0f;
528 } 635 }
529 return m_PointCount == 5 || (m_pPoints[3].m_Flag & FXPT_CLOSEFIGURE); 636 CFX_GraphStateData::CFX_GraphStateData(const CFX_GraphStateData& src) {
530 } 637 m_DashArray = NULL;
531 FX_BOOL CFX_PathData::IsRect(const CFX_AffineMatrix* pMatrix, CFX_FloatRect* pRe ct) const 638 Copy(src);
532 { 639 }
533 if (pMatrix == NULL) { 640 void CFX_GraphStateData::Copy(const CFX_GraphStateData& src) {
534 if (!IsRect()) { 641 m_LineCap = src.m_LineCap;
535 return FALSE; 642 m_DashCount = src.m_DashCount;
536 } 643 if (m_DashArray) {
537 if (pRect) { 644 FX_Free(m_DashArray);
538 pRect->left = m_pPoints[0].m_PointX; 645 }
539 pRect->right = m_pPoints[2].m_PointX; 646 m_DashArray = NULL;
540 pRect->bottom = m_pPoints[0].m_PointY; 647 m_DashPhase = src.m_DashPhase;
541 pRect->top = m_pPoints[2].m_PointY; 648 m_LineJoin = src.m_LineJoin;
542 pRect->Normalize(); 649 m_MiterLimit = src.m_MiterLimit;
543 } 650 m_LineWidth = src.m_LineWidth;
544 return TRUE; 651 if (m_DashCount) {
545 } 652 m_DashArray = FX_Alloc(FX_FLOAT, m_DashCount);
546 if (m_PointCount != 5 && m_PointCount != 4) { 653 FXSYS_memcpy(m_DashArray, src.m_DashArray, m_DashCount * sizeof(FX_FLOAT));
547 return FALSE; 654 }
548 } 655 }
549 if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) || 656 CFX_GraphStateData::~CFX_GraphStateData() {
550 (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_Po intY == m_pPoints[3].m_PointY)) { 657 if (m_DashArray) {
551 return FALSE; 658 FX_Free(m_DashArray);
552 } 659 }
553 if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m _pPoints[0].m_PointY != m_pPoints[3].m_PointY) { 660 }
554 return FALSE; 661 void CFX_GraphStateData::SetDashCount(int count) {
555 } 662 if (m_DashArray) {
556 FX_FLOAT x[5], y[5]; 663 FX_Free(m_DashArray);
557 for (int i = 0; i < m_PointCount; i ++) { 664 }
558 pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, x[i], y [i]); 665 m_DashArray = NULL;
559 if (i) { 666 m_DashCount = count;
560 if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) { 667 if (count == 0) {
561 return FALSE; 668 return;
562 } 669 }
563 if (x[i] != x[i - 1] && y[i] != y[i - 1]) { 670 m_DashArray = FX_Alloc(FX_FLOAT, count);
564 return FALSE; 671 }
565 }
566 }
567 }
568 if (pRect) {
569 pRect->left = x[0];
570 pRect->right = x[2];
571 pRect->bottom = y[0];
572 pRect->top = y[2];
573 pRect->Normalize();
574 }
575 return TRUE;
576 }
577 void CFX_PathData::Copy(const CFX_PathData &src)
578 {
579 SetPointCount(src.m_PointCount);
580 FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
581 }
582 CFX_GraphStateData::CFX_GraphStateData()
583 {
584 m_LineCap = LineCapButt;
585 m_DashCount = 0;
586 m_DashArray = NULL;
587 m_DashPhase = 0;
588 m_LineJoin = LineJoinMiter;
589 m_MiterLimit = 10 * 1.0f;
590 m_LineWidth = 1.0f;
591 }
592 CFX_GraphStateData::CFX_GraphStateData(const CFX_GraphStateData& src)
593 {
594 m_DashArray = NULL;
595 Copy(src);
596 }
597 void CFX_GraphStateData::Copy(const CFX_GraphStateData& src)
598 {
599 m_LineCap = src.m_LineCap;
600 m_DashCount = src.m_DashCount;
601 if (m_DashArray) {
602 FX_Free(m_DashArray);
603 }
604 m_DashArray = NULL;
605 m_DashPhase = src.m_DashPhase;
606 m_LineJoin = src.m_LineJoin;
607 m_MiterLimit = src.m_MiterLimit;
608 m_LineWidth = src.m_LineWidth;
609 if (m_DashCount) {
610 m_DashArray = FX_Alloc(FX_FLOAT, m_DashCount);
611 FXSYS_memcpy(m_DashArray, src.m_DashArray, m_DashCount * sizeof(FX_FLOAT ));
612 }
613 }
614 CFX_GraphStateData::~CFX_GraphStateData()
615 {
616 if (m_DashArray) {
617 FX_Free(m_DashArray);
618 }
619 }
620 void CFX_GraphStateData::SetDashCount(int count)
621 {
622 if (m_DashArray) {
623 FX_Free(m_DashArray);
624 }
625 m_DashArray = NULL;
626 m_DashCount = count;
627 if (count == 0) {
628 return;
629 }
630 m_DashArray = FX_Alloc(FX_FLOAT, count);
631 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698