Use override in more classes in core/
[pdfium.git] / fpdfsdk / src / pdfwindow / PWL_Utils.cpp
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 "../../include/pdfwindow/PDFWindow.h"
8 #include "../../include/pdfwindow/PWL_Wnd.h"
9 #include "../../include/pdfwindow/PWL_Utils.h"
10 #include "../../include/pdfwindow/PWL_Icon.h"
11
12 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
13 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
14 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
15 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
16
17 /* ---------------------------- CPWL_Utils ------------------------------ */
18
19 CFX_ByteString CPWL_Utils::GetAppStreamFromArray(const CPWL_PathData* pPathData,
20                                                  int32_t nCount) {
21   CFX_ByteTextBuf csAP;
22
23   for (int32_t i = 0; i < nCount; i++) {
24     switch (pPathData[i].type) {
25       case PWLPT_MOVETO:
26         csAP << pPathData[i].point.x << " " << pPathData[i].point.y << " m\n";
27         break;
28       case PWLPT_LINETO:
29         csAP << pPathData[i].point.x << " " << pPathData[i].point.y << " l\n";
30         break;
31       case PWLPT_BEZIERTO:
32         csAP << pPathData[i].point.x << " " << pPathData[i].point.y << " "
33              << pPathData[i + 1].point.x << " " << pPathData[i + 1].point.y
34              << " " << pPathData[i + 2].point.x << " "
35              << pPathData[i + 2].point.y << " c\n";
36
37         i += 2;
38         break;
39       default:
40         break;
41     }
42   }
43
44   return csAP.GetByteString();
45 }
46
47 void CPWL_Utils::GetPathDataFromArray(CFX_PathData& path,
48                                       const CPWL_PathData* pPathData,
49                                       int32_t nCount) {
50   path.SetPointCount(nCount);
51
52   for (int32_t i = 0; i < nCount; i++) {
53     switch (pPathData[i].type) {
54       case PWLPT_MOVETO:
55         path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y,
56                       FXPT_MOVETO);
57         break;
58       case PWLPT_LINETO:
59         path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y,
60                       FXPT_LINETO);
61         break;
62       case PWLPT_BEZIERTO:
63         path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y,
64                       FXPT_BEZIERTO);
65         break;
66       default:
67         break;
68     }
69   }
70 }
71
72 CPDF_Rect CPWL_Utils::MaxRect(const CPDF_Rect& rect1, const CPDF_Rect& rect2) {
73   CPDF_Rect rcRet;
74
75   rcRet.left = PWL_MIN(rect1.left, rect2.left);
76   rcRet.bottom = PWL_MIN(rect1.bottom, rect2.bottom);
77   rcRet.right = PWL_MAX(rect1.right, rect2.right);
78   rcRet.top = PWL_MAX(rect1.top, rect2.top);
79
80   return rcRet;
81 }
82
83 CPDF_Rect CPWL_Utils::OffsetRect(const CPDF_Rect& rect,
84                                  FX_FLOAT x,
85                                  FX_FLOAT y) {
86   return CPDF_Rect(rect.left + x, rect.bottom + y, rect.right + x,
87                    rect.top + y);
88 }
89
90 FX_BOOL CPWL_Utils::ContainsRect(const CPDF_Rect& rcParent,
91                                  const CPDF_Rect& rcChild) {
92   return rcChild.left >= rcParent.left && rcChild.bottom >= rcParent.bottom &&
93          rcChild.right <= rcParent.right && rcChild.top <= rcParent.top;
94 }
95
96 FX_BOOL CPWL_Utils::IntersectRect(const CPDF_Rect& rect1,
97                                   const CPDF_Rect& rect2) {
98   FX_FLOAT left = rect1.left > rect2.left ? rect1.left : rect2.left;
99   FX_FLOAT right = rect1.right < rect2.right ? rect1.right : rect2.right;
100   FX_FLOAT bottom = rect1.bottom > rect2.bottom ? rect1.bottom : rect2.bottom;
101   FX_FLOAT top = rect1.top < rect2.top ? rect1.top : rect2.top;
102
103   return left < right && bottom < top;
104 }
105
106 CPDF_Point CPWL_Utils::OffsetPoint(const CPDF_Point& point,
107                                    FX_FLOAT x,
108                                    FX_FLOAT y) {
109   return CPDF_Point(point.x + x, point.y + y);
110 }
111
112 CPVT_WordRange CPWL_Utils::OverlapWordRange(const CPVT_WordRange& wr1,
113                                             const CPVT_WordRange& wr2) {
114   CPVT_WordRange wrRet;
115
116   if (wr2.EndPos.WordCmp(wr1.BeginPos) < 0 ||
117       wr2.BeginPos.WordCmp(wr1.EndPos) > 0)
118     return wrRet;
119   if (wr1.EndPos.WordCmp(wr2.BeginPos) < 0 ||
120       wr1.BeginPos.WordCmp(wr2.EndPos) > 0)
121     return wrRet;
122
123   if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0) {
124     wrRet.BeginPos = wr2.BeginPos;
125   } else {
126     wrRet.BeginPos = wr1.BeginPos;
127   }
128
129   if (wr1.EndPos.WordCmp(wr2.EndPos) < 0) {
130     wrRet.EndPos = wr1.EndPos;
131   } else {
132     wrRet.EndPos = wr2.EndPos;
133   }
134
135   return wrRet;
136 }
137
138 CFX_ByteString CPWL_Utils::GetAP_Check(const CPDF_Rect& crBBox) {
139   CFX_ByteTextBuf csAP;
140
141   FX_FLOAT fWidth = crBBox.right - crBBox.left;
142   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
143
144   const int32_t num = 8;
145
146   CPWL_Point pts[num * 3] = {// 1
147                              CPWL_Point(0.28f, 0.52f), CPWL_Point(0.27f, 0.48f),
148                              CPWL_Point(0.29f, 0.40f),
149
150                              // 2
151                              CPWL_Point(0.30f, 0.33f), CPWL_Point(0.31f, 0.29f),
152                              CPWL_Point(0.31f, 0.28f),
153
154                              // 3
155                              CPWL_Point(0.39f, 0.28f), CPWL_Point(0.49f, 0.29f),
156                              CPWL_Point(0.77f, 0.67f),
157
158                              // 4
159                              CPWL_Point(0.76f, 0.68f), CPWL_Point(0.78f, 0.69f),
160                              CPWL_Point(0.76f, 0.75f),
161
162                              // 5
163                              CPWL_Point(0.76f, 0.75f), CPWL_Point(0.73f, 0.80f),
164                              CPWL_Point(0.68f, 0.75f),
165
166                              // 6
167                              CPWL_Point(0.68f, 0.74f), CPWL_Point(0.68f, 0.74f),
168                              CPWL_Point(0.44f, 0.47f),
169
170                              // 7
171                              CPWL_Point(0.43f, 0.47f), CPWL_Point(0.40f, 0.47f),
172                              CPWL_Point(0.41f, 0.58f),
173
174                              // 8
175                              CPWL_Point(0.40f, 0.60f), CPWL_Point(0.28f, 0.66f),
176                              CPWL_Point(0.30f, 0.56f)};
177
178   for (int32_t j = 0; j < num * 3; j++) {
179     pts[j].x *= fWidth;
180     pts[j].x += crBBox.left;
181
182     pts[j].y *= fHeight;
183     pts[j].y += crBBox.bottom;
184   }
185
186   csAP << pts[0].x << " " << pts[0].y << " m\n";
187
188   for (int32_t i = 0; i < num; i++) {
189     int32_t nCur = i * 3;
190     int32_t n1 = i * 3 + 1;
191     int32_t n2 = i * 3 + 2;
192     int32_t nNext = (i < num - 1 ? (i + 1) * 3 : 0);
193
194     FX_FLOAT px1 = pts[n1].x - pts[nCur].x;
195     FX_FLOAT py1 = pts[n1].y - pts[nCur].y;
196     FX_FLOAT px2 = pts[n2].x - pts[nNext].x;
197     FX_FLOAT py2 = pts[n2].y - pts[nNext].y;
198
199     csAP << pts[nCur].x + px1 * PWL_BEZIER << " "
200          << pts[nCur].y + py1 * PWL_BEZIER << " "
201          << pts[nNext].x + px2 * PWL_BEZIER << " "
202          << pts[nNext].y + py2 * PWL_BEZIER << " " << pts[nNext].x << " "
203          << pts[nNext].y << " c\n";
204   }
205
206   return csAP.GetByteString();
207 }
208
209 CFX_ByteString CPWL_Utils::GetAP_Circle(const CPDF_Rect& crBBox) {
210   CFX_ByteTextBuf csAP;
211
212   FX_FLOAT fWidth = crBBox.right - crBBox.left;
213   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
214
215   CPDF_Point pt1(crBBox.left, crBBox.bottom + fHeight / 2);
216   CPDF_Point pt2(crBBox.left + fWidth / 2, crBBox.top);
217   CPDF_Point pt3(crBBox.right, crBBox.bottom + fHeight / 2);
218   CPDF_Point pt4(crBBox.left + fWidth / 2, crBBox.bottom);
219
220   csAP << pt1.x << " " << pt1.y << " m\n";
221
222   FX_FLOAT px = pt2.x - pt1.x;
223   FX_FLOAT py = pt2.y - pt1.y;
224
225   csAP << pt1.x << " " << pt1.y + py * PWL_BEZIER << " "
226        << pt2.x - px * PWL_BEZIER << " " << pt2.y << " " << pt2.x << " "
227        << pt2.y << " c\n";
228
229   px = pt3.x - pt2.x;
230   py = pt2.y - pt3.y;
231
232   csAP << pt2.x + px * PWL_BEZIER << " " << pt2.y << " " << pt3.x << " "
233        << pt3.y + py * PWL_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
234
235   px = pt3.x - pt4.x;
236   py = pt3.y - pt4.y;
237
238   csAP << pt3.x << " " << pt3.y - py * PWL_BEZIER << " "
239        << pt4.x + px * PWL_BEZIER << " " << pt4.y << " " << pt4.x << " "
240        << pt4.y << " c\n";
241
242   px = pt4.x - pt1.x;
243   py = pt1.y - pt4.y;
244
245   csAP << pt4.x - px * PWL_BEZIER << " " << pt4.y << " " << pt1.x << " "
246        << pt1.y - py * PWL_BEZIER << " " << pt1.x << " " << pt1.y << " c\n";
247
248   return csAP.GetByteString();
249 }
250
251 CFX_ByteString CPWL_Utils::GetAP_Cross(const CPDF_Rect& crBBox) {
252   CFX_ByteTextBuf csAP;
253
254   csAP << crBBox.left << " " << crBBox.top << " m\n";
255   csAP << crBBox.right << " " << crBBox.bottom << " l\n";
256   csAP << crBBox.left << " " << crBBox.bottom << " m\n";
257   csAP << crBBox.right << " " << crBBox.top << " l\n";
258
259   return csAP.GetByteString();
260 }
261
262 CFX_ByteString CPWL_Utils::GetAP_Diamond(const CPDF_Rect& crBBox) {
263   CFX_ByteTextBuf csAP;
264
265   FX_FLOAT fWidth = crBBox.right - crBBox.left;
266   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
267
268   CPDF_Point pt1(crBBox.left, crBBox.bottom + fHeight / 2);
269   CPDF_Point pt2(crBBox.left + fWidth / 2, crBBox.top);
270   CPDF_Point pt3(crBBox.right, crBBox.bottom + fHeight / 2);
271   CPDF_Point pt4(crBBox.left + fWidth / 2, crBBox.bottom);
272
273   csAP << pt1.x << " " << pt1.y << " m\n";
274   csAP << pt2.x << " " << pt2.y << " l\n";
275   csAP << pt3.x << " " << pt3.y << " l\n";
276   csAP << pt4.x << " " << pt4.y << " l\n";
277   csAP << pt1.x << " " << pt1.y << " l\n";
278
279   return csAP.GetByteString();
280 }
281
282 CFX_ByteString CPWL_Utils::GetAP_Square(const CPDF_Rect& crBBox) {
283   CFX_ByteTextBuf csAP;
284
285   csAP << crBBox.left << " " << crBBox.top << " m\n";
286   csAP << crBBox.right << " " << crBBox.top << " l\n";
287   csAP << crBBox.right << " " << crBBox.bottom << " l\n";
288   csAP << crBBox.left << " " << crBBox.bottom << " l\n";
289   csAP << crBBox.left << " " << crBBox.top << " l\n";
290
291   return csAP.GetByteString();
292 }
293
294 CFX_ByteString CPWL_Utils::GetAP_Star(const CPDF_Rect& crBBox) {
295   CFX_ByteTextBuf csAP;
296
297   FX_FLOAT fRadius =
298       (crBBox.top - crBBox.bottom) / (1 + (FX_FLOAT)cos(PWL_PI / 5.0f));
299   CPDF_Point ptCenter = CPDF_Point((crBBox.left + crBBox.right) / 2.0f,
300                                    (crBBox.top + crBBox.bottom) / 2.0f);
301
302   FX_FLOAT px[5], py[5];
303
304   FX_FLOAT fAngel = PWL_PI / 10.0f;
305
306   for (int32_t i = 0; i < 5; i++) {
307     px[i] = ptCenter.x + fRadius * (FX_FLOAT)cos(fAngel);
308     py[i] = ptCenter.y + fRadius * (FX_FLOAT)sin(fAngel);
309
310     fAngel += PWL_PI * 2 / 5.0f;
311   }
312
313   csAP << px[0] << " " << py[0] << " m\n";
314
315   int32_t nNext = 0;
316   for (int32_t j = 0; j < 5; j++) {
317     nNext += 2;
318     if (nNext >= 5)
319       nNext -= 5;
320     csAP << px[nNext] << " " << py[nNext] << " l\n";
321   }
322
323   return csAP.GetByteString();
324 }
325
326 CFX_ByteString CPWL_Utils::GetAP_HalfCircle(const CPDF_Rect& crBBox,
327                                             FX_FLOAT fRotate) {
328   CFX_ByteTextBuf csAP;
329
330   FX_FLOAT fWidth = crBBox.right - crBBox.left;
331   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
332
333   CPDF_Point pt1(-fWidth / 2, 0);
334   CPDF_Point pt2(0, fHeight / 2);
335   CPDF_Point pt3(fWidth / 2, 0);
336
337   FX_FLOAT px, py;
338
339   csAP << cos(fRotate) << " " << sin(fRotate) << " " << -sin(fRotate) << " "
340        << cos(fRotate) << " " << crBBox.left + fWidth / 2 << " "
341        << crBBox.bottom + fHeight / 2 << " cm\n";
342
343   csAP << pt1.x << " " << pt1.y << " m\n";
344
345   px = pt2.x - pt1.x;
346   py = pt2.y - pt1.y;
347
348   csAP << pt1.x << " " << pt1.y + py * PWL_BEZIER << " "
349        << pt2.x - px * PWL_BEZIER << " " << pt2.y << " " << pt2.x << " "
350        << pt2.y << " c\n";
351
352   px = pt3.x - pt2.x;
353   py = pt2.y - pt3.y;
354
355   csAP << pt2.x + px * PWL_BEZIER << " " << pt2.y << " " << pt3.x << " "
356        << pt3.y + py * PWL_BEZIER << " " << pt3.x << " " << pt3.y << " c\n";
357
358   return csAP.GetByteString();
359 }
360
361 CPDF_Rect CPWL_Utils::InflateRect(const CPDF_Rect& rcRect, FX_FLOAT fSize) {
362   if (rcRect.IsEmpty())
363     return rcRect;
364
365   CPDF_Rect rcNew(rcRect.left - fSize, rcRect.bottom - fSize,
366                   rcRect.right + fSize, rcRect.top + fSize);
367   rcNew.Normalize();
368   return rcNew;
369 }
370
371 CPDF_Rect CPWL_Utils::DeflateRect(const CPDF_Rect& rcRect, FX_FLOAT fSize) {
372   if (rcRect.IsEmpty())
373     return rcRect;
374
375   CPDF_Rect rcNew(rcRect.left + fSize, rcRect.bottom + fSize,
376                   rcRect.right - fSize, rcRect.top - fSize);
377   rcNew.Normalize();
378   return rcNew;
379 }
380
381 CPDF_Rect CPWL_Utils::ScaleRect(const CPDF_Rect& rcRect, FX_FLOAT fScale) {
382   FX_FLOAT fHalfWidth = (rcRect.right - rcRect.left) / 2.0f;
383   FX_FLOAT fHalfHeight = (rcRect.top - rcRect.bottom) / 2.0f;
384
385   CPDF_Point ptCenter = CPDF_Point((rcRect.left + rcRect.right) / 2,
386                                    (rcRect.top + rcRect.bottom) / 2);
387
388   return CPDF_Rect(
389       ptCenter.x - fHalfWidth * fScale, ptCenter.y - fHalfHeight * fScale,
390       ptCenter.x + fHalfWidth * fScale, ptCenter.y + fHalfHeight * fScale);
391 }
392
393 CFX_ByteString CPWL_Utils::GetRectFillAppStream(const CPDF_Rect& rect,
394                                                 const CPWL_Color& color) {
395   CFX_ByteTextBuf sAppStream;
396
397   CFX_ByteString sColor = GetColorAppStream(color, TRUE);
398   if (sColor.GetLength() > 0) {
399     sAppStream << "q\n" << sColor;
400     sAppStream << rect.left << " " << rect.bottom << " "
401                << rect.right - rect.left << " " << rect.top - rect.bottom
402                << " re f\nQ\n";
403   }
404
405   return sAppStream.GetByteString();
406 }
407
408 CFX_ByteString CPWL_Utils::GetCircleFillAppStream(const CPDF_Rect& rect,
409                                                   const CPWL_Color& color) {
410   CFX_ByteTextBuf sAppStream;
411
412   CFX_ByteString sColor = GetColorAppStream(color, TRUE);
413   if (sColor.GetLength() > 0) {
414     sAppStream << "q\n" << sColor << CPWL_Utils::GetAP_Circle(rect) << "f\nQ\n";
415   }
416
417   return sAppStream.GetByteString();
418 }
419
420 CPDF_Rect CPWL_Utils::GetCenterSquare(const CPDF_Rect& rect) {
421   FX_FLOAT fWidth = rect.right - rect.left;
422   FX_FLOAT fHeight = rect.top - rect.bottom;
423
424   FX_FLOAT fCenterX = (rect.left + rect.right) / 2.0f;
425   FX_FLOAT fCenterY = (rect.top + rect.bottom) / 2.0f;
426
427   FX_FLOAT fRadius = (fWidth > fHeight) ? fHeight / 2 : fWidth / 2;
428
429   return CPDF_Rect(fCenterX - fRadius, fCenterY - fRadius, fCenterX + fRadius,
430                    fCenterY + fRadius);
431 }
432
433 CFX_ByteString CPWL_Utils::GetEditAppStream(IFX_Edit* pEdit,
434                                             const CPDF_Point& ptOffset,
435                                             const CPVT_WordRange* pRange,
436                                             FX_BOOL bContinuous,
437                                             FX_WORD SubWord) {
438   return IFX_Edit::GetEditAppearanceStream(pEdit, ptOffset, pRange, bContinuous,
439                                            SubWord);
440 }
441
442 CFX_ByteString CPWL_Utils::GetEditSelAppStream(IFX_Edit* pEdit,
443                                                const CPDF_Point& ptOffset,
444                                                const CPVT_WordRange* pRange) {
445   return IFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange);
446 }
447
448 static CFX_ByteString GetSquigglyAppearanceStream(FX_FLOAT fStartX,
449                                                   FX_FLOAT fEndX,
450                                                   FX_FLOAT fY,
451                                                   FX_FLOAT fStep) {
452   CFX_ByteTextBuf sRet;
453
454   sRet << "0 w\n" << fStartX << " " << fY << " m\n";
455
456   FX_FLOAT fx;
457   int32_t i;
458
459   for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {
460     sRet << fx << " " << fY + (i & 1) * fStep << " l\n";
461   }
462
463   sRet << "S\n";
464
465   return sRet.GetByteString();
466 }
467
468 static CFX_ByteString GetWordSpellCheckAppearanceStream(
469     IFX_Edit_Iterator* pIterator,
470     const CPDF_Point& ptOffset,
471     const CPVT_WordRange& wrWord) {
472   CFX_ByteTextBuf sRet;
473
474   FX_FLOAT fStartX = 0.0f;
475   FX_FLOAT fEndX = 0.0f;
476   FX_FLOAT fY = 0.0f;
477   FX_FLOAT fStep = 0.0f;
478
479   FX_BOOL bBreak = FALSE;
480
481   if (pIterator) {
482     pIterator->SetAt(wrWord.BeginPos);
483
484     do {
485       CPVT_WordPlace place = pIterator->GetAt();
486
487       CPVT_Line line;
488       if (pIterator->GetLine(line)) {
489         fY = line.ptLine.y;
490         fStep = (line.fLineAscent - line.fLineDescent) / 16.0f;
491       }
492
493       if (place.LineCmp(wrWord.BeginPos) == 0) {
494         pIterator->SetAt(wrWord.BeginPos);
495         CPVT_Word word;
496         if (pIterator->GetWord(word)) {
497           fStartX = word.ptWord.x;
498         }
499       } else {
500         fStartX = line.ptLine.x;
501       }
502
503       if (place.LineCmp(wrWord.EndPos) == 0) {
504         pIterator->SetAt(wrWord.EndPos);
505         CPVT_Word word;
506         if (pIterator->GetWord(word)) {
507           fEndX = word.ptWord.x + word.fWidth;
508         }
509
510         bBreak = TRUE;
511       } else {
512         fEndX = line.ptLine.x + line.fLineWidth;
513       }
514
515       sRet << GetSquigglyAppearanceStream(
516           fStartX + ptOffset.x, fEndX + ptOffset.x, fY + ptOffset.y, fStep);
517
518       if (bBreak)
519         break;
520     } while (pIterator->NextLine());
521   }
522
523   return sRet.GetByteString();
524 }
525
526 CFX_ByteString CPWL_Utils::GetSpellCheckAppStream(
527     IFX_Edit* pEdit,
528     IPWL_SpellCheck* pSpellCheck,
529     const CPDF_Point& ptOffset,
530     const CPVT_WordRange* pRange) {
531   ASSERT(pEdit != NULL);
532   ASSERT(pSpellCheck != NULL);
533
534   CFX_ByteTextBuf sRet;
535
536   if (pRange && pRange->IsExist()) {
537     if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
538       pIterator->SetAt(pRange->BeginPos);
539
540       FX_BOOL bLatinWord = FALSE;
541       CPVT_WordPlace wpWordStart;
542       CFX_ByteString sWord;
543
544       CPVT_WordPlace oldplace;
545       while (pIterator->NextWord()) {
546         CPVT_WordPlace place = pIterator->GetAt();
547         if (pRange && place.WordCmp(pRange->EndPos) > 0)
548           break;
549
550         CPVT_Word word;
551         if (pIterator->GetWord(word)) {
552           if (FX_EDIT_ISLATINWORD(word.Word)) {
553             if (!bLatinWord) {
554               wpWordStart = place;
555               bLatinWord = TRUE;
556             }
557
558             sWord += (char)word.Word;
559             oldplace = place;
560           } else {
561             if (bLatinWord) {
562               if (!pSpellCheck->CheckWord(sWord)) {
563                 sRet << GetWordSpellCheckAppearanceStream(
564                     pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace));
565                 pIterator->SetAt(place);
566               }
567               bLatinWord = FALSE;
568             }
569
570             sWord.Empty();
571           }
572         } else {
573           if (bLatinWord) {
574             if (!pSpellCheck->CheckWord(sWord))
575               sRet << GetWordSpellCheckAppearanceStream(
576                   pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace));
577             bLatinWord = FALSE;
578             sWord.Empty();
579           }
580         }
581       }
582
583       if (bLatinWord) {
584         if (!pSpellCheck->CheckWord(sWord))
585           sRet << GetWordSpellCheckAppearanceStream(
586               pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace));
587
588         bLatinWord = FALSE;
589         sWord.Empty();
590       }
591     }
592   }
593
594   return sRet.GetByteString();
595 }
596
597 CFX_ByteString CPWL_Utils::GetTextAppStream(const CPDF_Rect& rcBBox,
598                                             IFX_Edit_FontMap* pFontMap,
599                                             const CFX_WideString& sText,
600                                             int32_t nAlignmentH,
601                                             int32_t nAlignmentV,
602                                             FX_FLOAT fFontSize,
603                                             FX_BOOL bMultiLine,
604                                             FX_BOOL bAutoReturn,
605                                             const CPWL_Color& crText) {
606   CFX_ByteTextBuf sRet;
607
608   if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
609     pEdit->SetFontMap(pFontMap);
610     pEdit->SetPlateRect(rcBBox);
611     pEdit->SetAlignmentH(nAlignmentH);
612     pEdit->SetAlignmentV(nAlignmentV);
613     pEdit->SetMultiLine(bMultiLine);
614     pEdit->SetAutoReturn(bAutoReturn);
615     if (IsFloatZero(fFontSize))
616       pEdit->SetAutoFontSize(TRUE);
617     else
618       pEdit->SetFontSize(fFontSize);
619
620     pEdit->Initialize();
621     pEdit->SetText(sText.c_str());
622
623     CFX_ByteString sEdit =
624         CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, 0.0f));
625     if (sEdit.GetLength() > 0) {
626       sRet << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
627            << "ET\n";
628     }
629     IFX_Edit::DelEdit(pEdit);
630   }
631
632   return sRet.GetByteString();
633 }
634
635 CFX_ByteString CPWL_Utils::GetPushButtonAppStream(const CPDF_Rect& rcBBox,
636                                                   IFX_Edit_FontMap* pFontMap,
637                                                   CPDF_Stream* pIconStream,
638                                                   CPDF_IconFit& IconFit,
639                                                   const CFX_WideString& sLabel,
640                                                   const CPWL_Color& crText,
641                                                   FX_FLOAT fFontSize,
642                                                   int32_t nLayOut) {
643   const FX_FLOAT fAutoFontScale = 1.0f / 3.0f;
644
645   if (IFX_Edit* pEdit = IFX_Edit::NewEdit()) {
646     pEdit->SetFontMap(pFontMap);
647     pEdit->SetAlignmentH(1);
648     pEdit->SetAlignmentV(1);
649     pEdit->SetMultiLine(FALSE);
650     pEdit->SetAutoReturn(FALSE);
651     if (IsFloatZero(fFontSize))
652       pEdit->SetAutoFontSize(TRUE);
653     else
654       pEdit->SetFontSize(fFontSize);
655
656     pEdit->Initialize();
657     pEdit->SetText(sLabel.c_str());
658
659     CPDF_Rect rcLabelContent = pEdit->GetContentRect();
660     CPWL_Icon Icon;
661     PWL_CREATEPARAM cp;
662     cp.dwFlags = PWS_VISIBLE;
663     Icon.Create(cp);
664     Icon.SetIconFit(&IconFit);
665     Icon.SetPDFStream(pIconStream);
666
667     CPDF_Rect rcLabel = CPDF_Rect(0, 0, 0, 0);
668     CPDF_Rect rcIcon = CPDF_Rect(0, 0, 0, 0);
669     FX_FLOAT fWidth = 0.0f;
670     FX_FLOAT fHeight = 0.0f;
671
672     switch (nLayOut) {
673       case PPBL_LABEL:
674         rcLabel = rcBBox;
675         rcIcon = CPDF_Rect(0, 0, 0, 0);
676         break;
677       case PPBL_ICON:
678         rcIcon = rcBBox;
679         rcLabel = CPDF_Rect(0, 0, 0, 0);
680         break;
681       case PPBL_ICONTOPLABELBOTTOM:
682
683         if (pIconStream) {
684           if (IsFloatZero(fFontSize)) {
685             fHeight = rcBBox.top - rcBBox.bottom;
686             rcLabel = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcBBox.right,
687                                 rcBBox.bottom + fHeight * fAutoFontScale);
688             rcIcon =
689                 CPDF_Rect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
690           } else {
691             fHeight = rcLabelContent.Height();
692
693             if (rcBBox.bottom + fHeight > rcBBox.top) {
694               rcIcon = CPDF_Rect(0, 0, 0, 0);
695               rcLabel = rcBBox;
696             } else {
697               rcLabel = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcBBox.right,
698                                   rcBBox.bottom + fHeight);
699               rcIcon =
700                   CPDF_Rect(rcBBox.left, rcLabel.top, rcBBox.right, rcBBox.top);
701             }
702           }
703         } else {
704           rcLabel = rcBBox;
705           rcIcon = CPDF_Rect(0, 0, 0, 0);
706         }
707
708         break;
709       case PPBL_LABELTOPICONBOTTOM:
710
711         if (pIconStream) {
712           if (IsFloatZero(fFontSize)) {
713             fHeight = rcBBox.top - rcBBox.bottom;
714             rcLabel =
715                 CPDF_Rect(rcBBox.left, rcBBox.top - fHeight * fAutoFontScale,
716                           rcBBox.right, rcBBox.top);
717             rcIcon = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcBBox.right,
718                                rcLabel.bottom);
719           } else {
720             fHeight = rcLabelContent.Height();
721
722             if (rcBBox.bottom + fHeight > rcBBox.top) {
723               rcIcon = CPDF_Rect(0, 0, 0, 0);
724               rcLabel = rcBBox;
725             } else {
726               rcLabel = CPDF_Rect(rcBBox.left, rcBBox.top - fHeight,
727                                   rcBBox.right, rcBBox.top);
728               rcIcon = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcBBox.right,
729                                  rcLabel.bottom);
730             }
731           }
732         } else {
733           rcLabel = rcBBox;
734           rcIcon = CPDF_Rect(0, 0, 0, 0);
735         }
736
737         break;
738       case PPBL_ICONLEFTLABELRIGHT:
739
740         if (pIconStream) {
741           if (IsFloatZero(fFontSize)) {
742             fWidth = rcBBox.right - rcBBox.left;
743             rcLabel = CPDF_Rect(rcBBox.right - fWidth * fAutoFontScale,
744                                 rcBBox.bottom, rcBBox.right, rcBBox.top);
745             rcIcon =
746                 CPDF_Rect(rcBBox.left, rcBBox.bottom, rcLabel.left, rcBBox.top);
747
748             if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
749             } else {
750               if (rcLabelContent.Width() < fWidth) {
751                 rcLabel = CPDF_Rect(rcBBox.right - rcLabelContent.Width(),
752                                     rcBBox.bottom, rcBBox.right, rcBBox.top);
753                 rcIcon = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcLabel.left,
754                                    rcBBox.top);
755               } else {
756                 rcLabel = rcBBox;
757                 rcIcon = CPDF_Rect(0, 0, 0, 0);
758               }
759             }
760           } else {
761             fWidth = rcLabelContent.Width();
762
763             if (rcBBox.left + fWidth > rcBBox.right) {
764               rcLabel = rcBBox;
765               rcIcon = CPDF_Rect(0, 0, 0, 0);
766             } else {
767               rcLabel = CPDF_Rect(rcBBox.right - fWidth, rcBBox.bottom,
768                                   rcBBox.right, rcBBox.top);
769               rcIcon = CPDF_Rect(rcBBox.left, rcBBox.bottom, rcLabel.left,
770                                  rcBBox.top);
771             }
772           }
773         } else {
774           rcLabel = rcBBox;
775           rcIcon = CPDF_Rect(0, 0, 0, 0);
776         }
777
778         break;
779       case PPBL_LABELLEFTICONRIGHT:
780
781         if (pIconStream) {
782           if (IsFloatZero(fFontSize)) {
783             fWidth = rcBBox.right - rcBBox.left;
784             rcLabel =
785                 CPDF_Rect(rcBBox.left, rcBBox.bottom,
786                           rcBBox.left + fWidth * fAutoFontScale, rcBBox.top);
787             rcIcon = CPDF_Rect(rcLabel.right, rcBBox.bottom, rcBBox.right,
788                                rcBBox.top);
789
790             if (rcLabelContent.Width() < fWidth * fAutoFontScale) {
791             } else {
792               if (rcLabelContent.Width() < fWidth) {
793                 rcLabel =
794                     CPDF_Rect(rcBBox.left, rcBBox.bottom,
795                               rcBBox.left + rcLabelContent.Width(), rcBBox.top);
796                 rcIcon = CPDF_Rect(rcLabel.right, rcBBox.bottom, rcBBox.right,
797                                    rcBBox.top);
798               } else {
799                 rcLabel = rcBBox;
800                 rcIcon = CPDF_Rect(0, 0, 0, 0);
801               }
802             }
803           } else {
804             fWidth = rcLabelContent.Width();
805
806             if (rcBBox.left + fWidth > rcBBox.right) {
807               rcLabel = rcBBox;
808               rcIcon = CPDF_Rect(0, 0, 0, 0);
809             } else {
810               rcLabel = CPDF_Rect(rcBBox.left, rcBBox.bottom,
811                                   rcBBox.left + fWidth, rcBBox.top);
812               rcIcon = CPDF_Rect(rcLabel.right, rcBBox.bottom, rcBBox.right,
813                                  rcBBox.top);
814             }
815           }
816         } else {
817           rcLabel = rcBBox;
818           rcIcon = CPDF_Rect(0, 0, 0, 0);
819         }
820
821         break;
822       case PPBL_LABELOVERICON:
823         rcLabel = rcBBox;
824         rcIcon = rcBBox;
825         break;
826     }
827
828     CFX_ByteTextBuf sAppStream, sTemp;
829
830     if (!rcIcon.IsEmpty()) {
831       Icon.Move(rcIcon, FALSE, FALSE);
832       sTemp << Icon.GetImageAppStream();
833     }
834
835     Icon.Destroy();
836
837     if (!rcLabel.IsEmpty()) {
838       pEdit->SetPlateRect(rcLabel);
839       CFX_ByteString sEdit =
840           CPWL_Utils::GetEditAppStream(pEdit, CPDF_Point(0.0f, 0.0f));
841       if (sEdit.GetLength() > 0) {
842         sTemp << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit
843               << "ET\n";
844       }
845     }
846
847     IFX_Edit::DelEdit(pEdit);
848
849     if (sTemp.GetSize() > 0) {
850       sAppStream << "q\n" << rcBBox.left << " " << rcBBox.bottom << " "
851                  << rcBBox.right - rcBBox.left << " "
852                  << rcBBox.top - rcBBox.bottom << " re W n\n";
853       sAppStream << sTemp << "Q\n";
854     }
855
856     return sAppStream.GetByteString();
857   }
858
859   return "";
860 }
861
862 CFX_ByteString CPWL_Utils::GetColorAppStream(const CPWL_Color& color,
863                                              const FX_BOOL& bFillOrStroke) {
864   CFX_ByteTextBuf sColorStream;
865
866   switch (color.nColorType) {
867     case COLORTYPE_RGB:
868       sColorStream << color.fColor1 << " " << color.fColor2 << " "
869                    << color.fColor3 << " " << (bFillOrStroke ? "rg" : "RG")
870                    << "\n";
871       break;
872     case COLORTYPE_GRAY:
873       sColorStream << color.fColor1 << " " << (bFillOrStroke ? "g" : "G")
874                    << "\n";
875       break;
876     case COLORTYPE_CMYK:
877       sColorStream << color.fColor1 << " " << color.fColor2 << " "
878                    << color.fColor3 << " " << color.fColor4 << " "
879                    << (bFillOrStroke ? "k" : "K") << "\n";
880       break;
881   }
882
883   return sColorStream.GetByteString();
884 }
885
886 CFX_ByteString CPWL_Utils::GetBorderAppStream(const CPDF_Rect& rect,
887                                               FX_FLOAT fWidth,
888                                               const CPWL_Color& color,
889                                               const CPWL_Color& crLeftTop,
890                                               const CPWL_Color& crRightBottom,
891                                               int32_t nStyle,
892                                               const CPWL_Dash& dash) {
893   CFX_ByteTextBuf sAppStream;
894   CFX_ByteString sColor;
895
896   FX_FLOAT fLeft = rect.left;
897   FX_FLOAT fRight = rect.right;
898   FX_FLOAT fTop = rect.top;
899   FX_FLOAT fBottom = rect.bottom;
900
901   if (fWidth > 0.0f) {
902     FX_FLOAT fHalfWidth = fWidth / 2.0f;
903
904     sAppStream << "q\n";
905
906     switch (nStyle) {
907       default:
908       case PBS_SOLID:
909         sColor = CPWL_Utils::GetColorAppStream(color, TRUE);
910         if (sColor.GetLength() > 0) {
911           sAppStream << sColor;
912           sAppStream << fLeft << " " << fBottom << " " << fRight - fLeft << " "
913                      << fTop - fBottom << " re\n";
914           sAppStream << fLeft + fWidth << " " << fBottom + fWidth << " "
915                      << fRight - fLeft - fWidth * 2 << " "
916                      << fTop - fBottom - fWidth * 2 << " re\n";
917           sAppStream << "f*\n";
918         }
919         break;
920       case PBS_DASH:
921         sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
922         if (sColor.GetLength() > 0) {
923           sAppStream << sColor;
924           sAppStream << fWidth << " w"
925                      << " [" << dash.nDash << " " << dash.nGap << "] "
926                      << dash.nPhase << " d\n";
927           sAppStream << fLeft + fWidth / 2 << " " << fBottom + fWidth / 2
928                      << " m\n";
929           sAppStream << fLeft + fWidth / 2 << " " << fTop - fWidth / 2
930                      << " l\n";
931           sAppStream << fRight - fWidth / 2 << " " << fTop - fWidth / 2
932                      << " l\n";
933           sAppStream << fRight - fWidth / 2 << " " << fBottom + fWidth / 2
934                      << " l\n";
935           sAppStream << fLeft + fWidth / 2 << " " << fBottom + fWidth / 2
936                      << " l S\n";
937         }
938         break;
939       case PBS_BEVELED:
940       case PBS_INSET:
941         sColor = CPWL_Utils::GetColorAppStream(crLeftTop, TRUE);
942         if (sColor.GetLength() > 0) {
943           sAppStream << sColor;
944           sAppStream << fLeft + fHalfWidth << " " << fBottom + fHalfWidth
945                      << " m\n";
946           sAppStream << fLeft + fHalfWidth << " " << fTop - fHalfWidth
947                      << " l\n";
948           sAppStream << fRight - fHalfWidth << " " << fTop - fHalfWidth
949                      << " l\n";
950           sAppStream << fRight - fHalfWidth * 2 << " " << fTop - fHalfWidth * 2
951                      << " l\n";
952           sAppStream << fLeft + fHalfWidth * 2 << " " << fTop - fHalfWidth * 2
953                      << " l\n";
954           sAppStream << fLeft + fHalfWidth * 2 << " "
955                      << fBottom + fHalfWidth * 2 << " l f\n";
956         }
957
958         sColor = CPWL_Utils::GetColorAppStream(crRightBottom, TRUE);
959         if (sColor.GetLength() > 0) {
960           sAppStream << sColor;
961           sAppStream << fRight - fHalfWidth << " " << fTop - fHalfWidth
962                      << " m\n";
963           sAppStream << fRight - fHalfWidth << " " << fBottom + fHalfWidth
964                      << " l\n";
965           sAppStream << fLeft + fHalfWidth << " " << fBottom + fHalfWidth
966                      << " l\n";
967           sAppStream << fLeft + fHalfWidth * 2 << " "
968                      << fBottom + fHalfWidth * 2 << " l\n";
969           sAppStream << fRight - fHalfWidth * 2 << " "
970                      << fBottom + fHalfWidth * 2 << " l\n";
971           sAppStream << fRight - fHalfWidth * 2 << " " << fTop - fHalfWidth * 2
972                      << " l f\n";
973         }
974
975         sColor = CPWL_Utils::GetColorAppStream(color, TRUE);
976         if (sColor.GetLength() > 0) {
977           sAppStream << sColor;
978           sAppStream << fLeft << " " << fBottom << " " << fRight - fLeft << " "
979                      << fTop - fBottom << " re\n";
980           sAppStream << fLeft + fHalfWidth << " " << fBottom + fHalfWidth << " "
981                      << fRight - fLeft - fHalfWidth * 2 << " "
982                      << fTop - fBottom - fHalfWidth * 2 << " re f*\n";
983         }
984         break;
985       case PBS_UNDERLINED:
986         sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
987         if (sColor.GetLength() > 0) {
988           sAppStream << sColor;
989           sAppStream << fWidth << " w\n";
990           sAppStream << fLeft << " " << fBottom + fWidth / 2 << " m\n";
991           sAppStream << fRight << " " << fBottom + fWidth / 2 << " l S\n";
992         }
993         break;
994     }
995
996     sAppStream << "Q\n";
997   }
998
999   return sAppStream.GetByteString();
1000 }
1001
1002 CFX_ByteString CPWL_Utils::GetCircleBorderAppStream(
1003     const CPDF_Rect& rect,
1004     FX_FLOAT fWidth,
1005     const CPWL_Color& color,
1006     const CPWL_Color& crLeftTop,
1007     const CPWL_Color& crRightBottom,
1008     int32_t nStyle,
1009     const CPWL_Dash& dash) {
1010   CFX_ByteTextBuf sAppStream;
1011   CFX_ByteString sColor;
1012
1013   if (fWidth > 0.0f) {
1014     sAppStream << "q\n";
1015
1016     switch (nStyle) {
1017       default:
1018       case PBS_SOLID:
1019       case PBS_UNDERLINED: {
1020         sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
1021         if (sColor.GetLength() > 0) {
1022           sAppStream << "q\n" << fWidth << " w\n" << sColor
1023                      << CPWL_Utils::GetAP_Circle(
1024                             CPWL_Utils::DeflateRect(rect, fWidth / 2.0f))
1025                      << " S\nQ\n";
1026         }
1027       } break;
1028       case PBS_DASH: {
1029         sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
1030         if (sColor.GetLength() > 0) {
1031           sAppStream << "q\n" << fWidth << " w\n"
1032                      << "[" << dash.nDash << " " << dash.nGap << "] "
1033                      << dash.nPhase << " d\n" << sColor
1034                      << CPWL_Utils::GetAP_Circle(
1035                             CPWL_Utils::DeflateRect(rect, fWidth / 2.0f))
1036                      << " S\nQ\n";
1037         }
1038       } break;
1039       case PBS_BEVELED: {
1040         FX_FLOAT fHalfWidth = fWidth / 2.0f;
1041
1042         sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
1043         if (sColor.GetLength() > 0) {
1044           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
1045                      << CPWL_Utils::GetAP_Circle(rect) << " S\nQ\n";
1046         }
1047
1048         sColor = CPWL_Utils::GetColorAppStream(crLeftTop, FALSE);
1049         if (sColor.GetLength() > 0) {
1050           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
1051                      << CPWL_Utils::GetAP_HalfCircle(
1052                             CPWL_Utils::DeflateRect(rect, fHalfWidth * 0.75f),
1053                             PWL_PI / 4.0f)
1054                      << " S\nQ\n";
1055         }
1056
1057         sColor = CPWL_Utils::GetColorAppStream(crRightBottom, FALSE);
1058         if (sColor.GetLength() > 0) {
1059           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
1060                      << CPWL_Utils::GetAP_HalfCircle(
1061                             CPWL_Utils::DeflateRect(rect, fHalfWidth * 0.75f),
1062                             PWL_PI * 5 / 4.0f)
1063                      << " S\nQ\n";
1064         }
1065       } break;
1066       case PBS_INSET: {
1067         FX_FLOAT fHalfWidth = fWidth / 2.0f;
1068
1069         sColor = CPWL_Utils::GetColorAppStream(color, FALSE);
1070         if (sColor.GetLength() > 0) {
1071           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
1072                      << CPWL_Utils::GetAP_Circle(rect) << " S\nQ\n";
1073         }
1074
1075         sColor = CPWL_Utils::GetColorAppStream(crLeftTop, FALSE);
1076         if (sColor.GetLength() > 0) {
1077           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
1078                      << CPWL_Utils::GetAP_HalfCircle(
1079                             CPWL_Utils::DeflateRect(rect, fHalfWidth * 0.75f),
1080                             PWL_PI / 4.0f)
1081                      << " S\nQ\n";
1082         }
1083
1084         sColor = CPWL_Utils::GetColorAppStream(crRightBottom, FALSE);
1085         if (sColor.GetLength() > 0) {
1086           sAppStream << "q\n" << fHalfWidth << " w\n" << sColor
1087                      << CPWL_Utils::GetAP_HalfCircle(
1088                             CPWL_Utils::DeflateRect(rect, fHalfWidth * 0.75f),
1089                             PWL_PI * 5 / 4.0f)
1090                      << " S\nQ\n";
1091         }
1092       } break;
1093     }
1094
1095     sAppStream << "Q\n";
1096   }
1097
1098   return sAppStream.GetByteString();
1099 }
1100
1101 CPWL_Color CPWL_Utils::SubstractColor(const CPWL_Color& sColor,
1102                                       FX_FLOAT fColorSub) {
1103   CPWL_Color sRet;
1104   sRet.nColorType = sColor.nColorType;
1105
1106   switch (sColor.nColorType) {
1107     case COLORTYPE_TRANSPARENT:
1108       sRet.nColorType = COLORTYPE_RGB;
1109       sRet.fColor1 = PWL_MAX(1 - fColorSub, 0.0f);
1110       sRet.fColor2 = PWL_MAX(1 - fColorSub, 0.0f);
1111       sRet.fColor3 = PWL_MAX(1 - fColorSub, 0.0f);
1112       break;
1113     case COLORTYPE_RGB:
1114     case COLORTYPE_GRAY:
1115     case COLORTYPE_CMYK:
1116       sRet.fColor1 = PWL_MAX(sColor.fColor1 - fColorSub, 0.0f);
1117       sRet.fColor2 = PWL_MAX(sColor.fColor2 - fColorSub, 0.0f);
1118       sRet.fColor3 = PWL_MAX(sColor.fColor3 - fColorSub, 0.0f);
1119       sRet.fColor4 = PWL_MAX(sColor.fColor4 - fColorSub, 0.0f);
1120       break;
1121   }
1122
1123   return sRet;
1124 }
1125
1126 CPWL_Color CPWL_Utils::DevideColor(const CPWL_Color& sColor,
1127                                    FX_FLOAT fColorDevide) {
1128   CPWL_Color sRet;
1129   sRet.nColorType = sColor.nColorType;
1130
1131   switch (sColor.nColorType) {
1132     case COLORTYPE_TRANSPARENT:
1133       sRet.nColorType = COLORTYPE_RGB;
1134       sRet.fColor1 = 1 / fColorDevide;
1135       sRet.fColor2 = 1 / fColorDevide;
1136       sRet.fColor3 = 1 / fColorDevide;
1137       break;
1138     case COLORTYPE_RGB:
1139     case COLORTYPE_GRAY:
1140     case COLORTYPE_CMYK:
1141       sRet = sColor;
1142       sRet.fColor1 /= fColorDevide;
1143       sRet.fColor2 /= fColorDevide;
1144       sRet.fColor3 /= fColorDevide;
1145       sRet.fColor4 /= fColorDevide;
1146       break;
1147   }
1148
1149   return sRet;
1150 }
1151
1152 CFX_ByteString CPWL_Utils::GetAppStream_Check(const CPDF_Rect& rcBBox,
1153                                               const CPWL_Color& crText) {
1154   CFX_ByteTextBuf sAP;
1155   sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
1156       << CPWL_Utils::GetAP_Check(rcBBox) << "f\nQ\n";
1157   return sAP.GetByteString();
1158 }
1159
1160 CFX_ByteString CPWL_Utils::GetAppStream_Circle(const CPDF_Rect& rcBBox,
1161                                                const CPWL_Color& crText) {
1162   CFX_ByteTextBuf sAP;
1163   sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
1164       << CPWL_Utils::GetAP_Circle(rcBBox) << "f\nQ\n";
1165   return sAP.GetByteString();
1166 }
1167
1168 CFX_ByteString CPWL_Utils::GetAppStream_Cross(const CPDF_Rect& rcBBox,
1169                                               const CPWL_Color& crText) {
1170   CFX_ByteTextBuf sAP;
1171   sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, FALSE)
1172       << CPWL_Utils::GetAP_Cross(rcBBox) << "S\nQ\n";
1173   return sAP.GetByteString();
1174 }
1175
1176 CFX_ByteString CPWL_Utils::GetAppStream_Diamond(const CPDF_Rect& rcBBox,
1177                                                 const CPWL_Color& crText) {
1178   CFX_ByteTextBuf sAP;
1179   sAP << "q\n1 w\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
1180       << CPWL_Utils::GetAP_Diamond(rcBBox) << "f\nQ\n";
1181   return sAP.GetByteString();
1182 }
1183
1184 CFX_ByteString CPWL_Utils::GetAppStream_Square(const CPDF_Rect& rcBBox,
1185                                                const CPWL_Color& crText) {
1186   CFX_ByteTextBuf sAP;
1187   sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
1188       << CPWL_Utils::GetAP_Square(rcBBox) << "f\nQ\n";
1189   return sAP.GetByteString();
1190 }
1191
1192 CFX_ByteString CPWL_Utils::GetAppStream_Star(const CPDF_Rect& rcBBox,
1193                                              const CPWL_Color& crText) {
1194   CFX_ByteTextBuf sAP;
1195   sAP << "q\n" << CPWL_Utils::GetColorAppStream(crText, TRUE)
1196       << CPWL_Utils::GetAP_Star(rcBBox) << "f\nQ\n";
1197   return sAP.GetByteString();
1198 }
1199
1200 CFX_ByteString CPWL_Utils::GetCheckBoxAppStream(const CPDF_Rect& rcBBox,
1201                                                 int32_t nStyle,
1202                                                 const CPWL_Color& crText) {
1203   CPDF_Rect rcCenter = GetCenterSquare(rcBBox);
1204   switch (nStyle) {
1205     default:
1206     case PCS_CHECK:
1207       return GetAppStream_Check(rcCenter, crText);
1208     case PCS_CIRCLE:
1209       return GetAppStream_Circle(ScaleRect(rcCenter, 2.0f / 3.0f), crText);
1210     case PCS_CROSS:
1211       return GetAppStream_Cross(rcCenter, crText);
1212     case PCS_DIAMOND:
1213       return GetAppStream_Diamond(ScaleRect(rcCenter, 2.0f / 3.0f), crText);
1214     case PCS_SQUARE:
1215       return GetAppStream_Square(ScaleRect(rcCenter, 2.0f / 3.0f), crText);
1216     case PCS_STAR:
1217       return GetAppStream_Star(ScaleRect(rcCenter, 2.0f / 3.0f), crText);
1218   }
1219 }
1220
1221 CFX_ByteString CPWL_Utils::GetRadioButtonAppStream(const CPDF_Rect& rcBBox,
1222                                                    int32_t nStyle,
1223                                                    const CPWL_Color& crText) {
1224   CPDF_Rect rcCenter = GetCenterSquare(rcBBox);
1225   switch (nStyle) {
1226     default:
1227     case PCS_CHECK:
1228       return GetAppStream_Check(rcCenter, crText);
1229     case PCS_CIRCLE:
1230       return GetAppStream_Circle(ScaleRect(rcCenter, 1.0f / 2.0f), crText);
1231     case PCS_CROSS:
1232       return GetAppStream_Cross(rcCenter, crText);
1233     case PCS_DIAMOND:
1234       return GetAppStream_Diamond(ScaleRect(rcCenter, 2.0f / 3.0f), crText);
1235     case PCS_SQUARE:
1236       return GetAppStream_Square(ScaleRect(rcCenter, 2.0f / 3.0f), crText);
1237     case PCS_STAR:
1238       return GetAppStream_Star(ScaleRect(rcCenter, 2.0f / 3.0f), crText);
1239   }
1240 }
1241
1242 CFX_ByteString CPWL_Utils::GetDropButtonAppStream(const CPDF_Rect& rcBBox) {
1243   CFX_ByteTextBuf sAppStream;
1244
1245   if (!rcBBox.IsEmpty()) {
1246     sAppStream << "q\n" << CPWL_Utils::GetColorAppStream(
1247                                CPWL_Color(COLORTYPE_RGB, 220.0f / 255.0f,
1248                                           220.0f / 255.0f, 220.0f / 255.0f),
1249                                TRUE);
1250     sAppStream << rcBBox.left << " " << rcBBox.bottom << " "
1251                << rcBBox.right - rcBBox.left << " "
1252                << rcBBox.top - rcBBox.bottom << " re f\n";
1253     sAppStream << "Q\n";
1254
1255     sAppStream << "q\n" << CPWL_Utils::GetBorderAppStream(
1256                                rcBBox, 2, CPWL_Color(COLORTYPE_GRAY, 0),
1257                                CPWL_Color(COLORTYPE_GRAY, 1),
1258                                CPWL_Color(COLORTYPE_GRAY, 0.5), PBS_BEVELED,
1259                                CPWL_Dash(3, 0, 0))
1260                << "Q\n";
1261
1262     CPDF_Point ptCenter = CPDF_Point((rcBBox.left + rcBBox.right) / 2,
1263                                      (rcBBox.top + rcBBox.bottom) / 2);
1264     if (IsFloatBigger(rcBBox.right - rcBBox.left, 6) &&
1265         IsFloatBigger(rcBBox.top - rcBBox.bottom, 6)) {
1266       sAppStream << "q\n"
1267                  << " 0 g\n";
1268       sAppStream << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " m\n";
1269       sAppStream << ptCenter.x + 3 << " " << ptCenter.y + 1.5f << " l\n";
1270       sAppStream << ptCenter.x << " " << ptCenter.y - 1.5f << " l\n";
1271       sAppStream << ptCenter.x - 3 << " " << ptCenter.y + 1.5f << " l f\n";
1272       sAppStream << "Q\n";
1273     }
1274   }
1275
1276   return sAppStream.GetByteString();
1277 }
1278
1279 void CPWL_Utils::ConvertCMYK2GRAY(FX_FLOAT dC,
1280                                   FX_FLOAT dM,
1281                                   FX_FLOAT dY,
1282                                   FX_FLOAT dK,
1283                                   FX_FLOAT& dGray) {
1284   if (dC < 0 || dC > 1 || dM < 0 || dM > 1 || dY < 0 || dY > 1 || dK < 0 ||
1285       dK > 1)
1286     return;
1287   dGray = 1.0f - FX_MIN(1.0f, 0.3f * dC + 0.59f * dM + 0.11f * dY + dK);
1288 }
1289
1290 void CPWL_Utils::ConvertGRAY2CMYK(FX_FLOAT dGray,
1291                                   FX_FLOAT& dC,
1292                                   FX_FLOAT& dM,
1293                                   FX_FLOAT& dY,
1294                                   FX_FLOAT& dK) {
1295   if (dGray < 0 || dGray > 1)
1296     return;
1297   dC = 0.0f;
1298   dM = 0.0f;
1299   dY = 0.0f;
1300   dK = 1.0f - dGray;
1301 }
1302
1303 void CPWL_Utils::ConvertGRAY2RGB(FX_FLOAT dGray,
1304                                  FX_FLOAT& dR,
1305                                  FX_FLOAT& dG,
1306                                  FX_FLOAT& dB) {
1307   if (dGray < 0 || dGray > 1)
1308     return;
1309   dR = dGray;
1310   dG = dGray;
1311   dB = dGray;
1312 }
1313
1314 void CPWL_Utils::ConvertRGB2GRAY(FX_FLOAT dR,
1315                                  FX_FLOAT dG,
1316                                  FX_FLOAT dB,
1317                                  FX_FLOAT& dGray) {
1318   if (dR < 0 || dR > 1 || dG < 0 || dG > 0 || dB < 0 || dB > 1)
1319     return;
1320   dGray = 0.3f * dR + 0.59f * dG + 0.11f * dB;
1321 }
1322
1323 void CPWL_Utils::ConvertCMYK2RGB(FX_FLOAT dC,
1324                                  FX_FLOAT dM,
1325                                  FX_FLOAT dY,
1326                                  FX_FLOAT dK,
1327                                  FX_FLOAT& dR,
1328                                  FX_FLOAT& dG,
1329                                  FX_FLOAT& dB) {
1330   if (dC < 0 || dC > 1 || dM < 0 || dM > 1 || dY < 0 || dY > 1 || dK < 0 ||
1331       dK > 1)
1332     return;
1333   dR = 1.0f - FX_MIN(1.0f, dC + dK);
1334   dG = 1.0f - FX_MIN(1.0f, dM + dK);
1335   dB = 1.0f - FX_MIN(1.0f, dY + dK);
1336 }
1337
1338 void CPWL_Utils::ConvertRGB2CMYK(FX_FLOAT dR,
1339                                  FX_FLOAT dG,
1340                                  FX_FLOAT dB,
1341                                  FX_FLOAT& dC,
1342                                  FX_FLOAT& dM,
1343                                  FX_FLOAT& dY,
1344                                  FX_FLOAT& dK) {
1345   if (dR < 0 || dR > 1 || dG < 0 || dG > 1 || dB < 0 || dB > 1)
1346     return;
1347
1348   dC = 1.0f - dR;
1349   dM = 1.0f - dG;
1350   dY = 1.0f - dB;
1351   dK = FX_MIN(dC, FX_MIN(dM, dY));
1352 }
1353
1354 void CPWL_Utils::PWLColorToARGB(const CPWL_Color& color,
1355                                 int32_t& alpha,
1356                                 FX_FLOAT& red,
1357                                 FX_FLOAT& green,
1358                                 FX_FLOAT& blue) {
1359   switch (color.nColorType) {
1360     case COLORTYPE_TRANSPARENT: {
1361       alpha = 0;
1362     } break;
1363     case COLORTYPE_GRAY: {
1364       ConvertGRAY2RGB(color.fColor1, red, green, blue);
1365     } break;
1366     case COLORTYPE_RGB: {
1367       red = color.fColor1;
1368       green = color.fColor2;
1369       blue = color.fColor3;
1370     } break;
1371     case COLORTYPE_CMYK: {
1372       ConvertCMYK2RGB(color.fColor1, color.fColor2, color.fColor3,
1373                       color.fColor4, red, green, blue);
1374     } break;
1375   }
1376 }
1377
1378 FX_COLORREF CPWL_Utils::PWLColorToFXColor(const CPWL_Color& color,
1379                                           int32_t nTransparancy) {
1380   int32_t nAlpha = nTransparancy;
1381   FX_FLOAT dRed = 0;
1382   FX_FLOAT dGreen = 0;
1383   FX_FLOAT dBlue = 0;
1384
1385   PWLColorToARGB(color, nAlpha, dRed, dGreen, dBlue);
1386
1387   return ArgbEncode(nAlpha, (int32_t)(dRed * 255), (int32_t)(dGreen * 255),
1388                     (int32_t)(dBlue * 255));
1389 }
1390
1391 void CPWL_Utils::DrawFillRect(CFX_RenderDevice* pDevice,
1392                               CPDF_Matrix* pUser2Device,
1393                               const CPDF_Rect& rect,
1394                               const FX_COLORREF& color) {
1395   CFX_PathData path;
1396   CPDF_Rect rcTemp(rect);
1397   path.AppendRect(rcTemp.left, rcTemp.bottom, rcTemp.right, rcTemp.top);
1398   pDevice->DrawPath(&path, pUser2Device, NULL, color, 0, FXFILL_WINDING);
1399 }
1400
1401 void CPWL_Utils::DrawFillArea(CFX_RenderDevice* pDevice,
1402                               CPDF_Matrix* pUser2Device,
1403                               const CPDF_Point* pPts,
1404                               int32_t nCount,
1405                               const FX_COLORREF& color) {
1406   CFX_PathData path;
1407   path.SetPointCount(nCount);
1408
1409   path.SetPoint(0, pPts[0].x, pPts[0].y, FXPT_MOVETO);
1410   for (int32_t i = 1; i < nCount; i++)
1411     path.SetPoint(i, pPts[i].x, pPts[i].y, FXPT_LINETO);
1412
1413   pDevice->DrawPath(&path, pUser2Device, NULL, color, 0, FXFILL_ALTERNATE);
1414 }
1415
1416 void CPWL_Utils::DrawStrokeRect(CFX_RenderDevice* pDevice,
1417                                 CPDF_Matrix* pUser2Device,
1418                                 const CPDF_Rect& rect,
1419                                 const FX_COLORREF& color,
1420                                 FX_FLOAT fWidth) {
1421   CFX_PathData path;
1422   CPDF_Rect rcTemp(rect);
1423   path.AppendRect(rcTemp.left, rcTemp.bottom, rcTemp.right, rcTemp.top);
1424
1425   CFX_GraphStateData gsd;
1426   gsd.m_LineWidth = fWidth;
1427
1428   pDevice->DrawPath(&path, pUser2Device, &gsd, 0, color, FXFILL_ALTERNATE);
1429 }
1430
1431 void CPWL_Utils::DrawStrokeLine(CFX_RenderDevice* pDevice,
1432                                 CPDF_Matrix* pUser2Device,
1433                                 const CPDF_Point& ptMoveTo,
1434                                 const CPDF_Point& ptLineTo,
1435                                 const FX_COLORREF& color,
1436                                 FX_FLOAT fWidth) {
1437   CFX_PathData path;
1438   path.SetPointCount(2);
1439   path.SetPoint(0, ptMoveTo.x, ptMoveTo.y, FXPT_MOVETO);
1440   path.SetPoint(1, ptLineTo.x, ptLineTo.y, FXPT_LINETO);
1441
1442   CFX_GraphStateData gsd;
1443   gsd.m_LineWidth = fWidth;
1444
1445   pDevice->DrawPath(&path, pUser2Device, &gsd, 0, color, FXFILL_ALTERNATE);
1446 }
1447
1448 void CPWL_Utils::DrawFillRect(CFX_RenderDevice* pDevice,
1449                               CPDF_Matrix* pUser2Device,
1450                               const CPDF_Rect& rect,
1451                               const CPWL_Color& color,
1452                               int32_t nTransparancy) {
1453   CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rect,
1454                            PWLColorToFXColor(color, nTransparancy));
1455 }
1456
1457 void CPWL_Utils::DrawShadow(CFX_RenderDevice* pDevice,
1458                             CPDF_Matrix* pUser2Device,
1459                             FX_BOOL bVertical,
1460                             FX_BOOL bHorizontal,
1461                             CPDF_Rect rect,
1462                             int32_t nTransparancy,
1463                             int32_t nStartGray,
1464                             int32_t nEndGray) {
1465   FX_FLOAT fStepGray = 1.0f;
1466
1467   if (bVertical) {
1468     fStepGray = (nEndGray - nStartGray) / rect.Height();
1469
1470     for (FX_FLOAT fy = rect.bottom + 0.5f; fy <= rect.top - 0.5f; fy += 1.0f) {
1471       int32_t nGray = nStartGray + (int32_t)(fStepGray * (fy - rect.bottom));
1472       CPWL_Utils::DrawStrokeLine(
1473           pDevice, pUser2Device, CPDF_Point(rect.left, fy),
1474           CPDF_Point(rect.right, fy),
1475           ArgbEncode(nTransparancy, nGray, nGray, nGray), 1.5f);
1476     }
1477   }
1478
1479   if (bHorizontal) {
1480     fStepGray = (nEndGray - nStartGray) / rect.Width();
1481
1482     for (FX_FLOAT fx = rect.left + 0.5f; fx <= rect.right - 0.5f; fx += 1.0f) {
1483       int32_t nGray = nStartGray + (int32_t)(fStepGray * (fx - rect.left));
1484       CPWL_Utils::DrawStrokeLine(
1485           pDevice, pUser2Device, CPDF_Point(fx, rect.bottom),
1486           CPDF_Point(fx, rect.top),
1487           ArgbEncode(nTransparancy, nGray, nGray, nGray), 1.5f);
1488     }
1489   }
1490 }
1491
1492 void CPWL_Utils::DrawBorder(CFX_RenderDevice* pDevice,
1493                             CPDF_Matrix* pUser2Device,
1494                             const CPDF_Rect& rect,
1495                             FX_FLOAT fWidth,
1496                             const CPWL_Color& color,
1497                             const CPWL_Color& crLeftTop,
1498                             const CPWL_Color& crRightBottom,
1499                             int32_t nStyle,
1500                             const CPWL_Dash& dash,
1501                             int32_t nTransparancy) {
1502   FX_FLOAT fLeft = rect.left;
1503   FX_FLOAT fRight = rect.right;
1504   FX_FLOAT fTop = rect.top;
1505   FX_FLOAT fBottom = rect.bottom;
1506
1507   if (fWidth > 0.0f) {
1508     FX_FLOAT fHalfWidth = fWidth / 2.0f;
1509
1510     switch (nStyle) {
1511       default:
1512       case PBS_SOLID: {
1513         CFX_PathData path;
1514         path.AppendRect(fLeft, fBottom, fRight, fTop);
1515         path.AppendRect(fLeft + fWidth, fBottom + fWidth, fRight - fWidth,
1516                         fTop - fWidth);
1517         pDevice->DrawPath(&path, pUser2Device, NULL,
1518                           PWLColorToFXColor(color, nTransparancy), 0,
1519                           FXFILL_ALTERNATE);
1520       } break;
1521       case PBS_DASH: {
1522         CFX_PathData path;
1523
1524         path.SetPointCount(5);
1525         path.SetPoint(0, fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f,
1526                       FXPT_MOVETO);
1527         path.SetPoint(1, fLeft + fWidth / 2.0f, fTop - fWidth / 2.0f,
1528                       FXPT_LINETO);
1529         path.SetPoint(2, fRight - fWidth / 2.0f, fTop - fWidth / 2.0f,
1530                       FXPT_LINETO);
1531         path.SetPoint(3, fRight - fWidth / 2.0f, fBottom + fWidth / 2.0f,
1532                       FXPT_LINETO);
1533         path.SetPoint(4, fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f,
1534                       FXPT_LINETO);
1535
1536         CFX_GraphStateData gsd;
1537         gsd.SetDashCount(2);
1538         gsd.m_DashArray[0] = 3.0f;
1539         gsd.m_DashArray[1] = 3.0f;
1540         gsd.m_DashPhase = 0;
1541
1542         gsd.m_LineWidth = fWidth;
1543         pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
1544                           PWLColorToFXColor(color, nTransparancy),
1545                           FXFILL_WINDING);
1546       } break;
1547       case PBS_BEVELED:
1548       case PBS_INSET: {
1549         CFX_GraphStateData gsd;
1550         gsd.m_LineWidth = fHalfWidth;
1551
1552         CFX_PathData pathLT;
1553
1554         pathLT.SetPointCount(7);
1555         pathLT.SetPoint(0, fLeft + fHalfWidth, fBottom + fHalfWidth,
1556                         FXPT_MOVETO);
1557         pathLT.SetPoint(1, fLeft + fHalfWidth, fTop - fHalfWidth, FXPT_LINETO);
1558         pathLT.SetPoint(2, fRight - fHalfWidth, fTop - fHalfWidth, FXPT_LINETO);
1559         pathLT.SetPoint(3, fRight - fHalfWidth * 2, fTop - fHalfWidth * 2,
1560                         FXPT_LINETO);
1561         pathLT.SetPoint(4, fLeft + fHalfWidth * 2, fTop - fHalfWidth * 2,
1562                         FXPT_LINETO);
1563         pathLT.SetPoint(5, fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2,
1564                         FXPT_LINETO);
1565         pathLT.SetPoint(6, fLeft + fHalfWidth, fBottom + fHalfWidth,
1566                         FXPT_LINETO);
1567
1568         pDevice->DrawPath(&pathLT, pUser2Device, &gsd,
1569                           PWLColorToFXColor(crLeftTop, nTransparancy), 0,
1570                           FXFILL_ALTERNATE);
1571
1572         CFX_PathData pathRB;
1573
1574         pathRB.SetPointCount(7);
1575         pathRB.SetPoint(0, fRight - fHalfWidth, fTop - fHalfWidth, FXPT_MOVETO);
1576         pathRB.SetPoint(1, fRight - fHalfWidth, fBottom + fHalfWidth,
1577                         FXPT_LINETO);
1578         pathRB.SetPoint(2, fLeft + fHalfWidth, fBottom + fHalfWidth,
1579                         FXPT_LINETO);
1580         pathRB.SetPoint(3, fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2,
1581                         FXPT_LINETO);
1582         pathRB.SetPoint(4, fRight - fHalfWidth * 2, fBottom + fHalfWidth * 2,
1583                         FXPT_LINETO);
1584         pathRB.SetPoint(5, fRight - fHalfWidth * 2, fTop - fHalfWidth * 2,
1585                         FXPT_LINETO);
1586         pathRB.SetPoint(6, fRight - fHalfWidth, fTop - fHalfWidth, FXPT_LINETO);
1587
1588         pDevice->DrawPath(&pathRB, pUser2Device, &gsd,
1589                           PWLColorToFXColor(crRightBottom, nTransparancy), 0,
1590                           FXFILL_ALTERNATE);
1591
1592         CFX_PathData path;
1593
1594         path.AppendRect(fLeft, fBottom, fRight, fTop);
1595         path.AppendRect(fLeft + fHalfWidth, fBottom + fHalfWidth,
1596                         fRight - fHalfWidth, fTop - fHalfWidth);
1597
1598         pDevice->DrawPath(&path, pUser2Device, &gsd,
1599                           PWLColorToFXColor(color, nTransparancy), 0,
1600                           FXFILL_ALTERNATE);
1601       } break;
1602       case PBS_UNDERLINED: {
1603         CFX_PathData path;
1604
1605         path.SetPointCount(2);
1606         path.SetPoint(0, fLeft, fBottom + fWidth / 2, FXPT_MOVETO);
1607         path.SetPoint(1, fRight, fBottom + fWidth / 2, FXPT_LINETO);
1608
1609         CFX_GraphStateData gsd;
1610         gsd.m_LineWidth = fWidth;
1611
1612         pDevice->DrawPath(&path, pUser2Device, &gsd, 0,
1613                           PWLColorToFXColor(color, nTransparancy),
1614                           FXFILL_ALTERNATE);
1615       } break;
1616       case PBS_SHADOW: {
1617         CFX_PathData path;
1618         path.AppendRect(fLeft, fBottom, fRight, fTop);
1619         path.AppendRect(fLeft + fWidth, fBottom + fWidth, fRight - fWidth,
1620                         fTop - fWidth);
1621         pDevice->DrawPath(&path, pUser2Device, NULL,
1622                           PWLColorToFXColor(color, nTransparancy / 2), 0,
1623                           FXFILL_ALTERNATE);
1624       } break;
1625     }
1626   }
1627 }
1628
1629 static void AddSquigglyPath(CFX_PathData& PathData,
1630                             FX_FLOAT fStartX,
1631                             FX_FLOAT fEndX,
1632                             FX_FLOAT fY,
1633                             FX_FLOAT fStep) {
1634   PathData.AddPointCount(1);
1635   PathData.SetPoint(PathData.GetPointCount() - 1, fStartX, fY, FXPT_MOVETO);
1636
1637   FX_FLOAT fx;
1638   int32_t i;
1639
1640   for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {
1641     PathData.AddPointCount(1);
1642     PathData.SetPoint(PathData.GetPointCount() - 1, fx, fY + (i & 1) * fStep,
1643                       FXPT_LINETO);
1644   }
1645 }
1646
1647 static void AddSpellCheckObj(CFX_PathData& PathData,
1648                              IFX_Edit* pEdit,
1649                              const CPVT_WordRange& wrWord) {
1650   FX_FLOAT fStartX = 0.0f;
1651   FX_FLOAT fEndX = 0.0f;
1652   FX_FLOAT fY = 0.0f;
1653   FX_FLOAT fStep = 0.0f;
1654
1655   FX_BOOL bBreak = FALSE;
1656
1657   if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
1658     pIterator->SetAt(wrWord.BeginPos);
1659
1660     do {
1661       CPVT_WordPlace place = pIterator->GetAt();
1662
1663       CPVT_Line line;
1664       if (pIterator->GetLine(line)) {
1665         fY = line.ptLine.y;
1666         fStep = (line.fLineAscent - line.fLineDescent) / 16.0f;
1667       }
1668
1669       if (place.LineCmp(wrWord.BeginPos) == 0) {
1670         pIterator->SetAt(wrWord.BeginPos);
1671         CPVT_Word word;
1672         if (pIterator->GetWord(word)) {
1673           fStartX = word.ptWord.x;
1674         }
1675       } else {
1676         fStartX = line.ptLine.x;
1677       }
1678
1679       if (place.LineCmp(wrWord.EndPos) == 0) {
1680         pIterator->SetAt(wrWord.EndPos);
1681         CPVT_Word word;
1682         if (pIterator->GetWord(word)) {
1683           fEndX = word.ptWord.x + word.fWidth;
1684         }
1685
1686         bBreak = TRUE;
1687       } else {
1688         fEndX = line.ptLine.x + line.fLineWidth;
1689       }
1690
1691       AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep);
1692
1693       if (bBreak)
1694         break;
1695     } while (pIterator->NextLine());
1696   }
1697 }
1698
1699 void CPWL_Utils::DrawEditSpellCheck(CFX_RenderDevice* pDevice,
1700                                     CPDF_Matrix* pUser2Device,
1701                                     IFX_Edit* pEdit,
1702                                     const CPDF_Rect& rcClip,
1703                                     const CPDF_Point& ptOffset,
1704                                     const CPVT_WordRange* pRange,
1705                                     IPWL_SpellCheck* pSpellCheck) {
1706   const FX_COLORREF crSpell = ArgbEncode(255, 255, 0, 0);
1707
1708   // for spellcheck
1709   FX_BOOL bLatinWord = FALSE;
1710   CPVT_WordPlace wpWordStart;
1711   CFX_ByteString sLatinWord;
1712
1713   CFX_PathData pathSpell;
1714
1715   pDevice->SaveState();
1716
1717   if (!rcClip.IsEmpty()) {
1718     CPDF_Rect rcTemp = rcClip;
1719     pUser2Device->TransformRect(rcTemp);
1720     FX_RECT rcDevClip;
1721     rcDevClip.left = (int32_t)rcTemp.left;
1722     rcDevClip.right = (int32_t)rcTemp.right;
1723     rcDevClip.top = (int32_t)rcTemp.top;
1724     rcDevClip.bottom = (int32_t)rcTemp.bottom;
1725     pDevice->SetClip_Rect(&rcDevClip);
1726   }
1727
1728   if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) {
1729     if (pEdit->GetFontMap()) {
1730       if (pRange)
1731         pIterator->SetAt(pRange->BeginPos);
1732       else
1733         pIterator->SetAt(0);
1734
1735       CPVT_WordPlace oldplace;
1736
1737       while (pIterator->NextWord()) {
1738         CPVT_WordPlace place = pIterator->GetAt();
1739         if (pRange && place.WordCmp(pRange->EndPos) > 0)
1740           break;
1741
1742         CPVT_Word word;
1743         if (pIterator->GetWord(word)) {
1744           if (FX_EDIT_ISLATINWORD(word.Word)) {
1745             if (!bLatinWord) {
1746               wpWordStart = place;
1747               bLatinWord = TRUE;
1748             }
1749
1750             sLatinWord += (char)word.Word;
1751           } else {
1752             if (bLatinWord) {
1753               if (!sLatinWord.IsEmpty()) {
1754                 if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) {
1755                   AddSpellCheckObj(pathSpell, pEdit,
1756                                    CPVT_WordRange(wpWordStart, oldplace));
1757                   pIterator->SetAt(place);
1758                 }
1759               }
1760               bLatinWord = FALSE;
1761             }
1762
1763             sLatinWord.Empty();
1764           }
1765
1766           oldplace = place;
1767         } else {
1768           if (bLatinWord) {
1769             if (!sLatinWord.IsEmpty()) {
1770               if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) {
1771                 AddSpellCheckObj(pathSpell, pEdit,
1772                                  CPVT_WordRange(wpWordStart, oldplace));
1773                 pIterator->SetAt(place);
1774               }
1775             }
1776             bLatinWord = FALSE;
1777           }
1778
1779           sLatinWord.Empty();
1780         }
1781       }
1782
1783       if (!sLatinWord.IsEmpty()) {
1784         if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) {
1785           AddSpellCheckObj(pathSpell, pEdit,
1786                            CPVT_WordRange(wpWordStart, oldplace));
1787         }
1788       }
1789     }
1790   }
1791
1792   CFX_GraphStateData gsd;
1793   gsd.m_LineWidth = 0;
1794   if (pathSpell.GetPointCount() > 0)
1795     pDevice->DrawPath(&pathSpell, pUser2Device, &gsd, 0, crSpell,
1796                       FXFILL_ALTERNATE);
1797
1798   pDevice->RestoreState();
1799 }
1800
1801 FX_BOOL CPWL_Utils::IsBlackOrWhite(const CPWL_Color& color) {
1802   switch (color.nColorType) {
1803     case COLORTYPE_TRANSPARENT:
1804       return FALSE;
1805     case COLORTYPE_GRAY:
1806       return color.fColor1 < 0.5f;
1807     case COLORTYPE_RGB:
1808       return color.fColor1 + color.fColor2 + color.fColor3 < 1.5f;
1809     case COLORTYPE_CMYK:
1810       return color.fColor1 + color.fColor2 + color.fColor3 + color.fColor4 >
1811              2.0f;
1812   }
1813
1814   return TRUE;
1815 }
1816
1817 CPWL_Color CPWL_Utils::GetReverseColor(const CPWL_Color& color) {
1818   CPWL_Color crRet = color;
1819
1820   switch (color.nColorType) {
1821     case COLORTYPE_GRAY:
1822       crRet.fColor1 = 1.0f - crRet.fColor1;
1823       break;
1824     case COLORTYPE_RGB:
1825       crRet.fColor1 = 1.0f - crRet.fColor1;
1826       crRet.fColor2 = 1.0f - crRet.fColor2;
1827       crRet.fColor3 = 1.0f - crRet.fColor3;
1828       break;
1829     case COLORTYPE_CMYK:
1830       crRet.fColor1 = 1.0f - crRet.fColor1;
1831       crRet.fColor2 = 1.0f - crRet.fColor2;
1832       crRet.fColor3 = 1.0f - crRet.fColor3;
1833       crRet.fColor4 = 1.0f - crRet.fColor4;
1834       break;
1835   }
1836
1837   return crRet;
1838 }
1839
1840 CFX_ByteString CPWL_Utils::GetIconAppStream(int32_t nType,
1841                                             const CPDF_Rect& rect,
1842                                             const CPWL_Color& crFill,
1843                                             const CPWL_Color& crStroke) {
1844   CFX_ByteString sAppStream = CPWL_Utils::GetColorAppStream(crStroke, FALSE);
1845   sAppStream += CPWL_Utils::GetColorAppStream(crFill, TRUE);
1846
1847   CFX_ByteString sPath;
1848   CFX_PathData path;
1849
1850   switch (nType) {
1851     case PWL_ICONTYPE_CHECKMARK:
1852       GetGraphics_Checkmark(sPath, path, rect, PWLPT_STREAM);
1853       break;
1854     case PWL_ICONTYPE_CIRCLE:
1855       GetGraphics_Circle(sPath, path, rect, PWLPT_STREAM);
1856       break;
1857     case PWL_ICONTYPE_COMMENT:
1858       GetGraphics_Comment(sPath, path, rect, PWLPT_STREAM);
1859       break;
1860     case PWL_ICONTYPE_CROSS:
1861       GetGraphics_Cross(sPath, path, rect, PWLPT_STREAM);
1862       break;
1863     case PWL_ICONTYPE_HELP:
1864       GetGraphics_Help(sPath, path, rect, PWLPT_STREAM);
1865       break;
1866     case PWL_ICONTYPE_INSERTTEXT:
1867       GetGraphics_InsertText(sPath, path, rect, PWLPT_STREAM);
1868       break;
1869     case PWL_ICONTYPE_KEY:
1870       GetGraphics_Key(sPath, path, rect, PWLPT_STREAM);
1871       break;
1872     case PWL_ICONTYPE_NEWPARAGRAPH:
1873       GetGraphics_NewParagraph(sPath, path, rect, PWLPT_STREAM);
1874       break;
1875     case PWL_ICONTYPE_TEXTNOTE:
1876       GetGraphics_TextNote(sPath, path, rect, PWLPT_STREAM);
1877       break;
1878     case PWL_ICONTYPE_PARAGRAPH:
1879       GetGraphics_Paragraph(sPath, path, rect, PWLPT_STREAM);
1880       break;
1881     case PWL_ICONTYPE_RIGHTARROW:
1882       GetGraphics_RightArrow(sPath, path, rect, PWLPT_STREAM);
1883       break;
1884     case PWL_ICONTYPE_RIGHTPOINTER:
1885       GetGraphics_RightPointer(sPath, path, rect, PWLPT_STREAM);
1886       break;
1887     case PWL_ICONTYPE_STAR:
1888       GetGraphics_Star(sPath, path, rect, PWLPT_STREAM);
1889       break;
1890     case PWL_ICONTYPE_UPARROW:
1891       GetGraphics_UpArrow(sPath, path, rect, PWLPT_STREAM);
1892       break;
1893     case PWL_ICONTYPE_UPLEFTARROW:
1894       GetGraphics_UpLeftArrow(sPath, path, rect, PWLPT_STREAM);
1895       break;
1896     case PWL_ICONTYPE_GRAPH:
1897       GetGraphics_Graph(sPath, path, rect, PWLPT_STREAM);
1898       break;
1899     case PWL_ICONTYPE_PAPERCLIP:
1900       GetGraphics_Paperclip(sPath, path, rect, PWLPT_STREAM);
1901       break;
1902     case PWL_ICONTYPE_ATTACHMENT:
1903       GetGraphics_Attachment(sPath, path, rect, PWLPT_STREAM);
1904       break;
1905     case PWL_ICONTYPE_TAG:
1906       GetGraphics_Tag(sPath, path, rect, PWLPT_STREAM);
1907       break;
1908     case PWL_ICONTYPE_FOXIT:
1909       GetGraphics_Foxit(sPath, path, rect, PWLPT_STREAM);
1910       break;
1911   }
1912
1913   sAppStream += sPath;
1914   if (crStroke.nColorType != COLORTYPE_TRANSPARENT)
1915     sAppStream += "B*\n";
1916   else
1917     sAppStream += "f*\n";
1918
1919   return sAppStream;
1920 }
1921
1922 void CPWL_Utils::DrawIconAppStream(CFX_RenderDevice* pDevice,
1923                                    CPDF_Matrix* pUser2Device,
1924                                    int32_t nType,
1925                                    const CPDF_Rect& rect,
1926                                    const CPWL_Color& crFill,
1927                                    const CPWL_Color& crStroke,
1928                                    const int32_t nTransparancy) {
1929   CFX_GraphStateData gsd;
1930   gsd.m_LineWidth = 1.0f;
1931
1932   CFX_ByteString sPath;
1933   CFX_PathData path;
1934
1935   switch (nType) {
1936     case PWL_ICONTYPE_CHECKMARK:
1937       GetGraphics_Checkmark(sPath, path, rect, PWLPT_PATHDATA);
1938       break;
1939     case PWL_ICONTYPE_CIRCLE:
1940       GetGraphics_Circle(sPath, path, rect, PWLPT_PATHDATA);
1941       break;
1942     case PWL_ICONTYPE_COMMENT:
1943       GetGraphics_Comment(sPath, path, rect, PWLPT_PATHDATA);
1944       break;
1945     case PWL_ICONTYPE_CROSS:
1946       GetGraphics_Cross(sPath, path, rect, PWLPT_PATHDATA);
1947       break;
1948     case PWL_ICONTYPE_HELP:
1949       GetGraphics_Help(sPath, path, rect, PWLPT_PATHDATA);
1950       break;
1951     case PWL_ICONTYPE_INSERTTEXT:
1952       GetGraphics_InsertText(sPath, path, rect, PWLPT_PATHDATA);
1953       break;
1954     case PWL_ICONTYPE_KEY:
1955       GetGraphics_Key(sPath, path, rect, PWLPT_PATHDATA);
1956       break;
1957     case PWL_ICONTYPE_NEWPARAGRAPH:
1958       GetGraphics_NewParagraph(sPath, path, rect, PWLPT_PATHDATA);
1959       break;
1960     case PWL_ICONTYPE_TEXTNOTE:
1961       GetGraphics_TextNote(sPath, path, rect, PWLPT_PATHDATA);
1962       break;
1963     case PWL_ICONTYPE_PARAGRAPH:
1964       GetGraphics_Paragraph(sPath, path, rect, PWLPT_PATHDATA);
1965       break;
1966     case PWL_ICONTYPE_RIGHTARROW:
1967       GetGraphics_RightArrow(sPath, path, rect, PWLPT_PATHDATA);
1968       break;
1969     case PWL_ICONTYPE_RIGHTPOINTER:
1970       GetGraphics_RightPointer(sPath, path, rect, PWLPT_PATHDATA);
1971       break;
1972     case PWL_ICONTYPE_STAR:
1973       GetGraphics_Star(sPath, path, rect, PWLPT_PATHDATA);
1974       break;
1975     case PWL_ICONTYPE_UPARROW:
1976       GetGraphics_UpArrow(sPath, path, rect, PWLPT_PATHDATA);
1977       break;
1978     case PWL_ICONTYPE_UPLEFTARROW:
1979       GetGraphics_UpLeftArrow(sPath, path, rect, PWLPT_PATHDATA);
1980       break;
1981     case PWL_ICONTYPE_GRAPH:
1982       GetGraphics_Graph(sPath, path, rect, PWLPT_PATHDATA);
1983       break;
1984     case PWL_ICONTYPE_PAPERCLIP:
1985       GetGraphics_Paperclip(sPath, path, rect, PWLPT_PATHDATA);
1986       break;
1987     case PWL_ICONTYPE_ATTACHMENT:
1988       GetGraphics_Attachment(sPath, path, rect, PWLPT_PATHDATA);
1989       break;
1990     case PWL_ICONTYPE_TAG:
1991       GetGraphics_Tag(sPath, path, rect, PWLPT_PATHDATA);
1992       break;
1993     case PWL_ICONTYPE_FOXIT:
1994       GetGraphics_Foxit(sPath, path, rect, PWLPT_PATHDATA);
1995       break;
1996     default:
1997       return;
1998   }
1999
2000   pDevice->DrawPath(
2001       &path, pUser2Device, &gsd, PWLColorToFXColor(crFill, nTransparancy),
2002       PWLColorToFXColor(crStroke, nTransparancy), FXFILL_ALTERNATE);
2003 }
2004
2005 void CPWL_Utils::GetGraphics_Checkmark(CFX_ByteString& sPathData,
2006                                        CFX_PathData& path,
2007                                        const CPDF_Rect& crBBox,
2008                                        const PWL_PATH_TYPE type) {
2009   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2010   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2011
2012   CPWL_PathData PathArray[] = {
2013       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
2014                                crBBox.bottom + fHeight * 2 / 5.0f),
2015                     PWLPT_MOVETO),
2016       CPWL_PathData(
2017           CPWL_Point(
2018               crBBox.left + fWidth / 15.0f +
2019                   PWL_BEZIER * (fWidth / 7.0f - fWidth / 15.0f),
2020               crBBox.bottom + fHeight * 2 / 5.0f +
2021                   PWL_BEZIER * (fHeight * 2 / 7.0f - fHeight * 2 / 5.0f)),
2022           PWLPT_BEZIERTO),
2023       CPWL_PathData(
2024           CPWL_Point(crBBox.left + fWidth / 4.5f +
2025                          PWL_BEZIER * (fWidth / 5.0f - fWidth / 4.5f),
2026                      crBBox.bottom + fHeight / 16.0f +
2027                          PWL_BEZIER * (fHeight / 5.0f - fHeight / 16.0f)),
2028           PWLPT_BEZIERTO),
2029       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 4.5f,
2030                                crBBox.bottom + fHeight / 16.0f),
2031                     PWLPT_BEZIERTO),
2032       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 4.5f +
2033                                    PWL_BEZIER * (fWidth / 4.4f - fWidth / 4.5f),
2034                                crBBox.bottom + fHeight / 16.0f -
2035                                    PWL_BEZIER * fHeight / 16.0f),
2036                     PWLPT_BEZIERTO),
2037       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f +
2038                                    PWL_BEZIER * (fWidth / 4.0f - fWidth / 3.0f),
2039                                crBBox.bottom),
2040                     PWLPT_BEZIERTO),
2041       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f, crBBox.bottom),
2042                     PWLPT_BEZIERTO),
2043       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f +
2044                                    PWL_BEZIER * fWidth * (1 / 7.0f + 2 / 15.0f),
2045                                crBBox.bottom + PWL_BEZIER * fHeight * 4 / 5.0f),
2046                     PWLPT_BEZIERTO),
2047       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 14 / 15.0f +
2048                                    PWL_BEZIER * fWidth * (1 / 7.0f - 7 / 15.0f),
2049                                crBBox.bottom + fHeight * 15 / 16.0f +
2050                                    PWL_BEZIER * (fHeight * 4 / 5.0f -
2051                                                  fHeight * 15 / 16.0f)),
2052                     PWLPT_BEZIERTO),
2053       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 14 / 15.0f,
2054                                crBBox.bottom + fHeight * 15 / 16.0f),
2055                     PWLPT_BEZIERTO),
2056       CPWL_PathData(
2057           CPWL_Point(
2058               crBBox.left + fWidth * 14 / 15.0f +
2059                   PWL_BEZIER * (fWidth * 7 / 15.0f - fWidth * 14 / 15.0f),
2060               crBBox.bottom + fHeight * 15 / 16.0f +
2061                   PWL_BEZIER * (fHeight * 8 / 7.0f - fHeight * 15 / 16.0f)),
2062           PWLPT_BEZIERTO),
2063       CPWL_PathData(
2064           CPWL_Point(crBBox.left + fWidth / 3.6f +
2065                          PWL_BEZIER * (fWidth / 3.4f - fWidth / 3.6f),
2066                      crBBox.bottom + fHeight / 3.5f +
2067                          PWL_BEZIER * (fHeight / 3.5f - fHeight / 3.5f)),
2068           PWLPT_BEZIERTO),
2069       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.6f,
2070                                crBBox.bottom + fHeight / 3.5f),
2071                     PWLPT_BEZIERTO),
2072       CPWL_PathData(
2073           CPWL_Point(crBBox.left + fWidth / 3.6f,
2074                      crBBox.bottom + fHeight / 3.5f +
2075                          PWL_BEZIER * (fHeight / 4.0f - fHeight / 3.5f)),
2076           PWLPT_BEZIERTO),
2077       CPWL_PathData(
2078           CPWL_Point(
2079               crBBox.left + fWidth / 15.0f +
2080                   PWL_BEZIER * (fWidth / 3.5f - fWidth / 15.0f),
2081               crBBox.bottom + fHeight * 2 / 5.0f +
2082                   PWL_BEZIER * (fHeight * 3.5f / 5.0f - fHeight * 2 / 5.0f)),
2083           PWLPT_BEZIERTO),
2084       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
2085                                crBBox.bottom + fHeight * 2 / 5.0f),
2086                     PWLPT_BEZIERTO)};
2087
2088   if (type == PWLPT_STREAM)
2089     sPathData = GetAppStreamFromArray(PathArray, 16);
2090   else
2091     GetPathDataFromArray(path, PathArray, 16);
2092 }
2093
2094 void CPWL_Utils::GetGraphics_Circle(CFX_ByteString& sPathData,
2095                                     CFX_PathData& path,
2096                                     const CPDF_Rect& crBBox,
2097                                     const PWL_PATH_TYPE type) {
2098   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2099   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2100
2101   CPWL_PathData PathArray[] = {
2102       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
2103                                crBBox.bottom + fHeight / 2.0f),
2104                     PWLPT_MOVETO),
2105       CPWL_PathData(
2106           CPWL_Point(crBBox.left + fWidth / 15.0f,
2107                      crBBox.bottom + fHeight / 2.0f +
2108                          PWL_BEZIER * (fHeight * 14 / 15.0f - fHeight / 2.0f)),
2109           PWLPT_BEZIERTO),
2110       CPWL_PathData(
2111           CPWL_Point(crBBox.left + fWidth / 2.0f -
2112                          PWL_BEZIER * (fWidth / 2.0f - fWidth / 15.0f),
2113                      crBBox.top - fHeight / 15.0f),
2114           PWLPT_BEZIERTO),
2115       CPWL_PathData(
2116           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f),
2117           PWLPT_BEZIERTO),
2118       CPWL_PathData(
2119           CPWL_Point(crBBox.left + fWidth / 2.0f +
2120                          PWL_BEZIER * (fWidth * 14 / 15.0f - fWidth / 2.0f),
2121                      crBBox.top - fHeight / 15.0f),
2122           PWLPT_BEZIERTO),
2123       CPWL_PathData(
2124           CPWL_Point(crBBox.right - fWidth / 15.0f,
2125                      crBBox.bottom + fHeight / 2.0f +
2126                          PWL_BEZIER * (fHeight * 14 / 15.0f - fHeight / 2.0f)),
2127           PWLPT_BEZIERTO),
2128       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
2129                                crBBox.bottom + fHeight / 2.0f),
2130                     PWLPT_BEZIERTO),
2131       CPWL_PathData(
2132           CPWL_Point(crBBox.right - fWidth / 15.0f,
2133                      crBBox.bottom + fHeight / 2.0f -
2134                          PWL_BEZIER * (fHeight / 2.0f - fHeight / 15.0f)),
2135           PWLPT_BEZIERTO),
2136       CPWL_PathData(
2137           CPWL_Point(crBBox.left + fWidth / 2.0f +
2138                          PWL_BEZIER * (fWidth * 14 / 15.0f - fWidth / 2.0f),
2139                      crBBox.bottom + fHeight / 15.0f),
2140           PWLPT_BEZIERTO),
2141       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
2142                                crBBox.bottom + fHeight / 15.0f),
2143                     PWLPT_BEZIERTO),
2144       CPWL_PathData(
2145           CPWL_Point(crBBox.left + fWidth / 2.0f -
2146                          PWL_BEZIER * (fWidth / 2.0f - fWidth / 15.0f),
2147                      crBBox.bottom + fHeight / 15.0f),
2148           PWLPT_BEZIERTO),
2149       CPWL_PathData(
2150           CPWL_Point(crBBox.left + fWidth / 15.0f,
2151                      crBBox.bottom + fHeight / 2.0f -
2152                          PWL_BEZIER * (fHeight / 2.0f - fHeight / 15.0f)),
2153           PWLPT_BEZIERTO),
2154       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
2155                                crBBox.bottom + fHeight / 2.0f),
2156                     PWLPT_BEZIERTO),
2157       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 3 / 15.0f,
2158                                crBBox.bottom + fHeight / 2.0f),
2159                     PWLPT_MOVETO),
2160       CPWL_PathData(
2161           CPWL_Point(crBBox.left + fWidth * 3 / 15.0f,
2162                      crBBox.bottom + fHeight / 2.0f +
2163                          PWL_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
2164           PWLPT_BEZIERTO),
2165       CPWL_PathData(
2166           CPWL_Point(crBBox.left + fWidth / 2.0f -
2167                          PWL_BEZIER * (fWidth / 2.0f - fWidth * 3 / 15.0f),
2168                      crBBox.top - fHeight * 3 / 15.0f),
2169           PWLPT_BEZIERTO),
2170       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
2171                                crBBox.top - fHeight * 3 / 15.0f),
2172                     PWLPT_BEZIERTO),
2173       CPWL_PathData(
2174           CPWL_Point(crBBox.left + fWidth / 2.0f +
2175                          PWL_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
2176                      crBBox.top - fHeight * 3 / 15.0f),
2177           PWLPT_BEZIERTO),
2178       CPWL_PathData(
2179           CPWL_Point(crBBox.right - fWidth * 3 / 15.0f,
2180                      crBBox.bottom + fHeight / 2.0f +
2181                          PWL_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
2182           PWLPT_BEZIERTO),
2183       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 15.0f,
2184                                crBBox.bottom + fHeight / 2.0f),
2185                     PWLPT_BEZIERTO),
2186       CPWL_PathData(
2187           CPWL_Point(crBBox.right - fWidth * 3 / 15.0f,
2188                      crBBox.bottom + fHeight / 2.0f -
2189                          PWL_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
2190           PWLPT_BEZIERTO),
2191       CPWL_PathData(
2192           CPWL_Point(crBBox.left + fWidth / 2.0f +
2193                          PWL_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
2194                      crBBox.bottom + fHeight * 3 / 15.0f),
2195           PWLPT_BEZIERTO),
2196       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
2197                                crBBox.bottom + fHeight * 3 / 15.0f),
2198                     PWLPT_BEZIERTO),
2199       CPWL_PathData(
2200           CPWL_Point(crBBox.left + fWidth / 2.0f -
2201                          PWL_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f),
2202                      crBBox.bottom + fHeight * 3 / 15.0f),
2203           PWLPT_BEZIERTO),
2204       CPWL_PathData(
2205           CPWL_Point(crBBox.left + fWidth * 3 / 15.0f,
2206                      crBBox.bottom + fHeight / 2.0f -
2207                          PWL_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)),
2208           PWLPT_BEZIERTO),
2209       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 3 / 15.0f,
2210                                crBBox.bottom + fHeight / 2.0f),
2211                     PWLPT_BEZIERTO)};
2212
2213   if (type == PWLPT_STREAM)
2214     sPathData = GetAppStreamFromArray(PathArray, 26);
2215   else
2216     GetPathDataFromArray(path, PathArray, 26);
2217 }
2218
2219 void CPWL_Utils::GetGraphics_Comment(CFX_ByteString& sPathData,
2220                                      CFX_PathData& path,
2221                                      const CPDF_Rect& crBBox,
2222                                      const PWL_PATH_TYPE type) {
2223   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2224   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2225
2226   CPWL_PathData PathArray[] = {
2227       CPWL_PathData(
2228           CPWL_Point(crBBox.left + fWidth / 15.0f, crBBox.top - fHeight / 6.0f),
2229           PWLPT_MOVETO),
2230       CPWL_PathData(
2231           CPWL_Point(crBBox.left + fWidth / 15.0f,
2232                      crBBox.top - fHeight / 6.0f +
2233                          PWL_BEZIER * (fHeight / 6.0f - fHeight / 10.0f)),
2234           PWLPT_BEZIERTO),
2235       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f -
2236                                    PWL_BEZIER * fWidth / 15.0f,
2237                                crBBox.top - fHeight / 10.0f),
2238                     PWLPT_BEZIERTO),
2239       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f,
2240                                crBBox.top - fHeight / 10.0f),
2241                     PWLPT_BEZIERTO),
2242       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f,
2243                                crBBox.top - fHeight / 10.0f),
2244                     PWLPT_LINETO),
2245       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f +
2246                                    PWL_BEZIER * fWidth / 15.0f,
2247                                crBBox.top - fHeight / 10.0f),
2248                     PWLPT_BEZIERTO),
2249       CPWL_PathData(
2250           CPWL_Point(crBBox.right - fWidth / 15.0f,
2251                      crBBox.top - fHeight / 6 +
2252                          PWL_BEZIER * (fHeight / 6.0f - fHeight / 10.0f)),
2253           PWLPT_BEZIERTO),
2254       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
2255                                crBBox.top - fHeight / 6.0f),
2256                     PWLPT_BEZIERTO),
2257       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
2258                                crBBox.bottom + fHeight / 3.0f),
2259                     PWLPT_LINETO),
2260       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
2261                                crBBox.bottom + fHeight * 4 / 15.0f +
2262                                    PWL_BEZIER * fHeight / 15.0f),
2263                     PWLPT_BEZIERTO),
2264       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f +
2265                                    PWL_BEZIER * fWidth / 15.0f,
2266                                crBBox.bottom + fHeight * 4 / 15.0f),
2267                     PWLPT_BEZIERTO),
2268       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f,
2269                                crBBox.bottom + fHeight * 4 / 15.0f),
2270                     PWLPT_BEZIERTO),
2271       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 5 / 15.0f,
2272                                crBBox.bottom + fHeight * 4 / 15.0f),
2273                     PWLPT_LINETO),
2274       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 5 / 15.0f,
2275                                crBBox.bottom + fHeight * 2 / 15 +
2276                                    PWL_BEZIER * fHeight * 2 / 15.0f),
2277                     PWLPT_BEZIERTO),
2278       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 5 / 15.0f -
2279                                    PWL_BEZIER * fWidth * 2 / 15.0f,
2280                                crBBox.bottom + fHeight * 2 / 15.0f),
2281                     PWLPT_BEZIERTO),
2282       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 6 / 30.0f,
2283                                crBBox.bottom + fHeight * 2 / 15.0f),
2284                     PWLPT_BEZIERTO),
2285       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f +
2286                                    PWL_BEZIER * fWidth / 30.0f,
2287                                crBBox.bottom + fHeight * 2 / 15.0f),
2288                     PWLPT_BEZIERTO),
2289       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f,
2290                                crBBox.bottom + fHeight * 2 / 15.0f +
2291                                    PWL_BEZIER * fHeight * 2 / 15.0f),
2292                     PWLPT_BEZIERTO),
2293       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f,
2294                                crBBox.bottom + fHeight * 4 / 15.0f),
2295                     PWLPT_BEZIERTO),
2296       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f,
2297                                crBBox.bottom + fHeight * 4 / 15.0f),
2298                     PWLPT_LINETO),
2299       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f -
2300                                    PWL_BEZIER * fWidth / 15.0f,
2301                                crBBox.bottom + fHeight * 4 / 15.0f),
2302                     PWLPT_BEZIERTO),
2303       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
2304                                crBBox.bottom + fHeight / 3.0f -
2305                                    PWL_BEZIER * fHeight / 15.0f),
2306                     PWLPT_BEZIERTO),
2307       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f,
2308                                crBBox.bottom + fHeight / 3.0f),
2309                     PWLPT_BEZIERTO),
2310       CPWL_PathData(
2311           CPWL_Point(crBBox.left + fWidth / 15.0f, crBBox.top - fHeight / 6.0f),
2312           PWLPT_LINETO),
2313       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f,
2314                                crBBox.top - fHeight * 8 / 30.0f),
2315                     PWLPT_MOVETO),
2316       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f,
2317                                crBBox.top - fHeight * 8 / 30.0f),
2318                     PWLPT_LINETO),
2319       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15,
2320                                crBBox.top - fHeight * 25 / 60.0f),
2321                     PWLPT_MOVETO),
2322       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f,
2323                                crBBox.top - fHeight * 25 / 60.0f),
2324                     PWLPT_LINETO),
2325       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f,
2326                                crBBox.top - fHeight * 17 / 30.0f),
2327                     PWLPT_MOVETO),
2328       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 4 / 15.0f,
2329                                crBBox.top - fHeight * 17 / 30.0f),
2330                     PWLPT_LINETO)};
2331
2332   if (type == PWLPT_STREAM)
2333     sPathData = GetAppStreamFromArray(PathArray, 30);
2334   else
2335     GetPathDataFromArray(path, PathArray, 30);
2336 }
2337
2338 void CPWL_Utils::GetGraphics_Cross(CFX_ByteString& sPathData,
2339                                    CFX_PathData& path,
2340                                    const CPDF_Rect& crBBox,
2341                                    const PWL_PATH_TYPE type) {
2342   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2343   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2344   // FX_FLOAT fcatercorner = (FX_FLOAT)sqrt(fWidth*fWidth + fHeight*fHeight);
2345   CPWL_Point center_point(crBBox.left + fWidth / 2,
2346                           crBBox.bottom + fHeight / 2);
2347
2348   CPWL_PathData PathArray[] = {
2349       CPWL_PathData(
2350           CPWL_Point(center_point.x, center_point.y + fHeight / 10.0f),
2351           PWLPT_MOVETO),
2352       CPWL_PathData(
2353           CPWL_Point(center_point.x + fWidth * 0.3f,
2354                      center_point.y + fHeight / 10.0f + fWidth * 0.3f),
2355           PWLPT_LINETO),
2356       CPWL_PathData(CPWL_Point(center_point.x + fWidth / 10.0f + fWidth * 0.3f,
2357                                center_point.y + fHeight * 0.3f),
2358                     PWLPT_LINETO),
2359       CPWL_PathData(CPWL_Point(center_point.x + fWidth / 10.0f, center_point.y),
2360                     PWLPT_LINETO),
2361       CPWL_PathData(CPWL_Point(center_point.x + fWidth / 10.0f + fWidth * 0.3f,
2362                                center_point.y - fHeight * 0.3f),
2363                     PWLPT_LINETO),
2364       CPWL_PathData(
2365           CPWL_Point(center_point.x + fWidth * 0.3f,
2366                      center_point.y - fHeight / 10.0f - fHeight * 0.3f),
2367           PWLPT_LINETO),
2368       CPWL_PathData(
2369           CPWL_Point(center_point.x, center_point.y - fHeight / 10.0f),
2370           PWLPT_LINETO),
2371       CPWL_PathData(CPWL_Point(center_point.x - fWidth * 0.3f,
2372                                center_point.y - fHeight / 10 - fHeight * 0.3f),
2373                     PWLPT_LINETO),
2374       CPWL_PathData(CPWL_Point(center_point.x - fWidth / 10.0f - fWidth * 0.3f,
2375                                center_point.y - fHeight * 0.3f),
2376                     PWLPT_LINETO),
2377       CPWL_PathData(CPWL_Point(center_point.x - fWidth / 10, center_point.y),
2378                     PWLPT_LINETO),
2379       CPWL_PathData(CPWL_Point(center_point.x - fWidth / 10 - fWidth * 0.3f,
2380                                center_point.y + fHeight * 0.3f),
2381                     PWLPT_LINETO),
2382       CPWL_PathData(
2383           CPWL_Point(center_point.x - fWidth * 0.3f,
2384                      center_point.y + fHeight / 10.0f + fHeight * 0.3f),
2385           PWLPT_LINETO),
2386       CPWL_PathData(
2387           CPWL_Point(center_point.x, center_point.y + fHeight / 10.0f),
2388           PWLPT_LINETO)};
2389
2390   if (type == PWLPT_STREAM)
2391     sPathData = GetAppStreamFromArray(PathArray, 13);
2392   else
2393     GetPathDataFromArray(path, PathArray, 13);
2394 }
2395
2396 void CPWL_Utils::GetGraphics_Help(CFX_ByteString& sPathData,
2397                                   CFX_PathData& path,
2398                                   const CPDF_Rect& crBBox,
2399                                   const PWL_PATH_TYPE type) {
2400   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2401   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2402
2403   CPWL_PathData PathArray[] = {
2404       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60.0f,
2405                                crBBox.bottom + fHeight / 2.0f),
2406                     PWLPT_MOVETO),
2407       CPWL_PathData(
2408           CPWL_Point(crBBox.left + fWidth / 60.0f,
2409                      crBBox.bottom + fHeight / 2.0f +
2410                          PWL_BEZIER * (fHeight / 60.0f - fHeight / 2.0f)),
2411           PWLPT_BEZIERTO),
2412       CPWL_PathData(
2413           CPWL_Point(crBBox.left + fWidth / 2.0f -
2414                          PWL_BEZIER * (fWidth / 2.0f - fWidth / 60.0f),
2415                      crBBox.bottom + fHeight / 60.0f),
2416           PWLPT_BEZIERTO),
2417       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
2418                                crBBox.bottom + fHeight / 60.0f),
2419                     PWLPT_BEZIERTO),
2420       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f +
2421                                    PWL_BEZIER * fWidth * 29 / 60.0f,
2422                                crBBox.bottom + fHeight / 60.0f),
2423                     PWLPT_BEZIERTO),
2424       CPWL_PathData(
2425           CPWL_Point(crBBox.right - fWidth / 60.0f,
2426                      crBBox.bottom + fHeight / 2.0f +
2427                          PWL_BEZIER * (fHeight / 60.0f - fHeight / 2.0f)),
2428           PWLPT_BEZIERTO),
2429       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 60.0f,
2430                                crBBox.bottom + fHeight / 2.0f),
2431                     PWLPT_BEZIERTO),
2432       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 60.0f,
2433                                crBBox.bottom + fHeight / 2.0f +
2434                                    PWL_BEZIER * fHeight * 29 / 60.0f),
2435                     PWLPT_BEZIERTO),
2436       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f +
2437                                    PWL_BEZIER * fWidth * 29 / 60.0f,
2438                                crBBox.top - fHeight / 60.0f),
2439                     PWLPT_BEZIERTO),
2440       CPWL_PathData(
2441           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 60.0f),
2442           PWLPT_BEZIERTO),
2443       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f -
2444                                    PWL_BEZIER * fWidth * 29 / 60.0f,
2445                                crBBox.top - fHeight / 60.0f),
2446                     PWLPT_BEZIERTO),
2447       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60.0f,
2448                                crBBox.bottom + fHeight / 2.0f +
2449                                    PWL_BEZIER * fHeight * 29 / 60.0f),
2450                     PWLPT_BEZIERTO),
2451       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60.0f,
2452                                crBBox.bottom + fHeight / 2.0f),
2453                     PWLPT_BEZIERTO),
2454       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.27f,
2455                                crBBox.top - fHeight * 0.36f),
2456                     PWLPT_MOVETO),
2457       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.27f,
2458                                crBBox.top - fHeight * 0.36f +
2459                                    PWL_BEZIER * fHeight * 0.23f),
2460                     PWLPT_BEZIERTO),
2461       CPWL_PathData(
2462           CPWL_Point(crBBox.left + fWidth * 0.5f - PWL_BEZIER * fWidth * 0.23f,
2463                      crBBox.bottom + fHeight * 0.87f),
2464           PWLPT_BEZIERTO),
2465       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.5f,
2466                                crBBox.bottom + fHeight * 0.87f),
2467                     PWLPT_BEZIERTO),
2468       CPWL_PathData(
2469           CPWL_Point(crBBox.left + fWidth * 0.5f + PWL_BEZIER * fWidth * 0.23f,
2470                      crBBox.bottom + fHeight * 0.87f),
2471           PWLPT_BEZIERTO),
2472       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.27f,
2473                                crBBox.top - fHeight * 0.36f +
2474                                    PWL_BEZIER * fHeight * 0.23f),
2475                     PWLPT_BEZIERTO),
2476       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.27f,
2477                                crBBox.top - fHeight * 0.36f),
2478                     PWLPT_BEZIERTO),
2479       CPWL_PathData(
2480           CPWL_Point(crBBox.right - fWidth * 0.27f - fWidth * 0.08f * 0.2f,
2481                      crBBox.top - fHeight * 0.36f - fHeight * 0.15f * 0.7f),
2482           PWLPT_BEZIERTO),
2483       CPWL_PathData(
2484           CPWL_Point(crBBox.right - fWidth * 0.35f + fWidth * 0.08f * 0.2f,
2485                      crBBox.top - fHeight * 0.51f + fHeight * 0.15f * 0.2f),
2486           PWLPT_BEZIERTO),
2487       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.35f,
2488                                crBBox.top - fHeight * 0.51f),
2489                     PWLPT_BEZIERTO),
2490       CPWL_PathData(
2491           CPWL_Point(crBBox.right - fWidth * 0.35f - fWidth * 0.1f * 0.5f,
2492                      crBBox.top - fHeight * 0.51f - fHeight * 0.15f * 0.3f),
2493           PWLPT_BEZIERTO),
2494       CPWL_PathData(
2495           CPWL_Point(crBBox.right - fWidth * 0.45f - fWidth * 0.1f * 0.5f,
2496                      crBBox.top - fHeight * 0.68f + fHeight * 0.15f * 0.5f),
2497           PWLPT_BEZIERTO),
2498       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.45f,
2499                                crBBox.top - fHeight * 0.68f),
2500                     PWLPT_BEZIERTO),
2501       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.45f,
2502                                crBBox.bottom + fHeight * 0.30f),
2503                     PWLPT_LINETO),
2504       CPWL_PathData(
2505           CPWL_Point(crBBox.right - fWidth * 0.45f,
2506                      crBBox.bottom + fHeight * 0.30f - fWidth * 0.1f * 0.7f),
2507           PWLPT_BEZIERTO),
2508       CPWL_PathData(
2509           CPWL_Point(crBBox.right - fWidth * 0.55f,
2510                      crBBox.bottom + fHeight * 0.30f - fWidth * 0.1f * 0.7f),
2511           PWLPT_BEZIERTO),
2512       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.55f,
2513                                crBBox.bottom + fHeight * 0.30f),
2514                     PWLPT_BEZIERTO),
2515       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.55f,
2516                                crBBox.top - fHeight * 0.66f),
2517                     PWLPT_LINETO),
2518       CPWL_PathData(
2519           CPWL_Point(crBBox.right - fWidth * 0.55f - fWidth * 0.1f * 0.05f,
2520                      crBBox.top - fHeight * 0.66f + fHeight * 0.18f * 0.5f),
2521           PWLPT_BEZIERTO),
2522       CPWL_PathData(
2523           CPWL_Point(crBBox.right - fWidth * 0.45f - fWidth * 0.1f * 0.05f,
2524                      crBBox.top - fHeight * 0.48f - fHeight * 0.18f * 0.3f),
2525           PWLPT_BEZIERTO),
2526       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.45f,
2527                                crBBox.top - fHeight * 0.48f),
2528                     PWLPT_BEZIERTO),
2529       CPWL_PathData(
2530           CPWL_Point(crBBox.right - fWidth * 0.45f + fWidth * 0.08f * 0.2f,
2531                      crBBox.top - fHeight * 0.48f + fHeight * 0.18f * 0.2f),
2532           PWLPT_BEZIERTO),
2533       CPWL_PathData(
2534           CPWL_Point(crBBox.right - fWidth * 0.37f - fWidth * 0.08f * 0.2f,
2535                      crBBox.top - fHeight * 0.36f - fHeight * 0.18f * 0.7f),
2536           PWLPT_BEZIERTO),
2537       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.37f,
2538                                crBBox.top - fHeight * 0.36f),
2539                     PWLPT_BEZIERTO),
2540       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.37f,
2541                                crBBox.top - fHeight * 0.36f +
2542                                    PWL_BEZIER * fHeight * 0.13f),
2543                     PWLPT_BEZIERTO),
2544       CPWL_PathData(
2545           CPWL_Point(crBBox.left + fWidth * 0.5f + PWL_BEZIER * fWidth * 0.13f,
2546                      crBBox.bottom + fHeight * 0.77f),
2547           PWLPT_BEZIERTO),
2548       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.5f,
2549                                crBBox.bottom + fHeight * 0.77f),
2550                     PWLPT_BEZIERTO),
2551       CPWL_PathData(
2552           CPWL_Point(crBBox.left + fWidth * 0.5f - PWL_BEZIER * fWidth * 0.13f,
2553                      crBBox.bottom + fHeight * 0.77f),
2554           PWLPT_BEZIERTO),
2555       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.37f,
2556                                crBBox.top - fHeight * 0.36f +
2557                                    PWL_BEZIER * fHeight * 0.13f),
2558                     PWLPT_BEZIERTO),
2559       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.37f,
2560                                crBBox.top - fHeight * 0.36f),
2561                     PWLPT_BEZIERTO),
2562       CPWL_PathData(
2563           CPWL_Point(crBBox.left + fWidth * 0.37f,
2564                      crBBox.top - fHeight * 0.36f - fWidth * 0.1f * 0.6f),
2565           PWLPT_BEZIERTO),
2566       CPWL_PathData(
2567           CPWL_Point(crBBox.left + fWidth * 0.27f,
2568                      crBBox.top - fHeight * 0.36f - fWidth * 0.1f * 0.6f),
2569           PWLPT_BEZIERTO),
2570       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.27f,
2571                                crBBox.top - fHeight * 0.36f),
2572                     PWLPT_BEZIERTO),
2573       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f,
2574                                crBBox.bottom + fHeight * 0.13f),
2575                     PWLPT_MOVETO),
2576       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f,
2577                                crBBox.bottom + fHeight * 0.13f +
2578                                    PWL_BEZIER * fHeight * 0.055f),
2579                     PWLPT_BEZIERTO),
2580       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f -
2581                                    PWL_BEZIER * fWidth * 0.095f,
2582                                crBBox.bottom + fHeight * 0.185f),
2583                     PWLPT_BEZIERTO),
2584       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f,
2585                                crBBox.bottom + fHeight * 0.185f),
2586                     PWLPT_BEZIERTO),
2587       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f +
2588                                    PWL_BEZIER * fWidth * 0.065f,
2589                                crBBox.bottom + fHeight * 0.185f),
2590                     PWLPT_BEZIERTO),
2591       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f,
2592                                crBBox.bottom + fHeight * 0.13f +
2593                                    PWL_BEZIER * fHeight * 0.055f),
2594                     PWLPT_BEZIERTO),
2595       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f,
2596                                crBBox.bottom + fHeight * 0.13f),
2597                     PWLPT_BEZIERTO),
2598       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f,
2599                                crBBox.bottom + fHeight * 0.13f -
2600                                    PWL_BEZIER * fHeight * 0.055f),
2601                     PWLPT_BEZIERTO),
2602       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f +
2603                                    PWL_BEZIER * fWidth * 0.065f,
2604                                crBBox.bottom + fHeight * 0.075f),
2605                     PWLPT_BEZIERTO),
2606       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f,
2607                                crBBox.bottom + fHeight * 0.075f),
2608                     PWLPT_BEZIERTO),
2609       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f -
2610                                    PWL_BEZIER * fWidth * 0.065f,
2611                                crBBox.bottom + fHeight * 0.075f),
2612                     PWLPT_BEZIERTO),
2613       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f,
2614                                crBBox.bottom + fHeight * 0.13f -
2615                                    PWL_BEZIER * fHeight * 0.055f),
2616                     PWLPT_BEZIERTO),
2617       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f,
2618                                crBBox.bottom + fHeight * 0.13f),
2619                     PWLPT_BEZIERTO)};
2620
2621   if (type == PWLPT_STREAM)
2622     sPathData = GetAppStreamFromArray(PathArray, 59);
2623   else
2624     GetPathDataFromArray(path, PathArray, 59);
2625 }
2626
2627 void CPWL_Utils::GetGraphics_InsertText(CFX_ByteString& sPathData,
2628                                         CFX_PathData& path,
2629                                         const CPDF_Rect& crBBox,
2630                                         const PWL_PATH_TYPE type) {
2631   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2632   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2633
2634   CPWL_PathData PathArray[] = {
2635       CPWL_PathData(
2636           CPWL_Point(crBBox.left + fWidth / 10, crBBox.bottom + fHeight / 10),
2637           PWLPT_MOVETO),
2638       CPWL_PathData(
2639           CPWL_Point(crBBox.left + fWidth / 2, crBBox.top - fHeight * 2 / 15),
2640           PWLPT_LINETO),
2641       CPWL_PathData(
2642           CPWL_Point(crBBox.right - fWidth / 10, crBBox.bottom + fHeight / 10),
2643           PWLPT_LINETO),
2644       CPWL_PathData(
2645           CPWL_Point(crBBox.left + fWidth / 10, crBBox.bottom + fHeight / 10),
2646           PWLPT_LINETO)};
2647
2648   if (type == PWLPT_STREAM)
2649     sPathData = GetAppStreamFromArray(PathArray, 4);
2650   else
2651     GetPathDataFromArray(path, PathArray, 4);
2652 }
2653
2654 void CPWL_Utils::GetGraphics_Key(CFX_ByteString& sPathData,
2655                                  CFX_PathData& path,
2656                                  const CPDF_Rect& crBBox,
2657                                  const PWL_PATH_TYPE type) {
2658   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2659   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2660   FX_FLOAT k = -fHeight / fWidth;
2661   CPWL_Point tail;
2662   CPWL_Point CicleCenter;
2663   tail.x = crBBox.left + fWidth * 0.9f;
2664   tail.y = k * (tail.x - crBBox.right) + crBBox.bottom;
2665   CicleCenter.x = crBBox.left + fWidth * 0.15f;
2666   CicleCenter.y = k * (CicleCenter.x - crBBox.right) + crBBox.bottom;
2667
2668   CPWL_PathData PathArray[] = {
2669       CPWL_PathData(
2670           CPWL_Point(tail.x + fWidth / 30.0f, -fWidth / 30.0f / k + tail.y),
2671           PWLPT_MOVETO),
2672       CPWL_PathData(CPWL_Point(tail.x + fWidth / 30.0f - fWidth * 0.18f,
2673                                -k * fWidth * 0.18f - fWidth / 30 / k + tail.y),
2674                     PWLPT_LINETO),
2675       CPWL_PathData(
2676           CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f + fWidth * 0.07f,
2677                      -fWidth * 0.07f / k - k * fWidth * 0.18f -
2678                          fWidth / 30 / k + tail.y),
2679           PWLPT_LINETO),
2680       CPWL_PathData(
2681           CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 +
2682                          fWidth * 0.07f,
2683                      -fWidth * 0.07f / k - k * fWidth / 20 -
2684                          k * fWidth * 0.18f - fWidth / 30 / k + tail.y),
2685           PWLPT_LINETO),
2686       CPWL_PathData(
2687           CPWL_Point(
2688               tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20,
2689               -k * fWidth / 20 - k * fWidth * 0.18f - fWidth / 30 / k + tail.y),
2690           PWLPT_LINETO),
2691       CPWL_PathData(
2692           CPWL_Point(
2693               tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 - fWidth / 15,
2694               -k * fWidth / 15 - k * fWidth / 20 - k * fWidth * 0.18f -
2695                   fWidth / 30 / k + tail.y),
2696           PWLPT_LINETO),
2697       CPWL_PathData(
2698           CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 -
2699                          fWidth / 15 + fWidth * 0.07f,
2700                      -fWidth * 0.07f / k - k * fWidth / 15 - k * fWidth / 20 -
2701                          k * fWidth * 0.18f - fWidth / 30 / k + tail.y),
2702           PWLPT_LINETO),
2703       CPWL_PathData(
2704           CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 -
2705                          fWidth / 15 - fWidth / 20 + fWidth * 0.07f,
2706                      -fWidth * 0.07f / k + -k * fWidth / 20 + -k * fWidth / 15 -
2707                          k * fWidth / 20 - k * fWidth * 0.18f -
2708                          fWidth / 30 / k + tail.y),
2709           PWLPT_LINETO),
2710       CPWL_PathData(
2711           CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 -
2712                          fWidth / 15 - fWidth / 20,
2713                      -k * fWidth / 20 + -k * fWidth / 15 - k * fWidth / 20 -
2714                          k * fWidth * 0.18f - fWidth / 30 / k + tail.y),
2715           PWLPT_LINETO),
2716       CPWL_PathData(CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.45f,
2717                                -k * fWidth * 0.45f - fWidth / 30 / k + tail.y),
2718                     PWLPT_LINETO),
2719       CPWL_PathData(
2720           CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.45f + fWidth * 0.2f,
2721                      -fWidth * 0.4f / k - k * fWidth * 0.45f - fWidth / 30 / k +
2722                          tail.y),
2723           PWLPT_BEZIERTO),
2724       CPWL_PathData(CPWL_Point(CicleCenter.x + fWidth * 0.2f,
2725                                -fWidth * 0.1f / k + CicleCenter.y),
2726                     PWLPT_BEZIERTO),
2727       CPWL_PathData(CPWL_Point(CicleCenter.x, CicleCenter.y), PWLPT_BEZIERTO),
2728       CPWL_PathData(CPWL_Point(CicleCenter.x - fWidth / 60.0f,
2729                                -k * fWidth / 60 + CicleCenter.y),
2730                     PWLPT_BEZIERTO),
2731       CPWL_PathData(CPWL_Point(CicleCenter.x - fWidth / 60,
2732                                -k * fWidth / 60 + CicleCenter.y),
2733                     PWLPT_BEZIERTO),
2734       CPWL_PathData(CPWL_Point(CicleCenter.x, CicleCenter.y), PWLPT_BEZIERTO),
2735       CPWL_PathData(
2736           CPWL_Point(CicleCenter.x - fWidth * 0.22f,
2737                      fWidth * 0.35f / k + CicleCenter.y - fHeight * 0.05f),
2738           PWLPT_BEZIERTO),
2739       CPWL_PathData(
2740           CPWL_Point(tail.x - fWidth / 30 - fWidth * 0.45f - fWidth * 0.18f,
2741                      fWidth * 0.05f / k - k * fWidth * 0.45f + fWidth / 30 / k +
2742                          tail.y - fHeight * 0.05f),
2743           PWLPT_BEZIERTO),
2744       CPWL_PathData(
2745           CPWL_Point(tail.x - fWidth / 30.0f - fWidth * 0.45f,
2746                      -k * fWidth * 0.45f + fWidth / 30.0f / k + tail.y),
2747           PWLPT_BEZIERTO),
2748       CPWL_PathData(
2749           CPWL_Point(tail.x - fWidth / 30.0f, fWidth / 30.0f / k + tail.y),
2750           PWLPT_LINETO),
2751       CPWL_PathData(CPWL_Point(tail.x + fWidth / 30, -fWidth / 30 / k + tail.y),
2752                     PWLPT_LINETO),
2753       CPWL_PathData(CPWL_Point(CicleCenter.x + fWidth * 0.08f,
2754                                k * fWidth * 0.08f + CicleCenter.y),
2755                     PWLPT_MOVETO),
2756       CPWL_PathData(
2757           CPWL_Point(CicleCenter.x + fWidth * 0.08f + fWidth * 0.1f,
2758                      -fWidth * 0.1f / k + k * fWidth * 0.08f + CicleCenter.y),
2759           PWLPT_BEZIERTO),
2760       CPWL_PathData(
2761           CPWL_Point(CicleCenter.x + fWidth * 0.22f + fWidth * 0.1f,
2762                      k * fWidth * 0.22f + CicleCenter.y - fWidth * 0.1f / k),
2763           PWLPT_BEZIERTO),
2764       CPWL_PathData(CPWL_Point(CicleCenter.x + fWidth * 0.22f,
2765                                k * fWidth * 0.22f + CicleCenter.y),
2766                     PWLPT_BEZIERTO),
2767       CPWL_PathData(
2768           CPWL_Point(CicleCenter.x + fWidth * 0.22f - fWidth * 0.1f,
2769                      fWidth * 0.1f / k + k * fWidth * 0.22f + CicleCenter.y),
2770           PWLPT_BEZIERTO),
2771       CPWL_PathData(
2772           CPWL_Point(CicleCenter.x + fWidth * 0.08f - fWidth * 0.1f,
2773                      fWidth * 0.1f / k + k * fWidth * 0.08f + CicleCenter.y),
2774           PWLPT_BEZIERTO),
2775       CPWL_PathData(CPWL_Point(CicleCenter.x + fWidth * 0.08f,
2776                                k * fWidth * 0.08f + CicleCenter.y),
2777                     PWLPT_BEZIERTO)};
2778
2779   if (type == PWLPT_STREAM)
2780     sPathData = GetAppStreamFromArray(PathArray, 28);
2781   else
2782     GetPathDataFromArray(path, PathArray, 28);
2783 }
2784
2785 void CPWL_Utils::GetGraphics_NewParagraph(CFX_ByteString& sPathData,
2786                                           CFX_PathData& path,
2787                                           const CPDF_Rect& crBBox,
2788                                           const PWL_PATH_TYPE type) {
2789   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2790   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2791
2792   CPWL_PathData PathArray[] = {
2793       CPWL_PathData(
2794           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 20.0f),
2795           PWLPT_MOVETO),
2796       CPWL_PathData(
2797           CPWL_Point(crBBox.left + fWidth / 10.0f, crBBox.top - fHeight / 2.0f),
2798           PWLPT_LINETO),
2799       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f,
2800                                crBBox.top - fHeight / 2.0f),
2801                     PWLPT_LINETO),
2802       CPWL_PathData(
2803           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 20.0f),
2804           PWLPT_LINETO),
2805       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.12f,
2806                                crBBox.top - fHeight * 17 / 30.0f),
2807                     PWLPT_MOVETO),
2808       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.12f,
2809                                crBBox.bottom + fHeight / 10.0f),
2810                     PWLPT_LINETO),
2811       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.22f,
2812                                crBBox.bottom + fHeight / 10.0f),
2813                     PWLPT_LINETO),
2814       CPWL_PathData(
2815           CPWL_Point(crBBox.left + fWidth * 0.22f,
2816                      crBBox.top - fHeight * 17 / 30.0f - fWidth * 0.14f),
2817           PWLPT_LINETO),
2818       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.38f,
2819                                crBBox.bottom + fHeight / 10.0f),
2820                     PWLPT_LINETO),
2821       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.48f,
2822                                crBBox.bottom + fHeight / 10.0f),
2823                     PWLPT_LINETO),
2824       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.48f,
2825                                crBBox.top - fHeight * 17 / 30.0f),
2826                     PWLPT_LINETO),
2827       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.38f,
2828                                crBBox.top - fHeight * 17 / 30.0f),
2829                     PWLPT_LINETO),
2830       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.38f,
2831                                crBBox.bottom + fWidth * 0.24f),
2832                     PWLPT_LINETO),
2833       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.22f,
2834                                crBBox.top - fHeight * 17 / 30.0f),
2835                     PWLPT_LINETO),
2836       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.12f,
2837                                crBBox.top - fHeight * 17 / 30.0f),
2838                     PWLPT_LINETO),
2839       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f,
2840                                crBBox.bottom + fHeight / 10.0f),
2841                     PWLPT_MOVETO),
2842       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f,
2843                                crBBox.bottom + fHeight / 10.0f),
2844                     PWLPT_LINETO),
2845       CPWL_PathData(
2846           CPWL_Point(crBBox.left + fWidth * 0.7f,
2847                      crBBox.bottom + fHeight / 10.0f + fHeight / 7.0f),
2848           PWLPT_LINETO),
2849       CPWL_PathData(
2850           CPWL_Point(crBBox.left + fWidth * 0.97f,
2851                      crBBox.bottom + fHeight / 10.0f + fHeight / 7.0f),
2852           PWLPT_BEZIERTO),
2853       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.97f,
2854                                crBBox.top - fHeight * 17 / 30.0f),
2855                     PWLPT_BEZIERTO),
2856       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f,
2857                                crBBox.top - fHeight * 17 / 30.0f),
2858                     PWLPT_BEZIERTO),
2859       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f,
2860                                crBBox.top - fHeight * 17 / 30.0f),
2861                     PWLPT_LINETO),
2862       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f,
2863                                crBBox.bottom + fHeight / 10.0f),
2864                     PWLPT_LINETO),
2865       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f,
2866                                crBBox.bottom + fHeight / 7 + fHeight * 0.18f),
2867                     PWLPT_MOVETO),
2868       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.85f,
2869                                crBBox.bottom + fHeight / 7 + fHeight * 0.18f),
2870                     PWLPT_BEZIERTO),
2871       CPWL_PathData(
2872           CPWL_Point(crBBox.left + fWidth * 0.85f,
2873                      crBBox.top - fHeight * 17 / 30.0f - fHeight * 0.08f),
2874           PWLPT_BEZIERTO),
2875       CPWL_PathData(
2876           CPWL_Point(crBBox.left + fWidth * 0.7f,
2877                      crBBox.top - fHeight * 17 / 30.0f - fHeight * 0.08f),
2878           PWLPT_BEZIERTO),
2879       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f,
2880                                crBBox.bottom + fHeight / 7 + fHeight * 0.18f),
2881                     PWLPT_LINETO)};
2882
2883   if (type == PWLPT_STREAM)
2884     sPathData = GetAppStreamFromArray(PathArray, 28);
2885   else
2886     GetPathDataFromArray(path, PathArray, 28);
2887 }
2888
2889 void CPWL_Utils::GetGraphics_TextNote(CFX_ByteString& sPathData,
2890                                       CFX_PathData& path,
2891                                       const CPDF_Rect& crBBox,
2892                                       const PWL_PATH_TYPE type) {
2893   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2894   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2895
2896   CPWL_PathData PathArray[] = {
2897       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f,
2898                                crBBox.bottom + fHeight / 15.0f),
2899                     PWLPT_MOVETO),
2900       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 10.0f,
2901                                crBBox.bottom + fHeight * 4 / 15.0f),
2902                     PWLPT_LINETO),
2903       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f,
2904                                crBBox.bottom + fHeight * 4 / 15.0f),
2905                     PWLPT_LINETO),
2906       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f,
2907                                crBBox.top - fHeight / 15.0f),
2908                     PWLPT_LINETO),
2909       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 10.0f,
2910                                crBBox.top - fHeight / 15.0f),
2911                     PWLPT_LINETO),
2912       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 10.0f,
2913                                crBBox.bottom + fHeight / 15.0f),
2914                     PWLPT_LINETO),
2915       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f,
2916                                crBBox.bottom + fHeight / 15.0f),
2917                     PWLPT_LINETO),
2918       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f,
2919                                crBBox.bottom + fHeight * 4 / 15.0f),
2920                     PWLPT_LINETO),
2921       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f,
2922                                crBBox.bottom + fHeight / 15.0f),
2923                     PWLPT_LINETO),
2924       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f,
2925                                crBBox.bottom + fHeight * 4 / 15.0f),
2926                     PWLPT_LINETO),
2927       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f,
2928                                crBBox.bottom + fHeight * 4 / 15.0f),
2929                     PWLPT_LINETO),
2930       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 5.0f,
2931                                crBBox.top - fHeight * 4 / 15.0f),
2932                     PWLPT_MOVETO),
2933       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 5.0f,
2934                                crBBox.top - fHeight * 4 / 15.0f),
2935                     PWLPT_LINETO),
2936       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 5.0f,
2937                                crBBox.top - fHeight * 7 / 15.0f),
2938                     PWLPT_MOVETO),
2939       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 5.0f,
2940                                crBBox.top - fHeight * 7 / 15.0f),
2941                     PWLPT_LINETO),
2942       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 5.0f,
2943                                crBBox.top - fHeight * 10 / 15.0f),
2944                     PWLPT_MOVETO),
2945       CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f,
2946                                crBBox.top - fHeight * 10 / 15.0f),
2947                     PWLPT_LINETO)};
2948
2949   if (type == PWLPT_STREAM)
2950     sPathData = GetAppStreamFromArray(PathArray, 17);
2951   else
2952     GetPathDataFromArray(path, PathArray, 17);
2953 }
2954
2955 void CPWL_Utils::GetGraphics_Paragraph(CFX_ByteString& sPathData,
2956                                        CFX_PathData& path,
2957                                        const CPDF_Rect& crBBox,
2958                                        const PWL_PATH_TYPE type) {
2959   FX_FLOAT fWidth = crBBox.right - crBBox.left;
2960   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
2961
2962   CPWL_PathData PathArray[] = {
2963       CPWL_PathData(
2964           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f),
2965           PWLPT_MOVETO),
2966       CPWL_PathData(
2967           CPWL_Point(crBBox.left + fWidth * 0.7f, crBBox.top - fHeight / 15.0f),
2968           PWLPT_LINETO),
2969       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f,
2970                                crBBox.bottom + fHeight / 15.0f),
2971                     PWLPT_LINETO),
2972       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.634f,
2973                                crBBox.bottom + fHeight / 15.0f),
2974                     PWLPT_LINETO),
2975       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.634f,
2976                                crBBox.top - fHeight * 2 / 15.0f),
2977                     PWLPT_LINETO),
2978       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.566f,
2979                                crBBox.top - fHeight * 2 / 15.0f),
2980                     PWLPT_LINETO),
2981       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.566f,
2982                                crBBox.bottom + fHeight / 15.0f),
2983                     PWLPT_LINETO),
2984       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
2985                                crBBox.bottom + fHeight / 15.0f),
2986                     PWLPT_LINETO),
2987       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
2988                                crBBox.top - fHeight / 15.0f - fHeight * 0.4f),
2989                     PWLPT_LINETO),
2990       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.2f,
2991                                crBBox.top - fHeight / 15.0f - fHeight * 0.4f),
2992                     PWLPT_BEZIERTO),
2993       CPWL_PathData(
2994           CPWL_Point(crBBox.left + fWidth * 0.2f, crBBox.top - fHeight / 15.0f),
2995           PWLPT_BEZIERTO),
2996       CPWL_PathData(
2997           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f),
2998           PWLPT_BEZIERTO)};
2999
3000   if (type == PWLPT_STREAM)
3001     sPathData = GetAppStreamFromArray(PathArray, 12);
3002   else
3003     GetPathDataFromArray(path, PathArray, 12);
3004 }
3005
3006 void CPWL_Utils::GetGraphics_RightArrow(CFX_ByteString& sPathData,
3007                                         CFX_PathData& path,
3008                                         const CPDF_Rect& crBBox,
3009                                         const PWL_PATH_TYPE type) {
3010   FX_FLOAT fWidth = crBBox.right - crBBox.left;
3011   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
3012
3013   CPWL_PathData PathArray[] = {
3014       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
3015                                crBBox.top - fHeight / 2.0f),
3016                     PWLPT_MOVETO),
3017       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f + fWidth / 8.0f,
3018                                crBBox.bottom + fHeight / 5.0f),
3019                     PWLPT_LINETO),
3020       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f,
3021                                crBBox.bottom + fHeight / 5.0f),
3022                     PWLPT_LINETO),
3023       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f - fWidth * 0.15f,
3024                                crBBox.top - fHeight / 2.0f - fWidth / 25.0f),
3025                     PWLPT_LINETO),
3026       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.1f,
3027                                crBBox.top - fHeight / 2.0f - fWidth / 25.0f),
3028                     PWLPT_LINETO),
3029       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.1f,
3030                                crBBox.top - fHeight / 2.0f + fWidth / 25.0f),
3031                     PWLPT_LINETO),
3032       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f - fWidth * 0.15f,
3033                                crBBox.top - fHeight / 2.0f + fWidth / 25.0f),
3034                     PWLPT_LINETO),
3035       CPWL_PathData(
3036           CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 5.0f),
3037           PWLPT_LINETO),
3038       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f + fWidth / 8.0f,
3039                                crBBox.top - fHeight / 5.0f),
3040                     PWLPT_LINETO),
3041       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f,
3042                                crBBox.top - fHeight / 2.0f),
3043                     PWLPT_LINETO)};
3044
3045   if (type == PWLPT_STREAM)
3046     sPathData = GetAppStreamFromArray(PathArray, 10);
3047   else
3048     GetPathDataFromArray(path, PathArray, 10);
3049 }
3050
3051 void CPWL_Utils::GetGraphics_RightPointer(CFX_ByteString& sPathData,
3052                                           CFX_PathData& path,
3053                                           const CPDF_Rect& crBBox,
3054                                           const PWL_PATH_TYPE type) {
3055   FX_FLOAT fWidth = crBBox.right - crBBox.left;
3056   FX_FLOAT fHeight = crBBox.top - crBBox.bottom;
3057
3058   CPWL_PathData PathArray[] = {
3059       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 30.0f,
3060                                crBBox.top - fHeight / 2.0f),
3061                     PWLPT_MOVETO),
3062       CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 30.0f,
3063                                crBBox.bottom + fHeight / 6.0f),
3064                     PWLPT_LINETO),
3065       CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 4 / 15.0f,
3066                                crBBox.top - fHeight / 2.0f),
3067                     PWLPT_LINETO),
3068       CPWL_PathData(
3069           CPWL_Point(crBBox.left + fWidth / 30.0f, crBBox.top - fHeight / 6.0f),
3070           PWLPT_LINETO),
3071       CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 30.0f,
3072                                crBBox.top - fHeight / 2.0f),
3073                     PWLPT_LINETO)};
3074
3075   if (type == PWLPT_STREAM)
3076     sPathData = GetAppStreamFromArray(PathArray, 5);
3077   else
3078     GetPathDataFromArray(path, PathArray, 5);
3079 }
3080
3081 void CPWL_Utils::GetGraphics_Star(CFX_ByteString& sPathData,
3082                                   CFX_PathData& path,
3083                                   const CPDF_Rect& crBBox,
3084                                   const PWL_PATH_TYPE type) {
3085   FX_FLOAT fLongRadius =
3086       (crBBox.top - crBBox.bottom) / (1 + (FX_FLOAT)cos(PWL_PI / 5.0f));
3087   fLongRadius = fLongRadius * 0.7f;
3088   FX_FLOAT fShortRadius = fLongRadius * 0.55f;
3089   CPDF_Point ptCenter = CPDF_Point((crBBox.left + crBBox.right) / 2.0f,
3090                                    (crBBox.top + crBBox.bottom) / 2.0f);
3091
3092   FX_FLOAT px1[5], py1[5];
3093   FX_FLOAT px2[5], py2[5];
3094
3095   FX_FLOAT fAngel = PWL_PI / 10.0f;
3096
3097   for (int32_t i = 0; i < 5; i++) {
3098     px1[i] = ptCenter.x + fLongRadius * (FX_FLOAT)cos(fAngel);
3099     py1[i] = ptCenter.y + fLongRadius * (FX_FLOAT)sin(fAngel);
3100
3101     fAngel += PWL_PI * 2 / 5.0f;
3102   }
3103
3104   fAngel = PWL_PI / 5.0f + PWL_PI / 10.0f;
3105
3106   for (int32_t j = 0; j < 5; j++) {
3107     px2[j] = ptCenter.x + fShortRadius * (FX_FLOAT)cos(fAngel);
3108     py2[j] = ptCenter.y + fShortRadius * (FX_FLOAT)sin(fAngel);
3109
3110     fAngel += PWL_PI * 2 / 5.0f;
3111   }
3112
3113   CPWL_PathData PathArray[11];
3114   PathArray[0] = CPWL_PathData(CPWL_Point(px1[0], py1[0]), PWLPT_MOVETO);
3115   PathArray[1] = CPWL_PathData(CPWL_Point(px2[0], py2[0]), PWLPT_LINETO);
3116
3117   for (int32_t k = 0; k < 4; k++) {
3118     PathArray[(k + 1) * 2] =
3119         CPWL_PathData(CPWL_Point(px1[k + 1], py1[k + 1]), PWLPT_LINETO);
3120     PathArray[(k + 1) * 2 + 1] =
3121         CPWL_PathData(CPWL_Point(px2[k + 1], py2[k + 1]), PWLPT_LINETO);
3122   }
3123
3124   PathArray[10] = CPWL_PathData(CPWL_Point(px1[0], py1[0]), PWLPT_LINETO);
3125
3126   if (type == PWLPT_STREAM)
3127     sPathData = GetAppStreamFromArray(PathArray, 11);
3128   else
3129     GetPathDataFromArray(path, PathArray, 11);
3130 }
3131
3132 void CPWL_Utils::GetGraphics_UpArrow(CFX_ByteString& sPathData,
3133                &