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