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