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"
XFA_ThemeGetOuterWidget(IFWL_Widget * pWidget)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 }
CXFA_FWLTheme(CXFA_FFApp * pApp)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 }
~CXFA_FWLTheme()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 };
Initialize()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 }
Finalize()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 }
IsValidWidget(IFWL_Widget * pWidget)91 FX_BOOL CXFA_FWLTheme::IsValidWidget(IFWL_Widget* pWidget) {
92 return TRUE;
93 }
GetThemeID(IFWL_Widget * pWidget)94 FX_DWORD CXFA_FWLTheme::GetThemeID(IFWL_Widget* pWidget) {
95 return 0;
96 }
SetThemeID(IFWL_Widget * pWidget,FX_DWORD dwThemeID,FX_BOOL bChildren)97 FX_DWORD CXFA_FWLTheme::SetThemeID(IFWL_Widget* pWidget,
98 FX_DWORD dwThemeID,
99 FX_BOOL bChildren) {
100 return 0;
101 }
DrawBackground(CFWL_ThemeBackground * pParams)102 FX_BOOL CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) {
103 return GetTheme(pParams->m_pWidget)->DrawBackground(pParams);
104 }
DrawText(CFWL_ThemeText * pParams)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 }
GetCapacity(CFWL_ThemePart * pThemePart,FX_DWORD dwCapacity)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 }
IsCustomizedLayout(IFWL_Widget * pWidget)261 FX_BOOL CXFA_FWLTheme::IsCustomizedLayout(IFWL_Widget* pWidget) {
262 return GetTheme(pWidget)->IsCustomizedLayout(pWidget);
263 }
GetPartRect(CFWL_ThemePart * pThemePart)264 FWL_ERR CXFA_FWLTheme::GetPartRect(CFWL_ThemePart* pThemePart) {
265 CFX_RectF rect;
266 return GetTheme(pThemePart->m_pWidget)->GetPartRect(pThemePart, rect);
267 }
IsInPart(CFWL_ThemePart * pThemePart,FX_FLOAT fx,FX_FLOAT fy)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 }
CalcTextRect(CFWL_ThemeText * pParams,CFX_RectF & rect)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 }
GetTheme(IFWL_Widget * pWidget)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 }
CXFA_FWLCheckBoxTP()339 CXFA_FWLCheckBoxTP::CXFA_FWLCheckBoxTP() {}
DrawBackground(CFWL_ThemeBackground * pParams)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 }
DrawCheckSign(IFWL_Widget * pWidget,CFX_Graphics * pGraphics,const CFX_RectF * pRtBox,int32_t iState,CFX_Matrix * pMatrix)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 }
CXFA_FWLEditTP()390 CXFA_FWLEditTP::CXFA_FWLEditTP() {}
~CXFA_FWLEditTP()391 CXFA_FWLEditTP::~CXFA_FWLEditTP() {}
DrawBackground(CFWL_ThemeBackground * pParams)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