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/fxfa/app/xfa_fwltheme.h"
8
9 #include "xfa/fde/tto/fde_textout.h"
10 #include "xfa/fgas/crt/fgas_codepage.h"
11 #include "xfa/fgas/font/cfgas_gefont.h"
12 #include "xfa/fwl/cfwl_barcode.h"
13 #include "xfa/fwl/cfwl_caret.h"
14 #include "xfa/fwl/cfwl_checkbox.h"
15 #include "xfa/fwl/cfwl_combobox.h"
16 #include "xfa/fwl/cfwl_datetimepicker.h"
17 #include "xfa/fwl/cfwl_edit.h"
18 #include "xfa/fwl/cfwl_listbox.h"
19 #include "xfa/fwl/cfwl_monthcalendar.h"
20 #include "xfa/fwl/cfwl_picturebox.h"
21 #include "xfa/fwl/cfwl_pushbutton.h"
22 #include "xfa/fwl/cfwl_scrollbar.h"
23 #include "xfa/fwl/cfwl_themebackground.h"
24 #include "xfa/fwl/cfwl_themetext.h"
25 #include "xfa/fxfa/xfa_ffapp.h"
26 #include "xfa/fxfa/xfa_ffwidget.h"
27 #include "xfa/fxgraphics/cfx_color.h"
28
29 namespace {
30
31 const FX_WCHAR* const g_FWLTheme_CalFonts[] = {
32 L"Arial", L"Courier New", L"DejaVu Sans",
33 };
34
35 const float kLineHeight = 12.0f;
36
37 } // namespace
38
XFA_ThemeGetOuterWidget(CFWL_Widget * pWidget)39 CXFA_FFWidget* XFA_ThemeGetOuterWidget(CFWL_Widget* pWidget) {
40 CFWL_Widget* pOuter = pWidget;
41 while (pOuter && pOuter->GetOuter())
42 pOuter = pOuter->GetOuter();
43 return pOuter ? pOuter->GetLayoutItem() : nullptr;
44 }
45
CXFA_FWLTheme(CXFA_FFApp * pApp)46 CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp)
47 : m_pCheckBoxTP(new CFWL_CheckBoxTP),
48 m_pListBoxTP(new CFWL_ListBoxTP),
49 m_pPictureBoxTP(new CFWL_PictureBoxTP),
50 m_pSrollBarTP(new CFWL_ScrollBarTP),
51 m_pEditTP(new CFWL_EditTP),
52 m_pComboBoxTP(new CFWL_ComboBoxTP),
53 m_pMonthCalendarTP(new CFWL_MonthCalendarTP),
54 m_pDateTimePickerTP(new CFWL_DateTimePickerTP),
55 m_pPushButtonTP(new CFWL_PushButtonTP),
56 m_pCaretTP(new CFWL_CaretTP),
57 m_pBarcodeTP(new CFWL_BarcodeTP),
58 m_pTextOut(new CFDE_TextOut),
59 m_pCalendarFont(nullptr),
60 m_pApp(pApp) {
61 m_Rect.Reset();
62
63 for (size_t i = 0; !m_pCalendarFont && i < FX_ArraySize(g_FWLTheme_CalFonts);
64 ++i) {
65 m_pCalendarFont = CFGAS_GEFont::LoadFont(g_FWLTheme_CalFonts[i], 0, 0,
66 m_pApp->GetFDEFontMgr());
67 }
68 if (!m_pCalendarFont) {
69 m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage(
70 FX_CODEPAGE_MSWin_WesternEuropean, 0, nullptr);
71 }
72
73 ASSERT(m_pCalendarFont);
74 }
75
~CXFA_FWLTheme()76 CXFA_FWLTheme::~CXFA_FWLTheme() {
77 m_pTextOut.reset();
78 FWLTHEME_Release();
79 }
80
DrawBackground(CFWL_ThemeBackground * pParams)81 void CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) {
82 GetTheme(pParams->m_pWidget)->DrawBackground(pParams);
83 }
84
DrawText(CFWL_ThemeText * pParams)85 void CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) {
86 if (pParams->m_wsText.IsEmpty())
87 return;
88
89 if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) {
90 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
91 if (!pWidget)
92 return;
93
94 m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
95 m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
96 m_pTextOut->SetFont(m_pCalendarFont);
97 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
98 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
99 if ((pParams->m_iPart == CFWL_Part::DatesIn) &&
100 !(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) &&
101 (pParams->m_dwStates &
102 (CFWL_PartState_Hovered | CFWL_PartState_Selected))) {
103 m_pTextOut->SetTextColor(0xFFFFFFFF);
104 }
105 if (pParams->m_iPart == CFWL_Part::Caption)
106 m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255));
107
108 CFX_Graphics* pGraphics = pParams->m_pGraphics;
109 CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
110 if (!pRenderDevice)
111 return;
112
113 m_pTextOut->SetRenderDevice(pRenderDevice);
114 CFX_Matrix mtPart = pParams->m_matrix;
115 CFX_Matrix* pMatrix = pGraphics->GetMatrix();
116 if (pMatrix) {
117 mtPart.Concat(*pMatrix);
118 }
119 m_pTextOut->SetMatrix(mtPart);
120 m_pTextOut->DrawLogicText(pParams->m_wsText.c_str(),
121 pParams->m_wsText.GetLength(), pParams->m_rtPart);
122 return;
123 }
124 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
125 if (!pWidget)
126 return;
127
128 CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
129 CFX_Graphics* pGraphics = pParams->m_pGraphics;
130 CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
131 if (!pRenderDevice)
132 return;
133
134 m_pTextOut->SetRenderDevice(pRenderDevice);
135 m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
136 m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
137 m_pTextOut->SetFont(pAcc->GetFDEFont());
138 m_pTextOut->SetFontSize(pAcc->GetFontSize());
139 m_pTextOut->SetTextColor(pAcc->GetTextColor());
140 CFX_Matrix mtPart = pParams->m_matrix;
141 CFX_Matrix* pMatrix = pGraphics->GetMatrix();
142 if (pMatrix)
143 mtPart.Concat(*pMatrix);
144
145 m_pTextOut->SetMatrix(mtPart);
146 m_pTextOut->DrawLogicText(pParams->m_wsText.c_str(),
147 pParams->m_wsText.GetLength(), pParams->m_rtPart);
148 }
149
GetUIMargin(CFWL_ThemePart * pThemePart) const150 CFX_RectF CXFA_FWLTheme::GetUIMargin(CFWL_ThemePart* pThemePart) const {
151 CFX_RectF rect;
152 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget);
153 if (!pWidget)
154 return rect;
155
156 CXFA_LayoutItem* pItem = pWidget;
157 CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
158 rect = pWidgetAcc->GetUIMargin();
159 if (CXFA_Para para = pWidgetAcc->GetPara()) {
160 rect.left += para.GetMarginLeft();
161 if (pWidgetAcc->IsMultiLine())
162 rect.width += para.GetMarginRight();
163 }
164 if (!pItem->GetPrev()) {
165 if (pItem->GetNext())
166 rect.height = 0;
167 } else if (!pItem->GetNext()) {
168 rect.top = 0;
169 } else {
170 rect.top = 0;
171 rect.height = 0;
172 }
173 return rect;
174 }
175
GetCXBorderSize() const176 float CXFA_FWLTheme::GetCXBorderSize() const {
177 return 1.0f;
178 }
179
GetCYBorderSize() const180 float CXFA_FWLTheme::GetCYBorderSize() const {
181 return 1.0f;
182 }
183
GetFontSize(CFWL_ThemePart * pThemePart) const184 float CXFA_FWLTheme::GetFontSize(CFWL_ThemePart* pThemePart) const {
185 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
186 return pWidget->GetDataAcc()->GetFontSize();
187 return FWLTHEME_CAPACITY_FontSize;
188 }
189
GetFont(CFWL_ThemePart * pThemePart) const190 CFX_RetainPtr<CFGAS_GEFont> CXFA_FWLTheme::GetFont(
191 CFWL_ThemePart* pThemePart) const {
192 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
193 return pWidget->GetDataAcc()->GetFDEFont();
194 return GetTheme(pThemePart->m_pWidget)->GetFont();
195 }
196
GetLineHeight(CFWL_ThemePart * pThemePart) const197 float CXFA_FWLTheme::GetLineHeight(CFWL_ThemePart* pThemePart) const {
198 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
199 return pWidget->GetDataAcc()->GetLineHeight();
200 return kLineHeight;
201 }
202
GetScrollBarWidth() const203 float CXFA_FWLTheme::GetScrollBarWidth() const {
204 return 9.0f;
205 }
206
GetTextColor(CFWL_ThemePart * pThemePart) const207 FX_COLORREF CXFA_FWLTheme::GetTextColor(CFWL_ThemePart* pThemePart) const {
208 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
209 return pWidget->GetDataAcc()->GetTextColor();
210 return FWLTHEME_CAPACITY_TextColor;
211 }
212
GetSpaceAboveBelow(CFWL_ThemePart * pThemePart) const213 CFX_SizeF CXFA_FWLTheme::GetSpaceAboveBelow(CFWL_ThemePart* pThemePart) const {
214 CFX_SizeF sizeAboveBelow;
215 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
216 CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
217 if (CXFA_Para para = pWidgetAcc->GetPara()) {
218 sizeAboveBelow.width = para.GetSpaceAbove();
219 sizeAboveBelow.height = para.GetSpaceBelow();
220 }
221 }
222 return sizeAboveBelow;
223 }
224
CalcTextRect(CFWL_ThemeText * pParams,CFX_RectF & rect)225 void CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) {
226 if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) {
227 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
228 if (!pWidget || !pParams || !m_pTextOut)
229 return;
230
231 m_pTextOut->SetFont(m_pCalendarFont);
232 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
233 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
234 m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
235 m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
236 m_pTextOut->CalcLogicSize(pParams->m_wsText.c_str(),
237 pParams->m_wsText.GetLength(), rect);
238 }
239
240 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
241 if (!pWidget)
242 return;
243
244 CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
245 m_pTextOut->SetFont(pAcc->GetFDEFont());
246 m_pTextOut->SetFontSize(pAcc->GetFontSize());
247 m_pTextOut->SetTextColor(pAcc->GetTextColor());
248 if (!pParams)
249 return;
250
251 m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
252 m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
253 m_pTextOut->CalcLogicSize(pParams->m_wsText.c_str(),
254 pParams->m_wsText.GetLength(), rect);
255 }
256
GetTheme(CFWL_Widget * pWidget) const257 CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(CFWL_Widget* pWidget) const {
258 switch (pWidget->GetClassID()) {
259 case FWL_Type::CheckBox:
260 return m_pCheckBoxTP.get();
261 case FWL_Type::ListBox:
262 return m_pListBoxTP.get();
263 case FWL_Type::PictureBox:
264 return m_pPictureBoxTP.get();
265 case FWL_Type::ScrollBar:
266 return m_pSrollBarTP.get();
267 case FWL_Type::Edit:
268 return m_pEditTP.get();
269 case FWL_Type::ComboBox:
270 return m_pComboBoxTP.get();
271 case FWL_Type::MonthCalendar:
272 return m_pMonthCalendarTP.get();
273 case FWL_Type::DateTimePicker:
274 return m_pDateTimePickerTP.get();
275 case FWL_Type::PushButton:
276 return m_pPushButtonTP.get();
277 case FWL_Type::Caret:
278 return m_pCaretTP.get();
279 case FWL_Type::Barcode:
280 return m_pBarcodeTP.get();
281 default:
282 return nullptr;
283 }
284 }
285