1// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "xfa/src/foxitlib.h"
8#define CHECKBOX_SIZE_SIGNMARGIN 3
9#define CHECKBOX_SIZE_SIGNBORDER 2
10#define CHECKBOX_SIZE_SIGNPATH 100
11#define CHECKBOX_COLOR_BOXLT1 (ArgbEncode(255, 172, 168, 153))
12#define CHECKBOX_COLOR_BOXLT2 (ArgbEncode(255, 113, 111, 100))
13#define CHECKBOX_COLOR_BOXRB1 (ArgbEncode(255, 241, 239, 226))
14#define CHECKBOX_COLOR_BOXRB2 (ArgbEncode(255, 255, 255, 255))
15#define CHECKBOX_FXGE_CoordinatesAdjust
16CFWL_CheckBoxTP::CFWL_CheckBoxTP() : m_pCheckPath(NULL) {
17  m_pThemeData = new CKBThemeData;
18  SetThemeData(0);
19}
20CFWL_CheckBoxTP::~CFWL_CheckBoxTP() {
21  if (m_pThemeData) {
22    delete m_pThemeData;
23    m_pThemeData = NULL;
24  }
25  if (m_pCheckPath) {
26    m_pCheckPath->Clear();
27    delete m_pCheckPath;
28    m_pCheckPath = NULL;
29  }
30}
31FX_BOOL CFWL_CheckBoxTP::IsValidWidget(IFWL_Widget* pWidget) {
32  return pWidget && pWidget->GetClassID() == FWL_CLASSHASH_CheckBox;
33}
34FX_DWORD CFWL_CheckBoxTP::SetThemeID(IFWL_Widget* pWidget,
35                                     FX_DWORD dwThemeID,
36                                     FX_BOOL bChildren) {
37  if (m_pThemeData) {
38    SetThemeData(FWL_GetThemeColor(dwThemeID));
39  }
40  return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
41}
42FX_BOOL CFWL_CheckBoxTP::DrawText(CFWL_ThemeText* pParams) {
43  if (!m_pTextOut)
44    return FALSE;
45  FX_BOOL bDisable = (pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask1) ==
46                     FWL_PARTSTATE_CKB_Disabled;
47  FX_ARGB argText =
48      bDisable ? FWLTHEME_CAPACITY_TextDisColor : FWLTHEME_CAPACITY_TextColor;
49  m_pTextOut->SetTextColor(argText);
50  return CFWL_WidgetTP::DrawText(pParams);
51}
52FX_BOOL CFWL_CheckBoxTP::DrawBackground(CFWL_ThemeBackground* pParams) {
53  if (!pParams)
54    return FALSE;
55  switch (pParams->m_iPart) {
56    case FWL_PART_CKB_Border: {
57      DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
58      break;
59    }
60    case FWL_PART_CKB_Edge: {
61      DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(),
62               &pParams->m_rtPart, &pParams->m_matrix);
63      break;
64    }
65    case FWL_PART_CKB_Background: {
66      FillBackground(pParams->m_pGraphics, &pParams->m_rtPart,
67                     &pParams->m_matrix);
68      if (pParams->m_dwStates & FWL_PARTSTATE_CKB_Focused) {
69        pParams->m_rtPart = *(CFX_RectF*)pParams->m_pData;
70        DrawFocus(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
71      }
72      break;
73    }
74    case FWL_PART_CKB_CheckBox: {
75      DrawBoxBk(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart,
76                pParams->m_dwStates, &pParams->m_matrix);
77      if (((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) ==
78           FWL_PARTSTATE_CKB_Checked) |
79          ((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) ==
80           FWL_PARTSTATE_CKB_Neutral)) {
81        DrawSign(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart,
82                 pParams->m_dwStates, &pParams->m_matrix);
83      }
84      FX_BOOL bDisable = (pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask1) ==
85                         FWL_PARTSTATE_CKB_Disabled;
86      DrawSignBorder(pParams->m_pWidget, pParams->m_pGraphics,
87                     &pParams->m_rtPart, bDisable, &pParams->m_matrix);
88      break;
89    }
90    default: { return FALSE; }
91  }
92  return TRUE;
93}
94FWL_ERR CFWL_CheckBoxTP::Initialize() {
95  InitTTO();
96  return CFWL_WidgetTP::Initialize();
97}
98FWL_ERR CFWL_CheckBoxTP::Finalize() {
99  FinalizeTTO();
100  return CFWL_WidgetTP::Finalize();
101}
102void CFWL_CheckBoxTP::DrawBoxBk(IFWL_Widget* pWidget,
103                                CFX_Graphics* pGraphics,
104                                const CFX_RectF* pRect,
105                                FX_DWORD dwStates,
106                                CFX_Matrix* pMatrix) {
107  dwStates &= 0x03;
108  int32_t fillMode = FXFILL_WINDING;
109  FX_DWORD dwStyleEx = pWidget->GetStylesEx();
110  dwStyleEx &= FWL_STYLEEXT_CKB_ShapeMask;
111  CFX_Path path;
112  path.Create();
113  FX_FLOAT fRight = pRect->right();
114  FX_FLOAT fBottom = pRect->bottom();
115  FX_BOOL bClipSign =
116      (dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Hovered;
117  if ((dwStyleEx == FWL_STYLEEXT_CKB_ShapeSolidSquare) ||
118      (dwStyleEx == FWL_STYLEEXT_CKB_ShapeSunkenSquare)) {
119    path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
120    if (bClipSign) {
121      fillMode = FXFILL_ALTERNATE;
122      path.AddRectangle(pRect->left + CHECKBOX_SIZE_SIGNMARGIN,
123                        pRect->top + CHECKBOX_SIZE_SIGNMARGIN,
124                        pRect->width - CHECKBOX_SIZE_SIGNMARGIN * 2,
125                        pRect->height - CHECKBOX_SIZE_SIGNMARGIN * 2);
126    }
127  } else {
128#ifdef CHECKBOX_FXGE_CoordinatesAdjust
129    CFX_RectF rect(*pRect);
130    rect.Deflate(0, 0, 1, 1);
131    path.AddEllipse(rect);
132#else
133    path.AddEllipse(*pRect);
134#endif
135    if (bClipSign) {
136      fillMode = FXFILL_ALTERNATE;
137#ifdef CHECKBOX_FXGE_CoordinatesAdjust
138      CFX_RectF rtClip(rect);
139#else
140      CFX_RectF rtClip(*pRect);
141#endif
142      rtClip.Deflate(CHECKBOX_SIZE_SIGNMARGIN - 1,
143                     CHECKBOX_SIZE_SIGNMARGIN - 1);
144      path.AddEllipse(rtClip);
145    }
146  }
147  int32_t iTheme = 1;
148  if ((dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Hovered) {
149    iTheme = 2;
150  } else if ((dwStates & FWL_PARTSTATE_CKB_Mask1) ==
151             FWL_PARTSTATE_CKB_Pressed) {
152    iTheme = 3;
153  } else if ((dwStates & FWL_PARTSTATE_CKB_Mask1) ==
154             FWL_PARTSTATE_CKB_Disabled) {
155    iTheme = 4;
156  }
157  if ((dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Checked) {
158    iTheme += 4;
159  } else if ((dwStates & FWL_PARTSTATE_CKB_Mask2) ==
160             FWL_PARTSTATE_CKB_Neutral) {
161    iTheme += 8;
162  }
163  DrawAxialShading(pGraphics, pRect->left - 1, pRect->top - 1, fRight, fBottom,
164                   m_pThemeData->clrBoxBk[iTheme][0],
165                   m_pThemeData->clrBoxBk[iTheme][1], &path, fillMode, pMatrix);
166}
167void CFWL_CheckBoxTP::DrawSign(IFWL_Widget* pWidget,
168                               CFX_Graphics* pGraphics,
169                               const CFX_RectF* pRtBox,
170                               FX_DWORD dwStates,
171                               CFX_Matrix* pMatrix) {
172  CFX_RectF rtSign(*pRtBox);
173  rtSign.Deflate(CHECKBOX_SIZE_SIGNMARGIN, CHECKBOX_SIZE_SIGNMARGIN);
174  FX_DWORD dwColor = m_pThemeData->clrSignCheck;
175  FX_BOOL bCheck = TRUE;
176  if (((dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Disabled) &&
177      ((dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Checked)) {
178    dwColor = m_pThemeData->clrSignBorderDisable;
179  } else if ((dwStates & FWL_PARTSTATE_CKB_Mask2) ==
180             FWL_PARTSTATE_CKB_Neutral) {
181    switch (dwStates & FWL_PARTSTATE_CKB_Mask1) {
182      case FWL_PARTSTATE_CKB_Normal: {
183        bCheck = FALSE;
184        dwColor = m_pThemeData->clrSignNeutralNormal;
185        break;
186      }
187      case FWL_PARTSTATE_CKB_Hovered: {
188        bCheck = FALSE;
189        dwColor = m_pThemeData->clrSignNeutralHover;
190        break;
191      }
192      case FWL_PARTSTATE_CKB_Pressed: {
193        bCheck = FALSE, dwColor = m_pThemeData->clrSignNeutralPressed;
194        break;
195      }
196      case FWL_PARTSTATE_CKB_Disabled: {
197        bCheck = FALSE, dwColor = m_pThemeData->clrSignBorderDisable;
198        break;
199      }
200    }
201  }
202  if (bCheck) {
203    FX_DWORD dwStyle = pWidget->GetStylesEx();
204    switch (dwStyle & FWL_STYLEEXT_CKB_SignShapeMask) {
205      case FWL_STYLEEXT_CKB_SignShapeCheck: {
206        DrawSignCheck(pGraphics, &rtSign, dwColor, pMatrix);
207        break;
208      }
209      case FWL_STYLEEXT_CKB_SignShapeCircle: {
210        rtSign.Deflate(1, 1);
211        DrawSignCircle(pGraphics, &rtSign, dwColor, pMatrix);
212        break;
213      }
214      case FWL_STYLEEXT_CKB_SignShapeCross: {
215        DrawSignCross(pGraphics, &rtSign, dwColor, pMatrix);
216        break;
217      }
218      case FWL_STYLEEXT_CKB_SignShapeDiamond: {
219        DrawSignDiamond(pGraphics, &rtSign, dwColor, pMatrix);
220        break;
221      }
222      case FWL_STYLEEXT_CKB_SignShapeSquare: {
223        DrawSignSquare(pGraphics, &rtSign, dwColor, pMatrix);
224        break;
225      }
226      case FWL_STYLEEXT_CKB_SignShapeStar: {
227        DrawSignStar(pGraphics, &rtSign, dwColor, pMatrix);
228        break;
229      }
230    }
231  } else {
232    FillSoildRect(pGraphics, ArgbEncode(255, 33, 161, 33), &rtSign, pMatrix);
233  }
234}
235void CFWL_CheckBoxTP::DrawSignNeutral(CFX_Graphics* pGraphics,
236                                      const CFX_RectF* pRtSign,
237                                      CFX_Matrix* pMatrix) {
238  ((CFX_RectF*)pRtSign)->Inflate(-3, -3);
239  FillSoildRect(pGraphics, m_pThemeData->clrSignNeutral, pRtSign, pMatrix);
240}
241void CFWL_CheckBoxTP::DrawSignCheck(CFX_Graphics* pGraphics,
242                                    const CFX_RectF* pRtSign,
243                                    FX_ARGB argbFill,
244                                    CFX_Matrix* pMatrix) {
245  if (!m_pCheckPath) {
246    initCheckPath(pRtSign->width);
247  }
248  CFX_Matrix mt;
249  mt.SetIdentity();
250  mt.Translate(pRtSign->left, pRtSign->top);
251  mt.Concat(*pMatrix);
252  CFX_Color crFill(argbFill);
253  pGraphics->SaveGraphState();
254  pGraphics->SetFillColor(&crFill);
255  pGraphics->FillPath(m_pCheckPath, FXFILL_WINDING, &mt);
256  pGraphics->RestoreGraphState();
257}
258void CFWL_CheckBoxTP::DrawSignCircle(CFX_Graphics* pGraphics,
259                                     const CFX_RectF* pRtSign,
260                                     FX_ARGB argbFill,
261                                     CFX_Matrix* pMatrix) {
262  CFX_Path path;
263  path.Create();
264  path.AddEllipse(*pRtSign);
265  CFX_Color crFill(argbFill);
266  pGraphics->SaveGraphState();
267  pGraphics->SetFillColor(&crFill);
268  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
269  pGraphics->RestoreGraphState();
270}
271void CFWL_CheckBoxTP::DrawSignCross(CFX_Graphics* pGraphics,
272                                    const CFX_RectF* pRtSign,
273                                    FX_ARGB argbFill,
274                                    CFX_Matrix* pMatrix) {
275  CFX_Path path;
276  path.Create();
277  FX_FLOAT fRight = pRtSign->right();
278  FX_FLOAT fBottom = pRtSign->bottom();
279  path.AddLine(pRtSign->left, pRtSign->top, fRight, fBottom);
280  path.AddLine(pRtSign->left, fBottom, fRight, pRtSign->top);
281  CFX_Color crFill(argbFill);
282  pGraphics->SaveGraphState();
283  pGraphics->SetStrokeColor(&crFill);
284  pGraphics->SetLineWidth(1.0f);
285  pGraphics->StrokePath(&path, pMatrix);
286  pGraphics->RestoreGraphState();
287}
288void CFWL_CheckBoxTP::DrawSignDiamond(CFX_Graphics* pGraphics,
289                                      const CFX_RectF* pRtSign,
290                                      FX_ARGB argbFill,
291                                      CFX_Matrix* pMatrix) {
292  CFX_Path path;
293  path.Create();
294  FX_FLOAT fWidth = pRtSign->width;
295  FX_FLOAT fHeight = pRtSign->height;
296  FX_FLOAT fBottom = pRtSign->bottom();
297  path.MoveTo(pRtSign->left + fWidth / 2, pRtSign->top);
298  path.LineTo(pRtSign->left, pRtSign->top + fHeight / 2);
299  path.LineTo(pRtSign->left + fWidth / 2, fBottom);
300  path.LineTo(pRtSign->right(), pRtSign->top + fHeight / 2);
301  path.LineTo(pRtSign->left + fWidth / 2, pRtSign->top);
302  CFX_Color crFill(argbFill);
303  pGraphics->SaveGraphState();
304  pGraphics->SetFillColor(&crFill);
305  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
306  pGraphics->RestoreGraphState();
307}
308void CFWL_CheckBoxTP::DrawSignSquare(CFX_Graphics* pGraphics,
309                                     const CFX_RectF* pRtSign,
310                                     FX_ARGB argbFill,
311                                     CFX_Matrix* pMatrix) {
312  CFX_Path path;
313  path.Create();
314  path.AddRectangle(pRtSign->left, pRtSign->top, pRtSign->width,
315                    pRtSign->height);
316  CFX_Color crFill(argbFill);
317  pGraphics->SaveGraphState();
318  pGraphics->SetFillColor(&crFill);
319  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
320  pGraphics->RestoreGraphState();
321}
322void CFWL_CheckBoxTP::DrawSignStar(CFX_Graphics* pGraphics,
323                                   const CFX_RectF* pRtSign,
324                                   FX_ARGB argbFill,
325                                   CFX_Matrix* pMatrix) {
326  CFX_Path path;
327  path.Create();
328  FX_FLOAT fBottom = pRtSign->bottom();
329  FX_FLOAT fRadius =
330      (pRtSign->top - fBottom) / (1 + (FX_FLOAT)cos(FX_PI / 5.0f));
331  CFX_PointF ptCenter;
332  ptCenter.Set((pRtSign->left + pRtSign->right()) / 2.0f,
333               (pRtSign->top + fBottom) / 2.0f);
334  FX_FLOAT px[5], py[5];
335  FX_FLOAT fAngel = FX_PI / 10.0f;
336  for (int32_t i = 0; i < 5; i++) {
337    px[i] = ptCenter.x + fRadius * (FX_FLOAT)cos(fAngel);
338    py[i] = ptCenter.y + fRadius * (FX_FLOAT)sin(fAngel);
339    fAngel += FX_PI * 2 / 5.0f;
340  }
341  path.MoveTo(px[0], py[0]);
342  int32_t nNext = 0;
343  for (int32_t j = 0; j < 5; j++) {
344    nNext += 2;
345    if (nNext >= 5) {
346      nNext -= 5;
347    }
348    path.LineTo(px[nNext], py[nNext]);
349  }
350  CFX_Color crFill(argbFill);
351  pGraphics->SaveGraphState();
352  pGraphics->SetFillColor(&crFill);
353  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
354  pGraphics->RestoreGraphState();
355}
356void CFWL_CheckBoxTP::DrawSignBorder(IFWL_Widget* pWidget,
357                                     CFX_Graphics* pGraphics,
358                                     const CFX_RectF* pRtBox,
359                                     FX_BOOL bDisable,
360                                     CFX_Matrix* pMatrix) {
361  switch (pWidget->GetStylesEx() & FWL_STYLEEXT_CKB_ShapeMask) {
362    case FWL_STYLEEXT_CKB_ShapeSolidSquare: {
363      DrawAnnulusRect(pGraphics, bDisable ? m_pThemeData->clrSignBorderDisable
364                                          : m_pThemeData->clrSignBorderNormal,
365                      pRtBox, 1, pMatrix);
366      break;
367    }
368    case FWL_STYLEEXT_CKB_ShapeSunkenSquare: {
369      Draw3DRect(pGraphics, FWLTHEME_EDGE_Sunken, CHECKBOX_SIZE_SIGNBORDER,
370                 pRtBox, CHECKBOX_COLOR_BOXLT1, CHECKBOX_COLOR_BOXLT2,
371                 CHECKBOX_COLOR_BOXRB1, CHECKBOX_COLOR_BOXRB2, pMatrix);
372      break;
373    }
374    case FWL_STYLEEXT_CKB_ShapeSolidCircle: {
375      DrawAnnulusCircle(pGraphics, bDisable ? m_pThemeData->clrSignBorderDisable
376                                            : m_pThemeData->clrSignBorderNormal,
377                        pRtBox, 1, pMatrix);
378      break;
379    }
380    case FWL_STYLEEXT_CKB_ShapeSunkenCircle: {
381      Draw3DCircle(pGraphics, FWLTHEME_EDGE_Sunken, CHECKBOX_SIZE_SIGNBORDER,
382                   pRtBox, CHECKBOX_COLOR_BOXLT1, CHECKBOX_COLOR_BOXLT2,
383                   CHECKBOX_COLOR_BOXRB1, CHECKBOX_COLOR_BOXRB2, pMatrix);
384      break;
385    }
386  }
387}
388void CFWL_CheckBoxTP::SetThemeData(FX_DWORD dwID) {
389  FX_DWORD* pData = (FX_DWORD*)&m_pThemeData->clrBoxBk;
390  if (dwID) {
391    *pData++ = 0, *pData++ = 0, *pData++ = ArgbEncode(255, 220, 220, 215),
392    *pData++ = ArgbEncode(255, 255, 255, 255),
393    *pData++ = ArgbEncode(255, 255, 240, 207),
394    *pData++ = ArgbEncode(255, 248, 179, 48),
395    *pData++ = ArgbEncode(255, 176, 176, 167),
396    *pData++ = ArgbEncode(255, 241, 239, 239),
397    *pData++ = ArgbEncode(255, 255, 255, 255),
398    *pData++ = ArgbEncode(255, 255, 255, 255),
399    *pData++ = ArgbEncode(255, 220, 220, 215),
400    *pData++ = ArgbEncode(255, 255, 255, 255),
401    *pData++ = ArgbEncode(255, 255, 240, 207),
402    *pData++ = ArgbEncode(255, 248, 179, 48),
403    *pData++ = ArgbEncode(255, 176, 176, 167),
404    *pData++ = ArgbEncode(255, 241, 239, 239),
405    *pData++ = ArgbEncode(255, 255, 255, 255),
406    *pData++ = ArgbEncode(255, 255, 255, 255),
407    *pData++ = ArgbEncode(255, 220, 220, 215),
408    *pData++ = ArgbEncode(255, 255, 255, 255),
409    *pData++ = ArgbEncode(255, 255, 240, 207),
410    *pData++ = ArgbEncode(255, 248, 179, 48),
411    *pData++ = ArgbEncode(255, 176, 176, 167),
412    *pData++ = ArgbEncode(255, 241, 239, 239),
413    *pData++ = ArgbEncode(255, 255, 255, 255),
414    *pData++ = ArgbEncode(255, 255, 255, 255);
415    m_pThemeData->clrSignBorderNormal = ArgbEncode(255, 154, 167, 114);
416    m_pThemeData->clrSignBorderDisable = ArgbEncode(255, 202, 200, 187);
417    m_pThemeData->clrSignCheck = ArgbEncode(255, 164, 180, 138);
418    m_pThemeData->clrSignNeutral = ArgbEncode(2255, 28, 134, 26);
419    m_pThemeData->clrSignNeutralNormal = ArgbEncode(255, 114, 192, 113);
420    m_pThemeData->clrSignNeutralHover = ArgbEncode(255, 33, 161, 33);
421    m_pThemeData->clrSignNeutralPressed = ArgbEncode(255, 28, 134, 26);
422  } else {
423    *pData++ = 0, *pData++ = 0, *pData++ = ArgbEncode(255, 220, 220, 215),
424    *pData++ = ArgbEncode(255, 255, 255, 255),
425    *pData++ = ArgbEncode(255, 255, 240, 207),
426    *pData++ = ArgbEncode(255, 248, 179, 48),
427    *pData++ = ArgbEncode(255, 176, 176, 167),
428    *pData++ = ArgbEncode(255, 241, 239, 239),
429    *pData++ = ArgbEncode(255, 255, 255, 255),
430    *pData++ = ArgbEncode(255, 255, 255, 255),
431    *pData++ = ArgbEncode(255, 220, 220, 215),
432    *pData++ = ArgbEncode(255, 255, 255, 255),
433    *pData++ = ArgbEncode(255, 255, 240, 207),
434    *pData++ = ArgbEncode(255, 248, 179, 48),
435    *pData++ = ArgbEncode(255, 176, 176, 167),
436    *pData++ = ArgbEncode(255, 241, 239, 239),
437    *pData++ = ArgbEncode(255, 255, 255, 255),
438    *pData++ = ArgbEncode(255, 255, 255, 255),
439    *pData++ = ArgbEncode(255, 220, 220, 215),
440    *pData++ = ArgbEncode(255, 255, 255, 255),
441    *pData++ = ArgbEncode(255, 255, 240, 207),
442    *pData++ = ArgbEncode(255, 248, 179, 48),
443    *pData++ = ArgbEncode(255, 176, 176, 167),
444    *pData++ = ArgbEncode(255, 241, 239, 239),
445    *pData++ = ArgbEncode(255, 255, 255, 255),
446    *pData++ = ArgbEncode(255, 255, 255, 255);
447    m_pThemeData->clrSignBorderNormal = ArgbEncode(255, 28, 81, 128);
448    m_pThemeData->clrSignBorderDisable = ArgbEncode(255, 202, 200, 187);
449    m_pThemeData->clrSignCheck = ArgbEncode(255, 28, 81, 128);
450    m_pThemeData->clrSignNeutral = ArgbEncode(255, 28, 134, 26);
451    m_pThemeData->clrSignNeutralNormal = ArgbEncode(255, 114, 192, 113);
452    m_pThemeData->clrSignNeutralHover = ArgbEncode(255, 33, 161, 33);
453    m_pThemeData->clrSignNeutralPressed = ArgbEncode(255, 28, 134, 26);
454  }
455}
456void CFWL_CheckBoxTP::initCheckPath(FX_FLOAT fCheckLen) {
457  if (!m_pCheckPath) {
458    m_pCheckPath = new CFX_Path;
459    m_pCheckPath->Create();
460    FX_FLOAT fWidth = CHECKBOX_SIZE_SIGNPATH;
461    FX_FLOAT fHeight = -CHECKBOX_SIZE_SIGNPATH;
462    FX_FLOAT fBottom = CHECKBOX_SIZE_SIGNPATH;
463    FX_FLOAT px1, py1, px2, py2;
464    CFX_PointF pt1;
465    pt1.Set(fWidth / 15.0f, fBottom + fHeight * 2 / 5.0f);
466    CFX_PointF pt2;
467    pt2.Set(fWidth / 4.5f, fBottom + fHeight / 16.0f);
468    CFX_PointF pt3;
469    pt3.Set(fWidth / 3.0f, fBottom);
470    CFX_PointF pt4;
471    pt4.Set(fWidth * 14 / 15.0f, fBottom + fHeight * 15 / 16.0f);
472    CFX_PointF pt5;
473    pt5.Set(fWidth / 3.6f, fBottom + fHeight / 3.5f);
474    CFX_PointF pt12;
475    pt12.Set(fWidth / 7.0f, fBottom + fHeight * 2 / 7.0f);
476    CFX_PointF pt21;
477    pt21.Set(fWidth / 5.0f, fBottom + fHeight / 5.0f);
478    CFX_PointF pt23;
479    pt23.Set(fWidth / 4.4f, fBottom + fHeight * 0 / 16.0f);
480    CFX_PointF pt32;
481    pt32.Set(fWidth / 4.0f, fBottom);
482    CFX_PointF pt34;
483    pt34.Set(fWidth * (1 / 7.0f + 7 / 15.0f), fBottom + fHeight * 4 / 5.0f);
484    CFX_PointF pt43;
485    pt43.Set(fWidth * (1 / 7.0f + 7 / 15.0f), fBottom + fHeight * 4 / 5.0f);
486    CFX_PointF pt45;
487    pt45.Set(fWidth * 7 / 15.0f, fBottom + fHeight * 8 / 7.0f);
488    CFX_PointF pt54;
489    pt54.Set(fWidth / 3.4f, fBottom + fHeight / 3.5f);
490    CFX_PointF pt51;
491    pt51.Set(fWidth / 3.6f, fBottom + fHeight / 4.0f);
492    CFX_PointF pt15;
493    pt15.Set(fWidth / 3.5f, fBottom + fHeight * 3.5f / 5.0f);
494    m_pCheckPath->MoveTo(pt1.x, pt1.y);
495    px1 = pt12.x - pt1.x;
496    py1 = pt12.y - pt1.y;
497    px2 = pt21.x - pt2.x;
498    py2 = pt21.y - pt2.y;
499    m_pCheckPath->BezierTo(pt1.x + px1 * FWLTHEME_BEZIER,
500                           pt1.y + py1 * FWLTHEME_BEZIER,
501                           pt2.x + px2 * FWLTHEME_BEZIER,
502                           pt2.y + py2 * FWLTHEME_BEZIER, pt2.x, pt2.y);
503    px1 = pt23.x - pt2.x;
504    py1 = pt23.y - pt2.y;
505    px2 = pt32.x - pt3.x;
506    py2 = pt32.y - pt3.y;
507    m_pCheckPath->BezierTo(pt2.x + px1 * FWLTHEME_BEZIER,
508                           pt2.y + py1 * FWLTHEME_BEZIER,
509                           pt3.x + px2 * FWLTHEME_BEZIER,
510                           pt3.y + py2 * FWLTHEME_BEZIER, pt3.x, pt3.y);
511    px1 = pt34.x - pt3.x;
512    py1 = pt34.y - pt3.y;
513    px2 = pt43.x - pt4.x;
514    py2 = pt43.y - pt4.y;
515    m_pCheckPath->BezierTo(pt3.x + px1 * FWLTHEME_BEZIER,
516                           pt3.y + py1 * FWLTHEME_BEZIER,
517                           pt4.x + px2 * FWLTHEME_BEZIER,
518                           pt4.y + py2 * FWLTHEME_BEZIER, pt4.x, pt4.y);
519    px1 = pt45.x - pt4.x;
520    py1 = pt45.y - pt4.y;
521    px2 = pt54.x - pt5.x;
522    py2 = pt54.y - pt5.y;
523    m_pCheckPath->BezierTo(pt4.x + px1 * FWLTHEME_BEZIER,
524                           pt4.y + py1 * FWLTHEME_BEZIER,
525                           pt5.x + px2 * FWLTHEME_BEZIER,
526                           pt5.y + py2 * FWLTHEME_BEZIER, pt5.x, pt5.y);
527    px1 = pt51.x - pt5.x;
528    py1 = pt51.y - pt5.y;
529    px2 = pt15.x - pt1.x;
530    py2 = pt15.y - pt1.y;
531    m_pCheckPath->BezierTo(pt5.x + px1 * FWLTHEME_BEZIER,
532                           pt5.y + py1 * FWLTHEME_BEZIER,
533                           pt1.x + px2 * FWLTHEME_BEZIER,
534                           pt1.y + py2 * FWLTHEME_BEZIER, pt1.x, pt1.y);
535    FX_FLOAT fScale = fCheckLen / CHECKBOX_SIZE_SIGNPATH;
536    CFX_Matrix mt;
537    mt.Set(1, 0, 0, 1, 0, 0);
538    mt.Scale(fScale, fScale);
539    CFX_PathData* pData = m_pCheckPath->GetPathData();
540    pData->Transform(&mt);
541  }
542}
543