• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/fwl/theme/cfwl_checkboxtp.h"
8 
9 #include "core/fxge/cfx_pathdata.h"
10 #include "third_party/base/ptr_util.h"
11 #include "xfa/fde/cfde_textout.h"
12 #include "xfa/fwl/cfwl_checkbox.h"
13 #include "xfa/fwl/cfwl_themebackground.h"
14 #include "xfa/fwl/cfwl_themetext.h"
15 #include "xfa/fwl/cfwl_widget.h"
16 #include "xfa/fxgraphics/cxfa_gecolor.h"
17 #include "xfa/fxgraphics/cxfa_gepath.h"
18 
19 namespace {
20 
21 const int kSignPath = 100;
22 
ScaleBezierPoint(const CFX_PointF & point)23 CFX_PointF ScaleBezierPoint(const CFX_PointF& point) {
24   CFX_PointF scaled_point(point);
25   scaled_point.x *= FX_BEZIER;
26   scaled_point.y *= FX_BEZIER;
27   return scaled_point;
28 }
29 
30 }  // namespace
31 
32 #define CHECKBOX_COLOR_BOXLT1 (ArgbEncode(255, 172, 168, 153))
33 #define CHECKBOX_COLOR_BOXLT2 (ArgbEncode(255, 113, 111, 100))
34 #define CHECKBOX_COLOR_BOXRB1 (ArgbEncode(255, 241, 239, 226))
35 #define CHECKBOX_COLOR_BOXRB2 (ArgbEncode(255, 255, 255, 255))
36 
CFWL_CheckBoxTP()37 CFWL_CheckBoxTP::CFWL_CheckBoxTP() : m_pThemeData(new CKBThemeData) {
38   SetThemeData();
39 }
40 
~CFWL_CheckBoxTP()41 CFWL_CheckBoxTP::~CFWL_CheckBoxTP() {
42   if (m_pCheckPath)
43     m_pCheckPath->Clear();
44 }
45 
Initialize()46 void CFWL_CheckBoxTP::Initialize() {
47   CFWL_WidgetTP::Initialize();
48   InitTTO();
49 }
50 
Finalize()51 void CFWL_CheckBoxTP::Finalize() {
52   FinalizeTTO();
53   CFWL_WidgetTP::Finalize();
54 }
55 
DrawText(CFWL_ThemeText * pParams)56 void CFWL_CheckBoxTP::DrawText(CFWL_ThemeText* pParams) {
57   if (!m_pTextOut)
58     return;
59 
60   m_pTextOut->SetTextColor(pParams->m_dwStates & CFWL_PartState_Disabled
61                                ? FWLTHEME_CAPACITY_TextDisColor
62                                : FWLTHEME_CAPACITY_TextColor);
63   CFWL_WidgetTP::DrawText(pParams);
64 }
65 
DrawSignCheck(CXFA_Graphics * pGraphics,const CFX_RectF * pRtSign,FX_ARGB argbFill,CFX_Matrix * pMatrix)66 void CFWL_CheckBoxTP::DrawSignCheck(CXFA_Graphics* pGraphics,
67                                     const CFX_RectF* pRtSign,
68                                     FX_ARGB argbFill,
69                                     CFX_Matrix* pMatrix) {
70   if (!m_pCheckPath)
71     InitCheckPath(pRtSign->width);
72 
73   CFX_Matrix mt;
74   mt.Translate(pRtSign->left, pRtSign->top);
75   mt.Concat(*pMatrix);
76   pGraphics->SaveGraphState();
77   pGraphics->SetFillColor(CXFA_GEColor(argbFill));
78   pGraphics->FillPath(m_pCheckPath.get(), FXFILL_WINDING, &mt);
79   pGraphics->RestoreGraphState();
80 }
81 
DrawSignCircle(CXFA_Graphics * pGraphics,const CFX_RectF * pRtSign,FX_ARGB argbFill,CFX_Matrix * pMatrix)82 void CFWL_CheckBoxTP::DrawSignCircle(CXFA_Graphics* pGraphics,
83                                      const CFX_RectF* pRtSign,
84                                      FX_ARGB argbFill,
85                                      CFX_Matrix* pMatrix) {
86   CXFA_GEPath path;
87   path.AddEllipse(*pRtSign);
88   pGraphics->SaveGraphState();
89   pGraphics->SetFillColor(CXFA_GEColor(argbFill));
90   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
91   pGraphics->RestoreGraphState();
92 }
93 
DrawSignCross(CXFA_Graphics * pGraphics,const CFX_RectF * pRtSign,FX_ARGB argbFill,CFX_Matrix * pMatrix)94 void CFWL_CheckBoxTP::DrawSignCross(CXFA_Graphics* pGraphics,
95                                     const CFX_RectF* pRtSign,
96                                     FX_ARGB argbFill,
97                                     CFX_Matrix* pMatrix) {
98   CXFA_GEPath path;
99   float fRight = pRtSign->right();
100   float fBottom = pRtSign->bottom();
101   path.AddLine(pRtSign->TopLeft(), CFX_PointF(fRight, fBottom));
102   path.AddLine(CFX_PointF(pRtSign->left, fBottom),
103                CFX_PointF(fRight, pRtSign->top));
104 
105   pGraphics->SaveGraphState();
106   pGraphics->SetStrokeColor(CXFA_GEColor(argbFill));
107   pGraphics->SetLineWidth(1.0f);
108   pGraphics->StrokePath(&path, pMatrix);
109   pGraphics->RestoreGraphState();
110 }
111 
DrawSignDiamond(CXFA_Graphics * pGraphics,const CFX_RectF * pRtSign,FX_ARGB argbFill,CFX_Matrix * pMatrix)112 void CFWL_CheckBoxTP::DrawSignDiamond(CXFA_Graphics* pGraphics,
113                                       const CFX_RectF* pRtSign,
114                                       FX_ARGB argbFill,
115                                       CFX_Matrix* pMatrix) {
116   CXFA_GEPath path;
117   float fWidth = pRtSign->width;
118   float fHeight = pRtSign->height;
119   float fBottom = pRtSign->bottom();
120   path.MoveTo(CFX_PointF(pRtSign->left + fWidth / 2, pRtSign->top));
121   path.LineTo(CFX_PointF(pRtSign->left, pRtSign->top + fHeight / 2));
122   path.LineTo(CFX_PointF(pRtSign->left + fWidth / 2, fBottom));
123   path.LineTo(CFX_PointF(pRtSign->right(), pRtSign->top + fHeight / 2));
124   path.LineTo(CFX_PointF(pRtSign->left + fWidth / 2, pRtSign->top));
125 
126   pGraphics->SaveGraphState();
127   pGraphics->SetFillColor(CXFA_GEColor(argbFill));
128   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
129   pGraphics->RestoreGraphState();
130 }
131 
DrawSignSquare(CXFA_Graphics * pGraphics,const CFX_RectF * pRtSign,FX_ARGB argbFill,CFX_Matrix * pMatrix)132 void CFWL_CheckBoxTP::DrawSignSquare(CXFA_Graphics* pGraphics,
133                                      const CFX_RectF* pRtSign,
134                                      FX_ARGB argbFill,
135                                      CFX_Matrix* pMatrix) {
136   CXFA_GEPath path;
137   path.AddRectangle(pRtSign->left, pRtSign->top, pRtSign->width,
138                     pRtSign->height);
139   pGraphics->SaveGraphState();
140   pGraphics->SetFillColor(CXFA_GEColor(argbFill));
141   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
142   pGraphics->RestoreGraphState();
143 }
144 
DrawSignStar(CXFA_Graphics * pGraphics,const CFX_RectF * pRtSign,FX_ARGB argbFill,CFX_Matrix * pMatrix)145 void CFWL_CheckBoxTP::DrawSignStar(CXFA_Graphics* pGraphics,
146                                    const CFX_RectF* pRtSign,
147                                    FX_ARGB argbFill,
148                                    CFX_Matrix* pMatrix) {
149   CXFA_GEPath path;
150   float fBottom = pRtSign->bottom();
151   float fRadius =
152       (pRtSign->top - fBottom) / (1 + static_cast<float>(cos(FX_PI / 5.0f)));
153   CFX_PointF ptCenter((pRtSign->left + pRtSign->right()) / 2.0f,
154                       (pRtSign->top + fBottom) / 2.0f);
155 
156   CFX_PointF points[5];
157   float fAngel = FX_PI / 10.0f;
158   for (int32_t i = 0; i < 5; i++) {
159     points[i] =
160         ptCenter + CFX_PointF(fRadius * static_cast<float>(cos(fAngel)),
161                               fRadius * static_cast<float>(sin(fAngel)));
162     fAngel += FX_PI * 2 / 5.0f;
163   }
164 
165   path.MoveTo(points[0]);
166   int32_t nNext = 0;
167   for (int32_t j = 0; j < 5; j++) {
168     nNext += 2;
169     if (nNext >= 5)
170       nNext -= 5;
171 
172     path.LineTo(points[nNext]);
173   }
174   pGraphics->SaveGraphState();
175   pGraphics->SetFillColor(CXFA_GEColor(argbFill));
176   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
177   pGraphics->RestoreGraphState();
178 }
179 
SetThemeData()180 void CFWL_CheckBoxTP::SetThemeData() {
181   uint32_t* pData = (uint32_t*)&m_pThemeData->clrBoxBk;
182 
183   *pData++ = 0;
184   *pData++ = 0;
185   *pData++ = ArgbEncode(255, 220, 220, 215),
186   *pData++ = ArgbEncode(255, 255, 255, 255),
187   *pData++ = ArgbEncode(255, 255, 240, 207),
188   *pData++ = ArgbEncode(255, 248, 179, 48),
189   *pData++ = ArgbEncode(255, 176, 176, 167),
190   *pData++ = ArgbEncode(255, 241, 239, 239),
191   *pData++ = ArgbEncode(255, 255, 255, 255),
192   *pData++ = ArgbEncode(255, 255, 255, 255),
193   *pData++ = ArgbEncode(255, 220, 220, 215),
194   *pData++ = ArgbEncode(255, 255, 255, 255),
195   *pData++ = ArgbEncode(255, 255, 240, 207),
196   *pData++ = ArgbEncode(255, 248, 179, 48),
197   *pData++ = ArgbEncode(255, 176, 176, 167),
198   *pData++ = ArgbEncode(255, 241, 239, 239),
199   *pData++ = ArgbEncode(255, 255, 255, 255),
200   *pData++ = ArgbEncode(255, 255, 255, 255),
201   *pData++ = ArgbEncode(255, 220, 220, 215),
202   *pData++ = ArgbEncode(255, 255, 255, 255),
203   *pData++ = ArgbEncode(255, 255, 240, 207),
204   *pData++ = ArgbEncode(255, 248, 179, 48),
205   *pData++ = ArgbEncode(255, 176, 176, 167),
206   *pData++ = ArgbEncode(255, 241, 239, 239),
207   *pData++ = ArgbEncode(255, 255, 255, 255),
208   *pData++ = ArgbEncode(255, 255, 255, 255);
209   m_pThemeData->clrSignBorderNormal = ArgbEncode(255, 28, 81, 128);
210   m_pThemeData->clrSignBorderDisable = ArgbEncode(255, 202, 200, 187);
211   m_pThemeData->clrSignCheck = ArgbEncode(255, 28, 81, 128);
212   m_pThemeData->clrSignNeutral = ArgbEncode(255, 28, 134, 26);
213   m_pThemeData->clrSignNeutralNormal = ArgbEncode(255, 114, 192, 113);
214   m_pThemeData->clrSignNeutralHover = ArgbEncode(255, 33, 161, 33);
215   m_pThemeData->clrSignNeutralPressed = ArgbEncode(255, 28, 134, 26);
216 }
217 
InitCheckPath(float fCheckLen)218 void CFWL_CheckBoxTP::InitCheckPath(float fCheckLen) {
219   if (!m_pCheckPath) {
220     m_pCheckPath = pdfium::MakeUnique<CXFA_GEPath>();
221 
222     float fWidth = kSignPath;
223     float fHeight = -kSignPath;
224     float fBottom = kSignPath;
225     CFX_PointF pt1(fWidth / 15.0f, fBottom + fHeight * 2 / 5.0f);
226     CFX_PointF pt2(fWidth / 4.5f, fBottom + fHeight / 16.0f);
227     CFX_PointF pt3(fWidth / 3.0f, fBottom);
228     CFX_PointF pt4(fWidth * 14 / 15.0f, fBottom + fHeight * 15 / 16.0f);
229     CFX_PointF pt5(fWidth / 3.6f, fBottom + fHeight / 3.5f);
230     CFX_PointF pt12(fWidth / 7.0f, fBottom + fHeight * 2 / 7.0f);
231     CFX_PointF pt21(fWidth / 5.0f, fBottom + fHeight / 5.0f);
232     CFX_PointF pt23(fWidth / 4.4f, fBottom + fHeight * 0 / 16.0f);
233     CFX_PointF pt32(fWidth / 4.0f, fBottom);
234     CFX_PointF pt34(fWidth * (1 / 7.0f + 7 / 15.0f),
235                     fBottom + fHeight * 4 / 5.0f);
236     CFX_PointF pt43(fWidth * (1 / 7.0f + 7 / 15.0f),
237                     fBottom + fHeight * 4 / 5.0f);
238     CFX_PointF pt45(fWidth * 7 / 15.0f, fBottom + fHeight * 8 / 7.0f);
239     CFX_PointF pt54(fWidth / 3.4f, fBottom + fHeight / 3.5f);
240     CFX_PointF pt51(fWidth / 3.6f, fBottom + fHeight / 4.0f);
241     CFX_PointF pt15(fWidth / 3.5f, fBottom + fHeight * 3.5f / 5.0f);
242     m_pCheckPath->MoveTo(pt1);
243 
244     CFX_PointF p1 = ScaleBezierPoint(pt12 - pt1);
245     CFX_PointF p2 = ScaleBezierPoint(pt21 - pt2);
246     m_pCheckPath->BezierTo(pt1 + p1, pt2 + p2, pt2);
247 
248     p1 = ScaleBezierPoint(pt23 - pt2);
249     p2 = ScaleBezierPoint(pt32 - pt3);
250     m_pCheckPath->BezierTo(pt2 + p1, pt3 + p2, pt3);
251 
252     p1 = ScaleBezierPoint(pt34 - pt3);
253     p2 = ScaleBezierPoint(pt43 - pt4);
254     m_pCheckPath->BezierTo(pt3 + p1, pt4 + p2, pt4);
255 
256     p1 = ScaleBezierPoint(pt45 - pt4);
257     p2 = ScaleBezierPoint(pt54 - pt5);
258     m_pCheckPath->BezierTo(pt4 + p1, pt5 + p2, pt5);
259 
260     p1 = ScaleBezierPoint(pt51 - pt5);
261     p2 = ScaleBezierPoint(pt15 - pt1);
262     m_pCheckPath->BezierTo(pt5 + p1, pt1 + p2, pt1);
263 
264     float fScale = fCheckLen / kSignPath;
265     CFX_Matrix mt;
266     mt.Scale(fScale, fScale);
267 
268     m_pCheckPath->TransformBy(mt);
269   }
270 }
271 
DrawBackground(CFWL_ThemeBackground * pParams)272 void CFWL_CheckBoxTP::DrawBackground(CFWL_ThemeBackground* pParams) {
273   if (pParams->m_iPart != CFWL_Part::CheckBox)
274     return;
275 
276   if ((pParams->m_dwStates & CFWL_PartState_Checked) ||
277       (pParams->m_dwStates & CFWL_PartState_Neutral)) {
278     DrawCheckSign(pParams->m_pWidget, pParams->m_pGraphics, pParams->m_rtPart,
279                   pParams->m_dwStates, &pParams->m_matrix);
280   }
281 }
282 
DrawCheckSign(CFWL_Widget * pWidget,CXFA_Graphics * pGraphics,const CFX_RectF & pRtBox,int32_t iState,CFX_Matrix * pMatrix)283 void CFWL_CheckBoxTP::DrawCheckSign(CFWL_Widget* pWidget,
284                                     CXFA_Graphics* pGraphics,
285                                     const CFX_RectF& pRtBox,
286                                     int32_t iState,
287                                     CFX_Matrix* pMatrix) {
288   CFX_RectF rtSign(pRtBox);
289   uint32_t dwColor = iState & CFWL_PartState_Neutral ? 0xFFA9A9A9 : 0xFF000000;
290 
291   uint32_t dwStyle = pWidget->GetStylesEx();
292   rtSign.Deflate(rtSign.width / 4, rtSign.height / 4);
293   switch (dwStyle & FWL_STYLEEXT_CKB_SignShapeMask) {
294     case FWL_STYLEEXT_CKB_SignShapeCheck:
295       DrawSignCheck(pGraphics, &rtSign, dwColor, pMatrix);
296       break;
297     case FWL_STYLEEXT_CKB_SignShapeCircle:
298       DrawSignCircle(pGraphics, &rtSign, dwColor, pMatrix);
299       break;
300     case FWL_STYLEEXT_CKB_SignShapeCross:
301       DrawSignCross(pGraphics, &rtSign, dwColor, pMatrix);
302       break;
303     case FWL_STYLEEXT_CKB_SignShapeDiamond:
304       DrawSignDiamond(pGraphics, &rtSign, dwColor, pMatrix);
305       break;
306     case FWL_STYLEEXT_CKB_SignShapeSquare:
307       DrawSignSquare(pGraphics, &rtSign, dwColor, pMatrix);
308       break;
309     case FWL_STYLEEXT_CKB_SignShapeStar:
310       DrawSignStar(pGraphics, &rtSign, dwColor, pMatrix);
311       break;
312     default:
313       break;
314   }
315 }
316