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 <algorithm> 8 9 #include "xfa/src/foxitlib.h" 10 static void FWL_SetChildThemeID(IFWL_Widget* pParent, FX_DWORD dwThemeID) { 11 IFWL_WidgetMgr* pWidgetMgr = FWL_GetWidgetMgr(); 12 IFWL_Widget* pChild = 13 pWidgetMgr->GetWidget(pParent, FWL_WGTRELATION_FirstChild); 14 while (pChild) { 15 IFWL_ThemeProvider* pTheme = pChild->GetThemeProvider(); 16 if (pTheme) { 17 pTheme->SetThemeID(pChild, dwThemeID, FALSE); 18 } 19 FWL_SetChildThemeID(pChild, dwThemeID); 20 pChild = pWidgetMgr->GetWidget(pChild, FWL_WGTRELATION_NextSibling); 21 } 22 } 23 FX_BOOL CFWL_WidgetTP::IsValidWidget(IFWL_Widget* pWidget) { 24 return FALSE; 25 } 26 FX_DWORD CFWL_WidgetTP::GetThemeID(IFWL_Widget* pWidget) { 27 return m_dwThemeID; 28 } 29 FX_DWORD CFWL_WidgetTP::SetThemeID(IFWL_Widget* pWidget, 30 FX_DWORD dwThemeID, 31 FX_BOOL bChildren) { 32 FX_DWORD dwOld = m_dwThemeID; 33 m_dwThemeID = dwThemeID; 34 if (CFWL_ArrowData::IsInstance()) { 35 CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(dwThemeID)); 36 } 37 if (bChildren) { 38 FWL_SetChildThemeID(pWidget, dwThemeID); 39 } 40 return dwOld; 41 } 42 FWL_ERR CFWL_WidgetTP::GetThemeMatrix(IFWL_Widget* pWidget, 43 CFX_Matrix& matrix) { 44 matrix.Set(_ctm.a, _ctm.b, _ctm.c, _ctm.d, _ctm.e, _ctm.f); 45 return FWL_ERR_Succeeded; 46 } 47 FWL_ERR CFWL_WidgetTP::SetThemeMatrix(IFWL_Widget* pWidget, 48 const CFX_Matrix& matrix) { 49 _ctm.Set(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f); 50 return FWL_ERR_Succeeded; 51 } 52 FX_BOOL CFWL_WidgetTP::DrawBackground(CFWL_ThemeBackground* pParams) { 53 return TRUE; 54 } 55 FX_BOOL CFWL_WidgetTP::DrawText(CFWL_ThemeText* pParams) { 56 if (!m_pTextOut) { 57 InitTTO(); 58 } 59 int32_t iLen = pParams->m_wsText.GetLength(); 60 if (iLen <= 0) 61 return FALSE; 62 CFX_Graphics* pGraphics = pParams->m_pGraphics; 63 m_pTextOut->SetRenderDevice(pGraphics->GetRenderDevice()); 64 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 65 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 66 CFX_Matrix* pMatrix = &pParams->m_matrix; 67 pMatrix->Concat(*pGraphics->GetMatrix()); 68 m_pTextOut->SetMatrix(*pMatrix); 69 m_pTextOut->DrawLogicText(pParams->m_wsText, iLen, pParams->m_rtPart); 70 return TRUE; 71 } 72 void* CFWL_WidgetTP::GetCapacity(CFWL_ThemePart* pThemePart, 73 FX_DWORD dwCapacity) { 74 switch (dwCapacity) { 75 case FWL_WGTCAPACITY_CXBorder: { 76 m_fValue = FWLTHEME_CAPACITY_CXBorder; 77 break; 78 } 79 case FWL_WGTCAPACITY_CYBorder: { 80 m_fValue = FWLTHEME_CAPACITY_CYBorder; 81 break; 82 } 83 case FWL_WGTCAPACITY_EdgeFlat: { 84 m_fValue = FWLTHEME_CAPACITY_EdgeFlat; 85 break; 86 } 87 case FWL_WGTCAPACITY_EdgeRaised: { 88 m_fValue = FWLTHEME_CAPACITY_EdgeRaised; 89 break; 90 } 91 case FWL_WGTCAPACITY_EdgeSunken: { 92 m_fValue = FWLTHEME_CAPACITY_EdgeSunken; 93 break; 94 } 95 case FWL_WGTCAPACITY_FontSize: { 96 m_fValue = FWLTHEME_CAPACITY_FontSize; 97 break; 98 } 99 case FWL_WGTCAPACITY_TextColor: { 100 m_dwValue = FWLTHEME_CAPACITY_TextColor; 101 return &m_dwValue; 102 } 103 case FWL_WGTCAPACITY_ScrollBarWidth: { 104 m_fValue = FWLTHEME_CAPACITY_ScrollBarWidth; 105 break; 106 } 107 case FWL_WGTCAPACITY_Font: { 108 return m_pFDEFont; 109 } 110 case FWL_WGTCAPACITY_TextSelColor: { 111 m_dwValue = (m_dwThemeID == 0) ? FWLTHEME_CAPACITY_TextSelColor 112 : FWLTHEME_COLOR_Green_BKSelected; 113 return &m_dwValue; 114 } 115 case FWL_WGTCAPACITY_LineHeight: { 116 m_fValue = FWLTHEME_CAPACITY_LineHeight; 117 break; 118 } 119 case FWL_WGTCAPACITY_UIMargin: { 120 m_rtMargin.Set(0, 0, 0, 0); 121 return &m_rtMargin; 122 } 123 default: { return NULL; } 124 } 125 return &m_fValue; 126 } 127 FX_BOOL CFWL_WidgetTP::IsCustomizedLayout(IFWL_Widget* pWidget) { 128 return FWL_GetThemeLayout(m_dwThemeID); 129 } 130 FWL_ERR CFWL_WidgetTP::GetPartRect(CFWL_ThemePart* pThemePart, 131 CFX_RectF& rect) { 132 return FWL_ERR_Succeeded; 133 } 134 FX_BOOL CFWL_WidgetTP::IsInPart(CFWL_ThemePart* pThemePart, 135 FX_FLOAT fx, 136 FX_FLOAT fy) { 137 return TRUE; 138 } 139 FX_BOOL CFWL_WidgetTP::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) { 140 if (!pParams) 141 return FALSE; 142 if (!m_pTextOut) 143 return FALSE; 144 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 145 m_pTextOut->SetStyles(pParams->m_dwTTOStyles | FDE_TTOSTYLE_ArabicContext); 146 m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(), 147 rect); 148 return TRUE; 149 } 150 FWL_ERR CFWL_WidgetTP::Initialize() { 151 m_dwThemeID = 0; 152 _ctm.SetIdentity(); 153 return FWL_ERR_Succeeded; 154 } 155 FWL_ERR CFWL_WidgetTP::Finalize() { 156 if (!m_pTextOut) { 157 FinalizeTTO(); 158 } 159 return FWL_ERR_Succeeded; 160 } 161 CFWL_WidgetTP::~CFWL_WidgetTP() {} 162 FWL_ERR CFWL_WidgetTP::SetFont(IFWL_Widget* pWidget, 163 const FX_WCHAR* strFont, 164 FX_FLOAT fFontSize, 165 FX_ARGB rgbFont) { 166 if (!m_pTextOut) { 167 return FWL_ERR_Succeeded; 168 } 169 m_pFDEFont = FWL_GetFontManager()->FindFont(strFont, 0, 0); 170 m_pTextOut->SetFont(m_pFDEFont); 171 m_pTextOut->SetFontSize(fFontSize); 172 m_pTextOut->SetTextColor(rgbFont); 173 return FWL_ERR_Succeeded; 174 } 175 FWL_ERR CFWL_WidgetTP::SetFont(IFWL_Widget* pWidget, 176 IFX_Font* pFont, 177 FX_FLOAT fFontSize, 178 FX_ARGB rgbFont) { 179 if (!m_pTextOut) { 180 return FWL_ERR_Succeeded; 181 } 182 m_pTextOut->SetFont(pFont); 183 m_pTextOut->SetFontSize(fFontSize); 184 m_pTextOut->SetTextColor(rgbFont); 185 return FWL_ERR_Succeeded; 186 } 187 IFX_Font* CFWL_WidgetTP::GetFont(IFWL_Widget* pWidget) { 188 return m_pFDEFont; 189 } 190 CFWL_WidgetTP::CFWL_WidgetTP() 191 : m_dwRefCount(1), m_pTextOut(NULL), m_pFDEFont(NULL), m_dwThemeID(0) {} 192 FX_ERR CFWL_WidgetTP::InitTTO() { 193 if (m_pTextOut) { 194 return FWL_ERR_Succeeded; 195 } 196 m_pFDEFont = FWL_GetFontManager()->FindFont(FX_WSTRC(L"Helvetica"), 0, 0); 197 m_pTextOut = IFDE_TextOut::Create(); 198 m_pTextOut->SetFont(m_pFDEFont); 199 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize); 200 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor); 201 m_pTextOut->SetEllipsisString(L"..."); 202 return FWL_ERR_Succeeded; 203 } 204 FX_ERR CFWL_WidgetTP::FinalizeTTO() { 205 if (m_pTextOut) { 206 m_pTextOut->Release(); 207 m_pTextOut = NULL; 208 } 209 return FWL_ERR_Succeeded; 210 } 211 #ifdef THEME_XPSimilar 212 void CFWL_WidgetTP::DrawEdge(CFX_Graphics* pGraphics, 213 FX_DWORD dwStyles, 214 const CFX_RectF* pRect, 215 CFX_Matrix* pMatrix) { 216 if (!pGraphics) 217 return; 218 if (!pRect) 219 return; 220 pGraphics->SaveGraphState(); 221 CFX_Color crStroke(FWL_GetThemeColor(m_dwThemeID) == 0 222 ? ArgbEncode(255, 127, 157, 185) 223 : FWLTHEME_COLOR_Green_BKSelected); 224 pGraphics->SetStrokeColor(&crStroke); 225 CFX_Path path; 226 path.Create(); 227 path.AddRectangle(pRect->left, pRect->top, pRect->width - 1, 228 pRect->height - 1); 229 pGraphics->StrokePath(&path, pMatrix); 230 path.Clear(); 231 crStroke = ArgbEncode(255, 255, 255, 255); 232 pGraphics->SetStrokeColor(&crStroke); 233 path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 3, 234 pRect->height - 3); 235 pGraphics->StrokePath(&path, pMatrix); 236 pGraphics->RestoreGraphState(); 237 } 238 #else 239 void CFWL_WidgetTP::DrawEdge(CFX_Graphics* pGraphics, 240 FX_DWORD dwStyles, 241 const CFX_RectF* pRect, 242 CFX_Matrix* pMatrix) { 243 if (!pGraphics) 244 return; 245 if (!pRect) 246 return; 247 FWLTHEME_EDGE eType; 248 FX_FLOAT fWidth; 249 switch (dwStyles & FWL_WGTSTYLE_EdgeMask) { 250 case FWL_WGTSTYLE_EdgeRaised: { 251 eType = FWLTHEME_EDGE_Raised, fWidth = FWLTHEME_CAPACITY_EdgeRaised; 252 break; 253 } 254 case FWL_WGTSTYLE_EdgeSunken: { 255 eType = FWLTHEME_EDGE_Sunken, fWidth = FWLTHEME_CAPACITY_EdgeSunken; 256 break; 257 } 258 case FWL_WGTSTYLE_EdgeFlat: 259 default: { return; } 260 } 261 Draw3DRect(pGraphics, eType, fWidth, pRect, FWLTHEME_COLOR_EDGELT1, 262 FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1, 263 FWLTHEME_COLOR_EDGERB2, pMatrix); 264 } 265 #endif 266 void CFWL_WidgetTP::Draw3DRect(CFX_Graphics* pGraphics, 267 FWLTHEME_EDGE eType, 268 FX_FLOAT fWidth, 269 const CFX_RectF* pRect, 270 FX_ARGB cr1, 271 FX_ARGB cr2, 272 FX_ARGB cr3, 273 FX_ARGB cr4, 274 CFX_Matrix* pMatrix) { 275 if (!pGraphics) 276 return; 277 if (!pRect) 278 return; 279 pGraphics->SaveGraphState(); 280 if (eType == FWLTHEME_EDGE_Flat) { 281 CFX_Path path; 282 path.Create(); 283 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); 284 path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2, 285 pRect->height - 2); 286 CFX_Color cr(ArgbEncode(255, 100, 100, 100)); 287 pGraphics->SetFillColor(&cr); 288 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); 289 path.Clear(); 290 path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2, 291 pRect->height - 2); 292 path.AddRectangle(pRect->left + 2, pRect->top + 2, pRect->width - 4, 293 pRect->height - 4); 294 cr.Set(0xFFFFFFFF); 295 pGraphics->SetFillColor(&cr); 296 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); 297 } else { 298 FX_FLOAT fLeft = pRect->left; 299 FX_FLOAT fRight = pRect->right(); 300 FX_FLOAT fTop = pRect->top; 301 FX_FLOAT fBottom = pRect->bottom(); 302 FX_FLOAT fHalfWidth = fWidth / 2.0f; 303 CFX_Color crLT(eType == FWLTHEME_EDGE_Raised ? cr4 : cr1); 304 pGraphics->SetFillColor(&crLT); 305 CFX_Path pathLT; 306 pathLT.Create(); 307 pathLT.MoveTo(fLeft, fBottom - fHalfWidth); 308 pathLT.LineTo(fLeft, fTop); 309 pathLT.LineTo(fRight - fHalfWidth, fTop); 310 pathLT.LineTo(fRight - fHalfWidth, fTop + fHalfWidth); 311 pathLT.LineTo(fLeft + fHalfWidth, fTop + fHalfWidth); 312 pathLT.LineTo(fLeft + fHalfWidth, fBottom - fHalfWidth); 313 pathLT.LineTo(fLeft, fBottom - fHalfWidth); 314 pGraphics->FillPath(&pathLT, FXFILL_WINDING, pMatrix); 315 crLT = CFX_Color(eType == FWLTHEME_EDGE_Raised ? cr3 : cr2); 316 pGraphics->SetFillColor(&crLT); 317 pathLT.Clear(); 318 pathLT.MoveTo(fLeft + fHalfWidth, fBottom - fWidth); 319 pathLT.LineTo(fLeft + fHalfWidth, fTop + fHalfWidth); 320 pathLT.LineTo(fRight - fWidth, fTop + fHalfWidth); 321 pathLT.LineTo(fRight - fWidth, fTop + fWidth); 322 pathLT.LineTo(fLeft + fWidth, fTop + fWidth); 323 pathLT.LineTo(fLeft + fWidth, fBottom - fWidth); 324 pathLT.LineTo(fLeft + fHalfWidth, fBottom - fWidth); 325 pGraphics->FillPath(&pathLT, FXFILL_WINDING, pMatrix); 326 CFX_Color crRB(eType == FWLTHEME_EDGE_Raised ? cr1 : cr3); 327 pGraphics->SetFillColor(&crRB); 328 CFX_Path pathRB; 329 pathRB.Create(); 330 pathRB.MoveTo(fRight - fHalfWidth, fTop + fHalfWidth); 331 pathRB.LineTo(fRight - fHalfWidth, fBottom - fHalfWidth); 332 pathRB.LineTo(fLeft + fHalfWidth, fBottom - fHalfWidth); 333 pathRB.LineTo(fLeft + fHalfWidth, fBottom - fWidth); 334 pathRB.LineTo(fRight - fWidth, fBottom - fWidth); 335 pathRB.LineTo(fRight - fWidth, fTop + fHalfWidth); 336 pathRB.LineTo(fRight - fHalfWidth, fTop + fHalfWidth); 337 pGraphics->FillPath(&pathRB, FXFILL_WINDING, pMatrix); 338 crRB = CFX_Color(eType == FWLTHEME_EDGE_Raised ? cr2 : cr4); 339 pGraphics->SetFillColor(&crRB); 340 pathRB.Clear(); 341 pathRB.MoveTo(fRight, fTop); 342 pathRB.LineTo(fRight, fBottom); 343 pathRB.LineTo(fLeft, fBottom); 344 pathRB.LineTo(fLeft, fBottom - fHalfWidth); 345 pathRB.LineTo(fRight - fHalfWidth, fBottom - fHalfWidth); 346 pathRB.LineTo(fRight - fHalfWidth, fTop); 347 pathRB.LineTo(fRight, fTop); 348 pGraphics->FillPath(&pathRB, FXFILL_WINDING, pMatrix); 349 } 350 pGraphics->RestoreGraphState(); 351 } 352 void CFWL_WidgetTP::Draw3DCircle(CFX_Graphics* pGraphics, 353 FWLTHEME_EDGE eType, 354 FX_FLOAT fWidth, 355 const CFX_RectF* pRect, 356 FX_ARGB cr1, 357 FX_ARGB cr2, 358 FX_ARGB cr3, 359 FX_ARGB cr4, 360 CFX_Matrix* pMatrix) { 361 if (!pGraphics) 362 return; 363 if (!pRect) 364 return; 365 pGraphics->SaveGraphState(); 366 CFX_Path path; 367 path.Create(); 368 path.AddArc(pRect->left, pRect->top, pRect->width, pRect->height, 369 FWLTHEME_PI * 3 / 4, FWLTHEME_PI); 370 CFX_Color crFill1(eType == FWLTHEME_EDGE_Raised ? cr4 : cr1); 371 pGraphics->SetStrokeColor(&crFill1); 372 pGraphics->StrokePath(&path, pMatrix); 373 CFX_RectF rtInner(*pRect); 374 rtInner.Deflate(pRect->width / 4, pRect->height / 4); 375 path.Clear(); 376 path.AddArc(rtInner.left, rtInner.top, rtInner.width, rtInner.height, 377 FWLTHEME_PI * 3 / 4, FWLTHEME_PI); 378 CFX_Color crFill2(eType == FWLTHEME_EDGE_Raised ? cr3 : cr2); 379 pGraphics->SetStrokeColor(&crFill2); 380 pGraphics->StrokePath(&path, pMatrix); 381 path.Clear(); 382 path.AddArc(pRect->left, pRect->top, pRect->width, pRect->height, 383 FWLTHEME_PI * 7 / 4, FWLTHEME_PI); 384 CFX_Color crFill3(eType == FWLTHEME_EDGE_Raised ? cr1 : cr3); 385 pGraphics->SetStrokeColor(&crFill3); 386 pGraphics->StrokePath(&path, pMatrix); 387 path.AddArc(rtInner.left, rtInner.top, rtInner.width, rtInner.height, 388 FWLTHEME_PI * 7 / 4, FWLTHEME_PI); 389 CFX_Color crFill4(eType == FWLTHEME_EDGE_Raised ? cr2 : cr4); 390 pGraphics->SetStrokeColor(&crFill4); 391 pGraphics->StrokePath(&path, pMatrix); 392 pGraphics->RestoreGraphState(); 393 } 394 void CFWL_WidgetTP::DrawBorder(CFX_Graphics* pGraphics, 395 const CFX_RectF* pRect, 396 CFX_Matrix* pMatrix) { 397 if (!pGraphics) 398 return; 399 if (!pRect) 400 return; 401 CFX_Path path; 402 path.Create(); 403 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); 404 path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2, 405 pRect->height - 2); 406 pGraphics->SaveGraphState(); 407 CFX_Color crFill(ArgbEncode(255, 0, 0, 0)); 408 pGraphics->SetFillColor(&crFill); 409 pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix); 410 pGraphics->RestoreGraphState(); 411 } 412 void CFWL_WidgetTP::FillBackground(CFX_Graphics* pGraphics, 413 const CFX_RectF* pRect, 414 CFX_Matrix* pMatrix) { 415 FillSoildRect(pGraphics, FWLTHEME_COLOR_Background, pRect, pMatrix); 416 } 417 void CFWL_WidgetTP::FillSoildRect(CFX_Graphics* pGraphics, 418 FX_ARGB fillColor, 419 const CFX_RectF* pRect, 420 CFX_Matrix* pMatrix) { 421 if (!pGraphics) 422 return; 423 if (!pRect) 424 return; 425 pGraphics->SaveGraphState(); 426 CFX_Color crFill(fillColor); 427 pGraphics->SetFillColor(&crFill); 428 CFX_Path path; 429 path.Create(); 430 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); 431 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); 432 pGraphics->RestoreGraphState(); 433 } 434 void CFWL_WidgetTP::DrawAxialShading(CFX_Graphics* pGraphics, 435 FX_FLOAT fx1, 436 FX_FLOAT fy1, 437 FX_FLOAT fx2, 438 FX_FLOAT fy2, 439 FX_ARGB beginColor, 440 FX_ARGB endColor, 441 CFX_Path* path, 442 int32_t fillMode, 443 CFX_Matrix* pMatrix) { 444 if (!pGraphics) 445 return; 446 if (!path) 447 return; 448 CFX_PointF begPoint, endPoint; 449 begPoint.Set(fx1, fy1); 450 endPoint.Set(fx2, fy2); 451 CFX_Shading shading; 452 shading.CreateAxial(begPoint, endPoint, FALSE, FALSE, beginColor, endColor); 453 pGraphics->SaveGraphState(); 454 CFX_Color color1(&shading); 455 pGraphics->SetFillColor(&color1); 456 pGraphics->FillPath(path, fillMode, pMatrix); 457 pGraphics->RestoreGraphState(); 458 } 459 void CFWL_WidgetTP::DrawAnnulusRect(CFX_Graphics* pGraphics, 460 FX_ARGB fillColor, 461 const CFX_RectF* pRect, 462 FX_FLOAT fRingWidth, 463 CFX_Matrix* pMatrix) { 464 if (!pGraphics) 465 return; 466 if (!pRect) 467 return; 468 pGraphics->SaveGraphState(); 469 CFX_Color cr(fillColor); 470 pGraphics->SetFillColor(&cr); 471 CFX_Path path; 472 path.Create(); 473 CFX_RectF rtInner(*pRect); 474 rtInner.Deflate(fRingWidth, fRingWidth); 475 path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height); 476 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); 477 pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix); 478 pGraphics->RestoreGraphState(); 479 } 480 void CFWL_WidgetTP::DrawAnnulusCircle(CFX_Graphics* pGraphics, 481 FX_ARGB fillColor, 482 const CFX_RectF* pRect, 483 FX_FLOAT fWidth, 484 CFX_Matrix* pMatrix) { 485 if (!pGraphics) 486 return; 487 if (!pRect) 488 return; 489 if (fWidth > pRect->width / 2) { 490 return; 491 } 492 pGraphics->SaveGraphState(); 493 CFX_Color cr(fillColor); 494 pGraphics->SetFillColor(&cr); 495 CFX_Path path; 496 path.Create(); 497 path.AddEllipse(*pRect); 498 CFX_RectF rtIn(*pRect); 499 rtIn.Inflate(-fWidth, -fWidth); 500 path.AddEllipse(rtIn); 501 pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix); 502 pGraphics->RestoreGraphState(); 503 } 504 void CFWL_WidgetTP::DrawFocus(CFX_Graphics* pGraphics, 505 const CFX_RectF* pRect, 506 CFX_Matrix* pMatrix) { 507 if (!pGraphics) 508 return; 509 if (!pRect) 510 return; 511 pGraphics->SaveGraphState(); 512 CFX_Color cr(0xFF000000); 513 pGraphics->SetStrokeColor(&cr); 514 FX_FLOAT DashPattern[2] = {1, 1}; 515 pGraphics->SetLineDash(0.0f, DashPattern, 2); 516 CFX_Path path; 517 path.Create(); 518 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); 519 pGraphics->StrokePath(&path, pMatrix); 520 pGraphics->RestoreGraphState(); 521 } 522 #define FWLTHEME_ARROW_Denominator 3 523 void CFWL_WidgetTP::DrawArrow(CFX_Graphics* pGraphics, 524 const CFX_RectF* pRect, 525 FWLTHEME_DIRECTION eDict, 526 FX_ARGB argbFill, 527 FX_BOOL bPressed, 528 CFX_Matrix* pMatrix) { 529 CFX_RectF rtArrow(*pRect); 530 CFX_Path path; 531 path.Create(); 532 FX_FLOAT fBtn = 533 std::min(pRect->width, pRect->height) / FWLTHEME_ARROW_Denominator; 534 rtArrow.left = pRect->left + (pRect->width - fBtn) / 2; 535 rtArrow.top = pRect->top + (pRect->height - fBtn) / 2; 536 rtArrow.width = fBtn; 537 rtArrow.height = fBtn; 538 if (bPressed) { 539 rtArrow.Offset(1, 1); 540 } 541 switch (eDict) { 542 case FWLTHEME_DIRECTION_Up: { 543 path.MoveTo(rtArrow.left, rtArrow.bottom()); 544 path.LineTo(rtArrow.right(), rtArrow.bottom()); 545 path.LineTo(rtArrow.left + fBtn / 2, rtArrow.top); 546 path.LineTo(rtArrow.left, rtArrow.bottom()); 547 break; 548 } 549 case FWLTHEME_DIRECTION_Left: { 550 path.MoveTo(rtArrow.right(), rtArrow.top); 551 path.LineTo(rtArrow.right(), rtArrow.bottom()); 552 path.LineTo(rtArrow.left, rtArrow.top + fBtn / 2); 553 path.LineTo(rtArrow.right(), rtArrow.top); 554 break; 555 } 556 case FWLTHEME_DIRECTION_Right: { 557 path.MoveTo(rtArrow.left, rtArrow.top); 558 path.LineTo(rtArrow.left, rtArrow.bottom()); 559 path.LineTo(rtArrow.right(), rtArrow.top + fBtn / 2); 560 path.LineTo(rtArrow.left, rtArrow.top); 561 break; 562 } 563 case FWLTHEME_DIRECTION_Down: 564 default: { 565 path.MoveTo(rtArrow.left, rtArrow.top); 566 path.LineTo(rtArrow.right(), rtArrow.top); 567 path.LineTo(rtArrow.left + fBtn / 2, rtArrow.bottom()); 568 path.LineTo(rtArrow.left, rtArrow.top); 569 } 570 } 571 pGraphics->SaveGraphState(); 572 CFX_Color cr(argbFill); 573 pGraphics->SetFillColor(&cr); 574 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); 575 pGraphics->RestoreGraphState(); 576 } 577 void CFWL_WidgetTP::DrawArrow(CFX_Graphics* pGraphics, 578 const CFX_RectF* pRect, 579 FWLTHEME_DIRECTION eDict, 580 FX_ARGB argSign, 581 CFX_Matrix* pMatrix) { 582 FX_BOOL bVert = 583 (eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down); 584 FX_FLOAT fLeft = 585 (FX_FLOAT)(((pRect->width - (bVert ? 9 : 6)) / 2 + pRect->left) + 0.5); 586 FX_FLOAT fTop = 587 (FX_FLOAT)(((pRect->height - (bVert ? 6 : 9)) / 2 + pRect->top) + 0.5); 588 CFX_Path path; 589 path.Create(); 590 switch (eDict) { 591 case FWLTHEME_DIRECTION_Down: { 592 path.MoveTo(fLeft, fTop + 1); 593 path.LineTo(fLeft + 4, fTop + 5); 594 path.LineTo(fLeft + 8, fTop + 1); 595 path.LineTo(fLeft + 7, fTop); 596 path.LineTo(fLeft + 4, fTop + 3); 597 path.LineTo(fLeft + 1, fTop); 598 break; 599 } 600 case FWLTHEME_DIRECTION_Up: { 601 path.MoveTo(fLeft, fTop + 4); 602 path.LineTo(fLeft + 4, fTop); 603 path.LineTo(fLeft + 8, fTop + 4); 604 path.LineTo(fLeft + 7, fTop + 5); 605 path.LineTo(fLeft + 4, fTop + 2); 606 path.LineTo(fLeft + 1, fTop + 5); 607 break; 608 } 609 case FWLTHEME_DIRECTION_Right: { 610 path.MoveTo(fLeft + 1, fTop); 611 path.LineTo(fLeft + 5, fTop + 4); 612 path.LineTo(fLeft + 1, fTop + 8); 613 path.LineTo(fLeft, fTop + 7); 614 path.LineTo(fLeft + 3, fTop + 4); 615 path.LineTo(fLeft, fTop + 1); 616 break; 617 } 618 case FWLTHEME_DIRECTION_Left: { 619 path.MoveTo(fLeft, fTop + 4); 620 path.LineTo(fLeft + 4, fTop); 621 path.LineTo(fLeft + 5, fTop + 1); 622 path.LineTo(fLeft + 2, fTop + 4); 623 path.LineTo(fLeft + 5, fTop + 7); 624 path.LineTo(fLeft + 4, fTop + 8); 625 break; 626 } 627 } 628 CFX_Color cr(argSign); 629 pGraphics->SetFillColor(&cr); 630 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); 631 } 632 void CFWL_WidgetTP::DrawBtn(CFX_Graphics* pGraphics, 633 const CFX_RectF* pRect, 634 FWLTHEME_STATE eState, 635 CFX_Matrix* pMatrix) { 636 CFX_Path path; 637 path.Create(); 638 if (!CFWL_ArrowData::IsInstance()) { 639 CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(m_dwThemeID)); 640 } 641 CFWL_ArrowData::CColorData* pColorData = 642 CFWL_ArrowData::GetInstance()->m_pColorData; 643 FX_FLOAT fRight = pRect->right(); 644 FX_FLOAT fBottom = pRect->bottom(); 645 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); 646 DrawAxialShading(pGraphics, pRect->left, pRect->top, fRight, fBottom, 647 pColorData->clrStart[eState - 1], 648 pColorData->clrEnd[eState - 1], &path, FXFILL_WINDING, 649 pMatrix); 650 CFX_Color rcStroke; 651 rcStroke.Set(pColorData->clrBorder[eState - 1]); 652 pGraphics->SetStrokeColor(&rcStroke); 653 pGraphics->StrokePath(&path, pMatrix); 654 } 655 void CFWL_WidgetTP::DrawArrowBtn(CFX_Graphics* pGraphics, 656 const CFX_RectF* pRect, 657 FWLTHEME_DIRECTION eDict, 658 FWLTHEME_STATE eState, 659 CFX_Matrix* pMatrix) { 660 DrawBtn(pGraphics, pRect, eState, pMatrix); 661 if (!CFWL_ArrowData::IsInstance()) { 662 CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(m_dwThemeID)); 663 } 664 CFWL_ArrowData::CColorData* pColorData = 665 CFWL_ArrowData::GetInstance()->m_pColorData; 666 DrawArrow(pGraphics, pRect, eDict, pColorData->clrSign[eState - 1], pMatrix); 667 } 668 FWLCOLOR CFWL_WidgetTP::BlendColor(FWLCOLOR srcColor, 669 FWLCOLOR renderColor, 670 uint8_t scale) { 671 FWLCOLOR dstColor; 672 uint8_t n = 255 - scale; 673 dstColor.a = (uint8_t)( 674 ((FX_WORD)srcColor.a * n + (FX_WORD)renderColor.a * scale) >> 8); 675 dstColor.r = (uint8_t)( 676 ((FX_WORD)srcColor.r * n + (FX_WORD)renderColor.r * scale) >> 8); 677 dstColor.g = (uint8_t)( 678 ((FX_WORD)srcColor.g * n + (FX_WORD)renderColor.g * scale) >> 8); 679 dstColor.b = (uint8_t)( 680 ((FX_WORD)srcColor.b * n + (FX_WORD)renderColor.b * scale) >> 8); 681 return dstColor; 682 } 683 CFWL_ArrowData::CFWL_ArrowData() : m_pColorData(NULL) { 684 SetColorData(0); 685 } 686 CFWL_FontManager* FWL_GetFontManager() { 687 static CFWL_FontManager* _fontManager = NULL; 688 if (_fontManager == NULL) { 689 _fontManager = new CFWL_FontManager; 690 } 691 return _fontManager; 692 } 693 void FWL_ReleaseFontManager() { 694 CFWL_FontManager* fontManager = FWL_GetFontManager(); 695 delete fontManager; 696 } 697 CFWL_FontData::CFWL_FontData() 698 : m_dwStyles(0), 699 m_dwCodePage(0), 700 m_pFont(0), 701 m_pFontMgr(NULL) 702 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ 703 , 704 m_pFontSource(NULL) 705 #endif 706 { 707 } 708 CFWL_FontData::~CFWL_FontData() { 709 if (m_pFont) { 710 m_pFont->Release(); 711 } 712 if (m_pFontMgr) { 713 m_pFontMgr->Release(); 714 } 715 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ 716 if (m_pFontSource != NULL) { 717 m_pFontSource->Release(); 718 } 719 #endif 720 } 721 FX_BOOL CFWL_FontData::Equal(const CFX_WideStringC& wsFontFamily, 722 FX_DWORD dwFontStyles, 723 FX_WORD wCodePage) { 724 return m_wsFamily == wsFontFamily && m_dwStyles == dwFontStyles && 725 m_dwCodePage == wCodePage; 726 } 727 FX_BOOL CFWL_FontData::LoadFont(const CFX_WideStringC& wsFontFamily, 728 FX_DWORD dwFontStyles, 729 FX_WORD dwCodePage) { 730 m_wsFamily = wsFontFamily; 731 m_dwStyles = dwFontStyles; 732 m_dwCodePage = dwCodePage; 733 if (!m_pFontMgr) { 734 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 735 m_pFontMgr = IFX_FontMgr::Create(FX_GetDefFontEnumerator()); 736 #else 737 m_pFontSource = FX_CreateDefaultFontSourceEnum(); 738 m_pFontMgr = IFX_FontMgr::Create(m_pFontSource); 739 #endif 740 } 741 m_pFont = IFX_Font::LoadFont(wsFontFamily.GetPtr(), dwFontStyles, dwCodePage, 742 m_pFontMgr); 743 return m_pFont != NULL; 744 } 745 CFWL_FontManager::CFWL_FontManager() {} 746 CFWL_FontManager::~CFWL_FontManager() { 747 for (int32_t i = 0; i < m_arrFonts.GetSize(); i++) { 748 delete static_cast<CFWL_FontData*>(m_arrFonts[i]); 749 } 750 m_arrFonts.RemoveAll(); 751 } 752 IFX_Font* CFWL_FontManager::FindFont(const CFX_WideStringC& wsFontFamily, 753 FX_DWORD dwFontStyles, 754 FX_WORD wCodePage) { 755 for (int32_t i = 0; i < m_arrFonts.GetSize(); i++) { 756 CFWL_FontData* data = static_cast<CFWL_FontData*>(m_arrFonts[i]); 757 if (data->Equal(wsFontFamily, dwFontStyles, wCodePage)) { 758 return data->GetFont(); 759 } 760 } 761 CFWL_FontData* fontData = new CFWL_FontData; 762 if (!fontData->LoadFont(wsFontFamily, dwFontStyles, wCodePage)) { 763 delete fontData; 764 return NULL; 765 } 766 m_arrFonts.Add(fontData); 767 return fontData->GetFont(); 768 } 769 FX_BOOL FWLTHEME_Init() { 770 return TRUE; 771 } 772 void FWLTHEME_Release() { 773 CFWL_ArrowData::DestroyInstance(); 774 FWL_ReleaseFontManager(); 775 } 776 FX_DWORD FWL_GetThemeLayout(FX_DWORD dwThemeID) { 777 return 0xffff0000 & dwThemeID; 778 } 779 FX_DWORD FWL_GetThemeColor(FX_DWORD dwThemeID) { 780 return 0x0000ffff & dwThemeID; 781 } 782 FX_DWORD FWL_MakeThemeID(FX_DWORD dwLayout, FX_DWORD dwColor) { 783 return (dwLayout << 16) | (0x0000FFFF & dwColor); 784 } 785 CFWL_ArrowData* CFWL_ArrowData::m_pInstance = NULL; 786 CFWL_ArrowData* CFWL_ArrowData::GetInstance() { 787 if (!m_pInstance) { 788 m_pInstance = new CFWL_ArrowData; 789 } 790 return m_pInstance; 791 } 792 FX_BOOL CFWL_ArrowData::IsInstance() { 793 return (m_pInstance != NULL); 794 } 795 void CFWL_ArrowData::DestroyInstance() { 796 if (m_pInstance) { 797 delete m_pInstance; 798 m_pInstance = NULL; 799 } 800 } 801 CFWL_ArrowData::~CFWL_ArrowData() { 802 if (m_pColorData) { 803 delete m_pColorData; 804 m_pColorData = NULL; 805 } 806 } 807 void CFWL_ArrowData::SetColorData(FX_DWORD dwID) { 808 if (!m_pColorData) { 809 m_pColorData = new CColorData; 810 } 811 if (dwID) { 812 m_pColorData->clrBorder[0] = ArgbEncode(255, 142, 153, 125); 813 m_pColorData->clrBorder[1] = ArgbEncode(255, 157, 171, 119); 814 m_pColorData->clrBorder[2] = ArgbEncode(255, 118, 131, 97); 815 m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153); 816 m_pColorData->clrStart[0] = ArgbEncode(255, 203, 215, 186); 817 m_pColorData->clrStart[1] = ArgbEncode(255, 218, 232, 185); 818 m_pColorData->clrStart[2] = ArgbEncode(255, 203, 215, 186); 819 m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251); 820 m_pColorData->clrEnd[0] = ArgbEncode(255, 149, 167, 117); 821 m_pColorData->clrEnd[1] = ArgbEncode(255, 198, 211, 155); 822 m_pColorData->clrEnd[2] = ArgbEncode(255, 149, 167, 117); 823 m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236); 824 m_pColorData->clrSign[0] = ArgbEncode(255, 255, 255, 255); 825 m_pColorData->clrSign[1] = ArgbEncode(255, 255, 255, 255); 826 m_pColorData->clrSign[2] = ArgbEncode(255, 255, 255, 255); 827 m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128); 828 } else { 829 m_pColorData->clrBorder[0] = ArgbEncode(255, 202, 216, 249); 830 m_pColorData->clrBorder[1] = ArgbEncode(255, 171, 190, 233); 831 m_pColorData->clrBorder[2] = ArgbEncode(255, 135, 147, 219); 832 m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153); 833 m_pColorData->clrStart[0] = ArgbEncode(255, 225, 234, 254); 834 m_pColorData->clrStart[1] = ArgbEncode(255, 253, 255, 255); 835 m_pColorData->clrStart[2] = ArgbEncode(255, 110, 142, 241); 836 m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251); 837 m_pColorData->clrEnd[0] = ArgbEncode(255, 175, 204, 251); 838 m_pColorData->clrEnd[1] = ArgbEncode(255, 185, 218, 251); 839 m_pColorData->clrEnd[2] = ArgbEncode(255, 210, 222, 235); 840 m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236); 841 m_pColorData->clrSign[0] = ArgbEncode(255, 77, 97, 133); 842 m_pColorData->clrSign[1] = ArgbEncode(255, 77, 97, 133); 843 m_pColorData->clrSign[2] = ArgbEncode(255, 77, 97, 133); 844 m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128); 845 } 846 } 847