xref: /aosp_15_r20/external/pdfium/xfa/fxfa/cxfa_fwltheme.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2014 The PDFium Authors
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/cxfa_fwltheme.h"
8 
9 #include "core/fxcrt/fx_codepage.h"
10 #include "xfa/fde/cfde_textout.h"
11 #include "xfa/fgas/font/cfgas_fontmgr.h"
12 #include "xfa/fgas/font/cfgas_gefont.h"
13 #include "xfa/fgas/font/cfgas_gemodule.h"
14 #include "xfa/fgas/graphics/cfgas_gecolor.h"
15 #include "xfa/fwl/cfwl_barcode.h"
16 #include "xfa/fwl/cfwl_caret.h"
17 #include "xfa/fwl/cfwl_checkbox.h"
18 #include "xfa/fwl/cfwl_combobox.h"
19 #include "xfa/fwl/cfwl_datetimepicker.h"
20 #include "xfa/fwl/cfwl_edit.h"
21 #include "xfa/fwl/cfwl_listbox.h"
22 #include "xfa/fwl/cfwl_monthcalendar.h"
23 #include "xfa/fwl/cfwl_picturebox.h"
24 #include "xfa/fwl/cfwl_pushbutton.h"
25 #include "xfa/fwl/cfwl_scrollbar.h"
26 #include "xfa/fwl/cfwl_themebackground.h"
27 #include "xfa/fwl/cfwl_themetext.h"
28 #include "xfa/fwl/theme/cfwl_widgettp.h"
29 #include "xfa/fxfa/cxfa_ffapp.h"
30 #include "xfa/fxfa/cxfa_ffwidget.h"
31 #include "xfa/fxfa/cxfa_fontmgr.h"
32 #include "xfa/fxfa/parser/cxfa_para.h"
33 
34 namespace {
35 
36 constexpr const wchar_t* kFWLThemeCalFonts[] = {
37     L"Arial",
38     L"Courier New",
39     L"DejaVu Sans",
40 };
41 
42 const float kLineHeight = 12.0f;
43 
GetOutmostFFWidget(CFWL_Widget * pWidget)44 CXFA_FFWidget* GetOutmostFFWidget(CFWL_Widget* pWidget) {
45   CFWL_Widget* pOuter = pWidget ? pWidget->GetOutmost() : nullptr;
46   return pOuter ? static_cast<CXFA_FFWidget*>(pOuter->GetAdapterIface())
47                 : nullptr;
48 }
49 
50 }  // namespace
51 
CXFA_FWLTheme(cppgc::Heap * pHeap,CXFA_FFApp * pApp)52 CXFA_FWLTheme::CXFA_FWLTheme(cppgc::Heap* pHeap, CXFA_FFApp* pApp)
53     : IFWL_ThemeProvider(pHeap),
54       m_pTextOut(std::make_unique<CFDE_TextOut>()),
55       m_pApp(pApp) {}
56 
57 CXFA_FWLTheme::~CXFA_FWLTheme() = default;
58 
PreFinalize()59 void CXFA_FWLTheme::PreFinalize() {
60   m_pTextOut.reset();
61 }
62 
Trace(cppgc::Visitor * visitor) const63 void CXFA_FWLTheme::Trace(cppgc::Visitor* visitor) const {
64   IFWL_ThemeProvider::Trace(visitor);
65   visitor->Trace(m_pApp);
66 }
67 
LoadCalendarFont(CXFA_FFDoc * doc)68 bool CXFA_FWLTheme::LoadCalendarFont(CXFA_FFDoc* doc) {
69   if (m_pCalendarFont)
70     return true;
71 
72   for (const wchar_t* font : kFWLThemeCalFonts) {
73     m_pCalendarFont = m_pApp->GetXFAFontMgr()->GetFont(doc, font, 0);
74     if (m_pCalendarFont)
75       return true;
76   }
77 
78   m_pCalendarFont = CFGAS_GEModule::Get()->GetFontMgr()->GetFontByCodePage(
79       FX_CodePage::kMSWin_WesternEuropean, 0, nullptr);
80   return !!m_pCalendarFont;
81 }
82 
DrawBackground(const CFWL_ThemeBackground & pParams)83 void CXFA_FWLTheme::DrawBackground(const CFWL_ThemeBackground& pParams) {
84   GetTheme(pParams.GetWidget())->DrawBackground(pParams);
85 }
86 
DrawText(const CFWL_ThemeText & pParams)87 void CXFA_FWLTheme::DrawText(const CFWL_ThemeText& pParams) {
88   if (pParams.m_wsText.IsEmpty())
89     return;
90 
91   if (pParams.GetWidget()->GetClassID() == FWL_Type::MonthCalendar) {
92     CXFA_FFWidget* pWidget = GetOutmostFFWidget(pParams.GetWidget());
93     if (!pWidget)
94       return;
95 
96     m_pTextOut->SetStyles(pParams.m_dwTTOStyles);
97     m_pTextOut->SetAlignment(pParams.m_iTTOAlign);
98     m_pTextOut->SetFont(m_pCalendarFont);
99     m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
100     m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
101     if ((pParams.GetPart() == CFWL_ThemePart::Part::kDatesIn) &&
102         !(pParams.m_dwStates & CFWL_PartState::kFlagged) &&
103         (pParams.m_dwStates &
104          Mask<CFWL_PartState>{CFWL_PartState::kHovered,
105                               CFWL_PartState::kSelected})) {
106       m_pTextOut->SetTextColor(0xFF888888);
107     }
108     if (pParams.GetPart() == CFWL_ThemePart::Part::kCaption)
109       m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255));
110 
111     CFGAS_GEGraphics* pGraphics = pParams.GetGraphics();
112     CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
113     CFX_Matrix mtPart = pParams.m_matrix;
114     const CFX_Matrix* pMatrix = pGraphics->GetMatrix();
115     if (pMatrix)
116       mtPart.Concat(*pMatrix);
117 
118     m_pTextOut->SetMatrix(mtPart);
119     m_pTextOut->DrawLogicText(pRenderDevice, pParams.m_wsText,
120                               pParams.m_PartRect);
121     return;
122   }
123   CXFA_FFWidget* pWidget = GetOutmostFFWidget(pParams.GetWidget());
124   if (!pWidget)
125     return;
126 
127   CXFA_Node* pNode = pWidget->GetNode();
128   CFGAS_GEGraphics* pGraphics = pParams.GetGraphics();
129   CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
130   m_pTextOut->SetStyles(pParams.m_dwTTOStyles);
131   m_pTextOut->SetAlignment(pParams.m_iTTOAlign);
132   m_pTextOut->SetFont(pNode->GetFGASFont(pWidget->GetDoc()));
133   m_pTextOut->SetFontSize(pNode->GetFontSize());
134   m_pTextOut->SetTextColor(pNode->GetTextColor());
135   CFX_Matrix mtPart = pParams.m_matrix;
136   const CFX_Matrix* pMatrix = pGraphics->GetMatrix();
137   if (pMatrix)
138     mtPart.Concat(*pMatrix);
139 
140   m_pTextOut->SetMatrix(mtPart);
141   m_pTextOut->DrawLogicText(pRenderDevice, pParams.m_wsText,
142                             pParams.m_PartRect);
143 }
144 
GetUIMargin(const CFWL_ThemePart & pThemePart) const145 CFX_RectF CXFA_FWLTheme::GetUIMargin(const CFWL_ThemePart& pThemePart) const {
146   CXFA_FFWidget* pWidget = GetOutmostFFWidget(pThemePart.GetWidget());
147   if (!pWidget)
148     return CFX_RectF();
149 
150   CXFA_ContentLayoutItem* pItem = pWidget->GetLayoutItem();
151   CXFA_Node* pNode = pWidget->GetNode();
152   CFX_RectF rect = pNode->GetUIMargin();
153   CXFA_Para* para = pNode->GetParaIfExists();
154   if (para) {
155     rect.left += para->GetMarginLeft();
156     if (pNode->IsMultiLine())
157       rect.width += para->GetMarginRight();
158   }
159   if (!pItem->GetPrev()) {
160     if (pItem->GetNext())
161       rect.height = 0;
162   } else if (!pItem->GetNext()) {
163     rect.top = 0;
164   } else {
165     rect.top = 0;
166     rect.height = 0;
167   }
168   return rect;
169 }
170 
GetCXBorderSize() const171 float CXFA_FWLTheme::GetCXBorderSize() const {
172   return 1.0f;
173 }
174 
GetCYBorderSize() const175 float CXFA_FWLTheme::GetCYBorderSize() const {
176   return 1.0f;
177 }
178 
GetFontSize(const CFWL_ThemePart & pThemePart) const179 float CXFA_FWLTheme::GetFontSize(const CFWL_ThemePart& pThemePart) const {
180   if (CXFA_FFWidget* pWidget = GetOutmostFFWidget(pThemePart.GetWidget()))
181     return pWidget->GetNode()->GetFontSize();
182   return FWLTHEME_CAPACITY_FontSize;
183 }
184 
GetFont(const CFWL_ThemePart & pThemePart)185 RetainPtr<CFGAS_GEFont> CXFA_FWLTheme::GetFont(
186     const CFWL_ThemePart& pThemePart) {
187   if (CXFA_FFWidget* pWidget = GetOutmostFFWidget(pThemePart.GetWidget()))
188     return pWidget->GetNode()->GetFGASFont(pWidget->GetDoc());
189 
190   return GetFWLFont();
191 }
192 
GetFWLFont()193 RetainPtr<CFGAS_GEFont> CXFA_FWLTheme::GetFWLFont() {
194   if (!m_pFWLFont)
195     m_pFWLFont = CFGAS_GEFont::LoadFont(L"Helvetica", 0, FX_CodePage::kDefANSI);
196 
197   return m_pFWLFont;
198 }
199 
GetLineHeight(const CFWL_ThemePart & pThemePart) const200 float CXFA_FWLTheme::GetLineHeight(const CFWL_ThemePart& pThemePart) const {
201   if (CXFA_FFWidget* pWidget = GetOutmostFFWidget(pThemePart.GetWidget()))
202     return pWidget->GetNode()->GetLineHeight();
203   return kLineHeight;
204 }
205 
GetScrollBarWidth() const206 float CXFA_FWLTheme::GetScrollBarWidth() const {
207   return 9.0f;
208 }
209 
GetTextColor(const CFWL_ThemePart & pThemePart) const210 FX_COLORREF CXFA_FWLTheme::GetTextColor(
211     const CFWL_ThemePart& pThemePart) const {
212   if (CXFA_FFWidget* pWidget = GetOutmostFFWidget(pThemePart.GetWidget()))
213     return pWidget->GetNode()->GetTextColor();
214   return FWLTHEME_CAPACITY_TextColor;
215 }
216 
GetSpaceAboveBelow(const CFWL_ThemePart & pThemePart) const217 CFX_SizeF CXFA_FWLTheme::GetSpaceAboveBelow(
218     const CFWL_ThemePart& pThemePart) const {
219   CFX_SizeF sizeAboveBelow;
220   if (CXFA_FFWidget* pWidget = GetOutmostFFWidget(pThemePart.GetWidget())) {
221     CXFA_Para* para = pWidget->GetNode()->GetParaIfExists();
222     if (para) {
223       sizeAboveBelow.width = para->GetSpaceAbove();
224       sizeAboveBelow.height = para->GetSpaceBelow();
225     }
226   }
227   return sizeAboveBelow;
228 }
229 
CalcTextRect(const CFWL_ThemeText & pParams,CFX_RectF * pRect)230 void CXFA_FWLTheme::CalcTextRect(const CFWL_ThemeText& pParams,
231                                  CFX_RectF* pRect) {
232   CXFA_FFWidget* pWidget = GetOutmostFFWidget(pParams.GetWidget());
233   if (!pWidget)
234     return;
235 
236   if (pParams.GetWidget()->GetClassID() == FWL_Type::MonthCalendar) {
237     m_pTextOut->SetFont(m_pCalendarFont);
238     m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
239     m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
240     m_pTextOut->SetAlignment(pParams.m_iTTOAlign);
241     m_pTextOut->SetStyles(pParams.m_dwTTOStyles);
242     m_pTextOut->CalcLogicSize(pParams.m_wsText.AsStringView(), pRect);
243     return;
244   }
245 
246   CXFA_Node* pNode = pWidget->GetNode();
247   m_pTextOut->SetFont(pNode->GetFGASFont(pWidget->GetDoc()));
248   m_pTextOut->SetFontSize(pNode->GetFontSize());
249   m_pTextOut->SetTextColor(pNode->GetTextColor());
250   m_pTextOut->SetAlignment(pParams.m_iTTOAlign);
251   m_pTextOut->SetStyles(pParams.m_dwTTOStyles);
252   m_pTextOut->CalcLogicSize(pParams.m_wsText.AsStringView(), pRect);
253 }
254