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 #include "xfa/src/fxfa/src/common/xfa_common.h" 9 #include "xfa_fwltheme.h" 10 #include "xfa_ffwidget.h" 11 #include "xfa_ffapp.h" 12 CXFA_FFWidget* XFA_ThemeGetOuterWidget(IFWL_Widget* pWidget) { 13 IFWL_Widget* pOuter = pWidget; 14 while (pOuter->GetOuter()) { 15 pOuter = pOuter->GetOuter(); 16 } 17 if (pOuter) { 18 return (CXFA_FFWidget*)pOuter->GetPrivateData(pOuter); 19 } 20 return NULL; 21 } 22 CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp) : m_pApp(pApp) { 23 m_pTextOut = NULL; 24 m_dwCapacity = 0; 25 m_fCapacity = 0; 26 m_pCalendarFont = NULL; 27 m_Rect.Set(0, 0, 0, 0); 28 m_SizeAboveBelow.Set(0, 0); 29 m_pCheckBoxTP = new CXFA_FWLCheckBoxTP; 30 m_pListBoxTP = new CFWL_ListBoxTP; 31 m_pPictureBoxTP = new CFWL_PictureBoxTP; 32 m_pSrollBarTP = new CFWL_ScrollBarTP; 33 m_pEditTP = new CXFA_FWLEditTP; 34 m_pComboBoxTP = new CFWL_ComboBoxTP; 35 m_pMonthCalendarTP = new CFWL_MonthCalendarTP; 36 m_pDateTimePickerTP = new CFWL_DateTimePickerTP; 37 m_pPushButtonTP = new CFWL_PushButtonTP; 38 m_pCaretTP = new CFWL_CaretTP; 39 m_pBarcodeTP = new CFWL_BarcodeTP; 40 Initialize(); 41 } 42 CXFA_FWLTheme::~CXFA_FWLTheme() { 43 Finalize(); 44 delete m_pCheckBoxTP; 45 delete m_pListBoxTP; 46 delete m_pPictureBoxTP; 47 delete m_pSrollBarTP; 48 delete m_pEditTP; 49 delete m_pComboBoxTP; 50 delete m_pMonthCalendarTP; 51 delete m_pDateTimePickerTP; 52 delete m_pPushButtonTP; 53 delete m_pCaretTP; 54 delete m_pBarcodeTP; 55 } 56 static const FX_WCHAR* g_FWLTheme_CalFonts[] = { 57 L"Arial", L"Courier New", L"DejaVu Sans", 58 }; 59 FWL_ERR CXFA_FWLTheme::Initialize() { 60 m_pTextOut = IFDE_TextOut::Create(); 61 for (int32_t i = 0; NULL == m_pCalendarFont && 62 i < sizeof(g_FWLTheme_CalFonts) / sizeof(const FX_WCHAR*); 63 i++) { 64 m_pCalendarFont = IFX_Font::LoadFont(g_FWLTheme_CalFonts[i], 0, 0, 65 m_pApp->GetFDEFontMgr()); 66 } 67 if (NULL == m_pCalendarFont) 68 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 69 m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetDefFontByCodePage( 70 FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL); 71 #else 72 m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage( 73 FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL); 74 #endif 75 FXSYS_assert(NULL != m_pCalendarFont); 76 FWLTHEME_Init(); 77 return FWL_ERR_Succeeded; 78 } 79 FWL_ERR CXFA_FWLTheme::Finalize() { 80 if (m_pTextOut) { 81 m_pTextOut->Release(); 82 m_pTextOut = NULL; 83 } 84 if (m_pCalendarFont) { 85 m_pCalendarFont->Release(); 86 m_pCalendarFont = NULL; 87 } 88 FWLTHEME_Release(); 89 return FWL_ERR_Succeeded; 90 } 91 FX_BOOL CXFA_FWLTheme::IsValidWidget(IFWL_Widget* pWidget) { 92 return TRUE; 93 } 94 FX_DWORD CXFA_FWLTheme::GetThemeID(IFWL_Widget* pWidget) { 95 return 0; 96 } 97 FX_DWORD CXFA_FWLTheme::SetThemeID(IFWL_Widget* pWidget, 98 FX_DWORD dwThemeID, 99 FX_BOOL bChildren) { 100 return 0; 101 } 102 FX_BOOL CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) { 103 return GetTheme(pParams->m_pWidget)->DrawBackground(pParams); 104 } 105 FX_BOOL CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) { 106 if (pParams->m_wsText.IsEmpty()) { 107 return FWL_ERR_Indefinite; 108 } 109 if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) { 110 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 111 if (!pWidget) { 112 return FWL_ERR_Indefinite; 113 } 114 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 115 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 116 m_pTextOut->SetFont(m_pCalendarFont); 117 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize); 118 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor); 119 if ((pParams->m_iPart == FWL_PART_MCD_DatesIn) && 120 !(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) && 121 (pParams->m_dwStates & 122 (FWL_PARTSTATE_MCD_Hovered | FWL_PARTSTATE_MCD_Selected))) { 123 m_pTextOut->SetTextColor(0xFFFFFFFF); 124 } 125 if (pParams->m_iPart == FWL_PART_MCD_Caption) { 126 if (m_pMonthCalendarTP->GetThemeID(pParams->m_pWidget) == 0) { 127 m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255)); 128 } else { 129 m_pTextOut->SetTextColor(ArgbEncode(0xff, 128, 128, 0)); 130 } 131 } 132 CFX_Graphics* pGraphics = pParams->m_pGraphics; 133 CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice(); 134 if (!pRenderDevice) 135 return FALSE; 136 m_pTextOut->SetRenderDevice(pRenderDevice); 137 CFX_Matrix mtPart = pParams->m_matrix; 138 CFX_Matrix* pMatrix = pGraphics->GetMatrix(); 139 if (pMatrix) { 140 mtPart.Concat(*pMatrix); 141 } 142 m_pTextOut->SetMatrix(mtPart); 143 m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(), 144 pParams->m_rtPart); 145 return TRUE; 146 } 147 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 148 if (!pWidget) { 149 return FWL_ERR_Indefinite; 150 } 151 CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc(); 152 CFX_Graphics* pGraphics = pParams->m_pGraphics; 153 CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice(); 154 if (!pRenderDevice) 155 return FALSE; 156 m_pTextOut->SetRenderDevice(pRenderDevice); 157 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 158 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 159 m_pTextOut->SetFont(pAcc->GetFDEFont()); 160 m_pTextOut->SetFontSize(pAcc->GetFontSize()); 161 m_pTextOut->SetTextColor(pAcc->GetTextColor()); 162 CFX_Matrix mtPart = pParams->m_matrix; 163 CFX_Matrix* pMatrix = pGraphics->GetMatrix(); 164 if (pMatrix) { 165 mtPart.Concat(*pMatrix); 166 } 167 m_pTextOut->SetMatrix(mtPart); 168 m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(), 169 pParams->m_rtPart); 170 return TRUE; 171 } 172 void* CXFA_FWLTheme::GetCapacity(CFWL_ThemePart* pThemePart, 173 FX_DWORD dwCapacity) { 174 switch (dwCapacity) { 175 case FWL_WGTCAPACITY_Font: { 176 if (CXFA_FFWidget* pWidget = 177 XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { 178 return pWidget->GetDataAcc()->GetFDEFont(); 179 } 180 } break; 181 case FWL_WGTCAPACITY_FontSize: { 182 if (CXFA_FFWidget* pWidget = 183 XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { 184 m_fCapacity = pWidget->GetDataAcc()->GetFontSize(); 185 return &m_fCapacity; 186 } 187 } break; 188 case FWL_WGTCAPACITY_TextColor: { 189 if (CXFA_FFWidget* pWidget = 190 XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { 191 m_dwCapacity = pWidget->GetDataAcc()->GetTextColor(); 192 return &m_dwCapacity; 193 } 194 } break; 195 case FWL_WGTCAPACITY_LineHeight: { 196 if (CXFA_FFWidget* pWidget = 197 XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { 198 m_fCapacity = pWidget->GetDataAcc()->GetLineHeight(); 199 return &m_fCapacity; 200 } 201 } break; 202 case FWL_WGTCAPACITY_ScrollBarWidth: { 203 m_fCapacity = 9; 204 return &m_fCapacity; 205 } break; 206 case FWL_WGTCAPACITY_UIMargin: { 207 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget); 208 if (pWidget) { 209 CXFA_LayoutItem* pItem = pWidget; 210 CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc(); 211 pWidgetAcc->GetUIMargin(m_Rect); 212 if (CXFA_Para para = pWidgetAcc->GetPara()) { 213 m_Rect.left += para.GetMarginLeft(); 214 if (pWidgetAcc->IsMultiLine()) { 215 m_Rect.width += para.GetMarginRight(); 216 } 217 } 218 if (pItem->GetPrev() == NULL) { 219 if (pItem->GetNext() != NULL) { 220 m_Rect.height = 0; 221 } 222 } else if (pItem->GetNext() == NULL) { 223 m_Rect.top = 0; 224 } else { 225 m_Rect.top = 0; 226 m_Rect.height = 0; 227 } 228 } 229 return &m_Rect; 230 } break; 231 case FWL_WGTCAPACITY_SpaceAboveBelow: { 232 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget); 233 if (pWidget) { 234 CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc(); 235 if (CXFA_Para para = pWidgetAcc->GetPara()) { 236 m_SizeAboveBelow.x = para.GetSpaceAbove(); 237 m_SizeAboveBelow.y = para.GetSpaceBelow(); 238 } 239 } 240 return &m_SizeAboveBelow; 241 } break; 242 default: 243 break; 244 } 245 if (pThemePart->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar && 246 dwCapacity >= FWL_MCCAPACITY_Sun && dwCapacity <= FWL_MCCAPACITY_Today) { 247 if (CXFA_FFWidget* pWidget = 248 XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { 249 IXFA_AppProvider* pAppProvider = pWidget->GetAppProvider(); 250 m_wsResource.Empty(); 251 pAppProvider->LoadString( 252 XFA_IDS_StringWeekDay_Sun + dwCapacity - FWL_WGTCAPACITY_MAX - 5, 253 m_wsResource); 254 if (!m_wsResource.IsEmpty()) { 255 return &m_wsResource; 256 } 257 } 258 } 259 return GetTheme(pThemePart->m_pWidget)->GetCapacity(pThemePart, dwCapacity); 260 } 261 FX_BOOL CXFA_FWLTheme::IsCustomizedLayout(IFWL_Widget* pWidget) { 262 return GetTheme(pWidget)->IsCustomizedLayout(pWidget); 263 } 264 FWL_ERR CXFA_FWLTheme::GetPartRect(CFWL_ThemePart* pThemePart) { 265 CFX_RectF rect; 266 return GetTheme(pThemePart->m_pWidget)->GetPartRect(pThemePart, rect); 267 } 268 FX_BOOL CXFA_FWLTheme::IsInPart(CFWL_ThemePart* pThemePart, 269 FX_FLOAT fx, 270 FX_FLOAT fy) { 271 return GetTheme(pThemePart->m_pWidget)->IsInPart(pThemePart, fx, fy); 272 } 273 FX_BOOL CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) { 274 if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) { 275 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 276 if (!pWidget) { 277 return FWL_ERR_Indefinite; 278 } 279 if (!pParams) 280 return FALSE; 281 if (!m_pTextOut) 282 return FALSE; 283 m_pTextOut->SetFont(m_pCalendarFont); 284 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize); 285 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor); 286 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 287 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 288 m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(), 289 rect); 290 return TRUE; 291 } 292 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 293 if (!pWidget) { 294 return FWL_ERR_Indefinite; 295 } 296 CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc(); 297 m_pTextOut->SetFont(pAcc->GetFDEFont()); 298 m_pTextOut->SetFontSize(pAcc->GetFontSize()); 299 m_pTextOut->SetTextColor(pAcc->GetTextColor()); 300 if (!pParams) 301 return FALSE; 302 if (!m_pTextOut) 303 return FALSE; 304 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 305 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 306 m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(), 307 rect); 308 return TRUE; 309 } 310 CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(IFWL_Widget* pWidget) { 311 switch (pWidget->GetClassID()) { 312 case FWL_CLASSHASH_CheckBox: 313 return m_pCheckBoxTP; 314 case FWL_CLASSHASH_ListBox: 315 return m_pListBoxTP; 316 case FWL_CLASSHASH_PictureBox: 317 return m_pPictureBoxTP; 318 case FWL_CLASSHASH_ScrollBar: 319 return m_pSrollBarTP; 320 case FWL_CLASSHASH_Edit: 321 return m_pEditTP; 322 case FWL_CLASSHASH_ComboBox: 323 return m_pComboBoxTP; 324 case FWL_CLASSHASH_MonthCalendar: 325 return m_pMonthCalendarTP; 326 case FWL_CLASSHASH_DateTimePicker: 327 return m_pDateTimePickerTP; 328 case FWL_CLASSHASH_PushButton: 329 return m_pPushButtonTP; 330 case FWL_CLASSHASH_Caret: 331 return m_pCaretTP; 332 case FWL_CLASSHASH_Barcode: 333 return m_pBarcodeTP; 334 default: 335 break; 336 } 337 return NULL; 338 } 339 CXFA_FWLCheckBoxTP::CXFA_FWLCheckBoxTP() {} 340 FX_BOOL CXFA_FWLCheckBoxTP::DrawBackground(CFWL_ThemeBackground* pParams) { 341 if (pParams->m_iPart != FWL_PART_CKB_CheckBox) { 342 return TRUE; 343 } 344 if (((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) == 345 FWL_PARTSTATE_CKB_Checked) || 346 ((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) == 347 FWL_PARTSTATE_CKB_Neutral)) { 348 DrawCheckSign(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart, 349 pParams->m_dwStates, &pParams->m_matrix); 350 } 351 return TRUE; 352 } 353 void CXFA_FWLCheckBoxTP::DrawCheckSign(IFWL_Widget* pWidget, 354 CFX_Graphics* pGraphics, 355 const CFX_RectF* pRtBox, 356 int32_t iState, 357 CFX_Matrix* pMatrix) { 358 CFX_RectF rtSign(*pRtBox); 359 FX_DWORD dwColor = 0xFF000000; 360 if ((iState & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral) { 361 dwColor = 0xFFA9A9A9; 362 } 363 { 364 FX_DWORD dwStyle = pWidget->GetStylesEx(); 365 rtSign.Deflate(rtSign.width / 4, rtSign.height / 4); 366 switch (dwStyle & FWL_STYLEEXT_CKB_SignShapeMask) { 367 case FWL_STYLEEXT_CKB_SignShapeCheck: 368 DrawSignCheck(pGraphics, &rtSign, dwColor, pMatrix); 369 break; 370 case FWL_STYLEEXT_CKB_SignShapeCircle: 371 DrawSignCircle(pGraphics, &rtSign, dwColor, pMatrix); 372 break; 373 case FWL_STYLEEXT_CKB_SignShapeCross: 374 DrawSignCross(pGraphics, &rtSign, dwColor, pMatrix); 375 break; 376 case FWL_STYLEEXT_CKB_SignShapeDiamond: 377 DrawSignDiamond(pGraphics, &rtSign, dwColor, pMatrix); 378 break; 379 case FWL_STYLEEXT_CKB_SignShapeSquare: 380 DrawSignSquare(pGraphics, &rtSign, dwColor, pMatrix); 381 break; 382 case FWL_STYLEEXT_CKB_SignShapeStar: 383 DrawSignStar(pGraphics, &rtSign, dwColor, pMatrix); 384 break; 385 default: 386 break; 387 } 388 } 389 } 390 CXFA_FWLEditTP::CXFA_FWLEditTP() {} 391 CXFA_FWLEditTP::~CXFA_FWLEditTP() {} 392 FX_BOOL CXFA_FWLEditTP::DrawBackground(CFWL_ThemeBackground* pParams) { 393 if (FWL_PART_EDT_CombTextLine == pParams->m_iPart) { 394 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 395 FX_ARGB cr = 0xFF000000; 396 FX_FLOAT fWidth = 1.0f; 397 if (CXFA_Border borderUI = pWidget->GetDataAcc()->GetUIBorder()) { 398 CXFA_Edge edge = borderUI.GetEdge(0); 399 if (edge) { 400 cr = edge.GetColor(); 401 fWidth = edge.GetThickness(); 402 } 403 } 404 CFX_Color crLine(cr); 405 pParams->m_pGraphics->SetStrokeColor(&crLine); 406 pParams->m_pGraphics->SetLineWidth(fWidth); 407 pParams->m_pGraphics->StrokePath(pParams->m_pPath, &pParams->m_matrix); 408 return TRUE; 409 } 410 return CFWL_EditTP::DrawBackground(pParams); 411 } 412