xfa_fwltheme.cpp revision 33357cad1fd1321a2b38d2963e2585f27ce980a2
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
29namespace {
30
31const FX_WCHAR* const g_FWLTheme_CalFonts[] = {
32    L"Arial", L"Courier New", L"DejaVu Sans",
33};
34
35const float kLineHeight = 12.0f;
36
37}  // namespace
38
39CXFA_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
46CXFA_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
76CXFA_FWLTheme::~CXFA_FWLTheme() {
77  m_pTextOut.reset();
78  FWLTHEME_Release();
79}
80
81void CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) {
82  GetTheme(pParams->m_pWidget)->DrawBackground(pParams);
83}
84
85void 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
150CFX_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
176float CXFA_FWLTheme::GetCXBorderSize() const {
177  return 1.0f;
178}
179
180float CXFA_FWLTheme::GetCYBorderSize() const {
181  return 1.0f;
182}
183
184float 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
190CFX_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
197float 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
203float CXFA_FWLTheme::GetScrollBarWidth() const {
204  return 9.0f;
205}
206
207FX_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
213CFX_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
225void 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
257CFWL_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