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/fwl/theme/cfwl_widgettp.h"
8
9 #include <algorithm>
10 #include <utility>
11
12 #include "third_party/base/ptr_util.h"
13 #include "xfa/fde/cfde_textout.h"
14 #include "xfa/fgas/font/cfgas_fontmgr.h"
15 #include "xfa/fgas/font/cfgas_gefont.h"
16 #include "xfa/fwl/cfwl_themebackground.h"
17 #include "xfa/fwl/cfwl_themepart.h"
18 #include "xfa/fwl/cfwl_themetext.h"
19 #include "xfa/fwl/cfwl_widget.h"
20 #include "xfa/fwl/cfwl_widgetmgr.h"
21 #include "xfa/fwl/ifwl_themeprovider.h"
22 #include "xfa/fxgraphics/cxfa_gecolor.h"
23 #include "xfa/fxgraphics/cxfa_gepath.h"
24 #include "xfa/fxgraphics/cxfa_geshading.h"
25
CFWL_WidgetTP()26 CFWL_WidgetTP::CFWL_WidgetTP()
27 : m_dwRefCount(1), m_pFDEFont(nullptr), m_pColorData(nullptr) {}
28
~CFWL_WidgetTP()29 CFWL_WidgetTP::~CFWL_WidgetTP() {}
30
Initialize()31 void CFWL_WidgetTP::Initialize() {}
32
Finalize()33 void CFWL_WidgetTP::Finalize() {
34 if (m_pTextOut)
35 FinalizeTTO();
36 }
37
DrawBackground(CFWL_ThemeBackground * pParams)38 void CFWL_WidgetTP::DrawBackground(CFWL_ThemeBackground* pParams) {}
39
DrawText(CFWL_ThemeText * pParams)40 void CFWL_WidgetTP::DrawText(CFWL_ThemeText* pParams) {
41 if (!m_pTextOut)
42 InitTTO();
43
44 int32_t iLen = pParams->m_wsText.GetLength();
45 if (iLen <= 0)
46 return;
47
48 CXFA_Graphics* pGraphics = pParams->m_pGraphics;
49 m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
50 m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
51
52 CFX_Matrix* pMatrix = &pParams->m_matrix;
53 pMatrix->Concat(*pGraphics->GetMatrix());
54 m_pTextOut->SetMatrix(*pMatrix);
55 m_pTextOut->DrawLogicText(pGraphics->GetRenderDevice(),
56 WideStringView(pParams->m_wsText.c_str(), iLen),
57 pParams->m_rtPart);
58 }
59
GetFont() const60 const RetainPtr<CFGAS_GEFont>& CFWL_WidgetTP::GetFont() const {
61 return m_pFDEFont;
62 }
63
InitializeArrowColorData()64 void CFWL_WidgetTP::InitializeArrowColorData() {
65 if (m_pColorData)
66 return;
67
68 m_pColorData = pdfium::MakeUnique<CColorData>();
69 m_pColorData->clrBorder[0] = ArgbEncode(255, 202, 216, 249);
70 m_pColorData->clrBorder[1] = ArgbEncode(255, 171, 190, 233);
71 m_pColorData->clrBorder[2] = ArgbEncode(255, 135, 147, 219);
72 m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
73 m_pColorData->clrStart[0] = ArgbEncode(255, 225, 234, 254);
74 m_pColorData->clrStart[1] = ArgbEncode(255, 253, 255, 255);
75 m_pColorData->clrStart[2] = ArgbEncode(255, 110, 142, 241);
76 m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
77 m_pColorData->clrEnd[0] = ArgbEncode(255, 175, 204, 251);
78 m_pColorData->clrEnd[1] = ArgbEncode(255, 185, 218, 251);
79 m_pColorData->clrEnd[2] = ArgbEncode(255, 210, 222, 235);
80 m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
81 m_pColorData->clrSign[0] = ArgbEncode(255, 77, 97, 133);
82 m_pColorData->clrSign[1] = ArgbEncode(255, 77, 97, 133);
83 m_pColorData->clrSign[2] = ArgbEncode(255, 77, 97, 133);
84 m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
85 }
86
87
InitTTO()88 void CFWL_WidgetTP::InitTTO() {
89 if (m_pTextOut)
90 return;
91
92 m_pFDEFont = CFWL_FontManager::GetInstance()->FindFont(L"Helvetica", 0, 0);
93 m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
94 m_pTextOut->SetFont(m_pFDEFont);
95 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
96 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
97 }
98
FinalizeTTO()99 void CFWL_WidgetTP::FinalizeTTO() {
100 m_pTextOut.reset();
101 }
102
DrawBorder(CXFA_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)103 void CFWL_WidgetTP::DrawBorder(CXFA_Graphics* pGraphics,
104 const CFX_RectF* pRect,
105 CFX_Matrix* pMatrix) {
106 if (!pGraphics || !pRect)
107 return;
108
109 CXFA_GEPath path;
110 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
111 path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
112 pRect->height - 2);
113 pGraphics->SaveGraphState();
114 pGraphics->SetFillColor(CXFA_GEColor(ArgbEncode(255, 0, 0, 0)));
115 pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
116 pGraphics->RestoreGraphState();
117 }
118
FillBackground(CXFA_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)119 void CFWL_WidgetTP::FillBackground(CXFA_Graphics* pGraphics,
120 const CFX_RectF* pRect,
121 CFX_Matrix* pMatrix) {
122 FillSoildRect(pGraphics, FWLTHEME_COLOR_Background, pRect, pMatrix);
123 }
124
FillSoildRect(CXFA_Graphics * pGraphics,FX_ARGB fillColor,const CFX_RectF * pRect,CFX_Matrix * pMatrix)125 void CFWL_WidgetTP::FillSoildRect(CXFA_Graphics* pGraphics,
126 FX_ARGB fillColor,
127 const CFX_RectF* pRect,
128 CFX_Matrix* pMatrix) {
129 if (!pGraphics || !pRect)
130 return;
131
132 CXFA_GEPath path;
133 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
134 pGraphics->SaveGraphState();
135 pGraphics->SetFillColor(CXFA_GEColor(fillColor));
136 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
137 pGraphics->RestoreGraphState();
138 }
139
DrawAxialShading(CXFA_Graphics * pGraphics,float fx1,float fy1,float fx2,float fy2,FX_ARGB beginColor,FX_ARGB endColor,CXFA_GEPath * path,int32_t fillMode,CFX_Matrix * pMatrix)140 void CFWL_WidgetTP::DrawAxialShading(CXFA_Graphics* pGraphics,
141 float fx1,
142 float fy1,
143 float fx2,
144 float fy2,
145 FX_ARGB beginColor,
146 FX_ARGB endColor,
147 CXFA_GEPath* path,
148 int32_t fillMode,
149 CFX_Matrix* pMatrix) {
150 if (!pGraphics || !path)
151 return;
152
153 CFX_PointF begPoint(fx1, fy1);
154 CFX_PointF endPoint(fx2, fy2);
155 CXFA_GEShading shading(begPoint, endPoint, false, false, beginColor,
156 endColor);
157 pGraphics->SaveGraphState();
158 pGraphics->SetFillColor(CXFA_GEColor(&shading));
159 pGraphics->FillPath(path, fillMode, pMatrix);
160 pGraphics->RestoreGraphState();
161 }
162
DrawFocus(CXFA_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)163 void CFWL_WidgetTP::DrawFocus(CXFA_Graphics* pGraphics,
164 const CFX_RectF* pRect,
165 CFX_Matrix* pMatrix) {
166 if (!pGraphics || !pRect)
167 return;
168
169 float DashPattern[2] = {1, 1};
170 CXFA_GEPath path;
171 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
172 pGraphics->SaveGraphState();
173 pGraphics->SetStrokeColor(CXFA_GEColor(0xFF000000));
174 pGraphics->SetLineDash(0.0f, DashPattern, 2);
175 pGraphics->StrokePath(&path, pMatrix);
176 pGraphics->RestoreGraphState();
177 }
178
DrawArrow(CXFA_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FX_ARGB argSign,CFX_Matrix * pMatrix)179 void CFWL_WidgetTP::DrawArrow(CXFA_Graphics* pGraphics,
180 const CFX_RectF* pRect,
181 FWLTHEME_DIRECTION eDict,
182 FX_ARGB argSign,
183 CFX_Matrix* pMatrix) {
184 bool bVert =
185 (eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down);
186 float fLeft =
187 (float)(((pRect->width - (bVert ? 9 : 6)) / 2 + pRect->left) + 0.5);
188 float fTop =
189 (float)(((pRect->height - (bVert ? 6 : 9)) / 2 + pRect->top) + 0.5);
190 CXFA_GEPath path;
191 switch (eDict) {
192 case FWLTHEME_DIRECTION_Down: {
193 path.MoveTo(CFX_PointF(fLeft, fTop + 1));
194 path.LineTo(CFX_PointF(fLeft + 4, fTop + 5));
195 path.LineTo(CFX_PointF(fLeft + 8, fTop + 1));
196 path.LineTo(CFX_PointF(fLeft + 7, fTop));
197 path.LineTo(CFX_PointF(fLeft + 4, fTop + 3));
198 path.LineTo(CFX_PointF(fLeft + 1, fTop));
199 break;
200 }
201 case FWLTHEME_DIRECTION_Up: {
202 path.MoveTo(CFX_PointF(fLeft, fTop + 4));
203 path.LineTo(CFX_PointF(fLeft + 4, fTop));
204 path.LineTo(CFX_PointF(fLeft + 8, fTop + 4));
205 path.LineTo(CFX_PointF(fLeft + 7, fTop + 5));
206 path.LineTo(CFX_PointF(fLeft + 4, fTop + 2));
207 path.LineTo(CFX_PointF(fLeft + 1, fTop + 5));
208 break;
209 }
210 case FWLTHEME_DIRECTION_Right: {
211 path.MoveTo(CFX_PointF(fLeft + 1, fTop));
212 path.LineTo(CFX_PointF(fLeft + 5, fTop + 4));
213 path.LineTo(CFX_PointF(fLeft + 1, fTop + 8));
214 path.LineTo(CFX_PointF(fLeft, fTop + 7));
215 path.LineTo(CFX_PointF(fLeft + 3, fTop + 4));
216 path.LineTo(CFX_PointF(fLeft, fTop + 1));
217 break;
218 }
219 case FWLTHEME_DIRECTION_Left: {
220 path.MoveTo(CFX_PointF(fLeft, fTop + 4));
221 path.LineTo(CFX_PointF(fLeft + 4, fTop));
222 path.LineTo(CFX_PointF(fLeft + 5, fTop + 1));
223 path.LineTo(CFX_PointF(fLeft + 2, fTop + 4));
224 path.LineTo(CFX_PointF(fLeft + 5, fTop + 7));
225 path.LineTo(CFX_PointF(fLeft + 4, fTop + 8));
226 break;
227 }
228 }
229 pGraphics->SetFillColor(CXFA_GEColor(argSign));
230 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
231 }
232
DrawBtn(CXFA_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)233 void CFWL_WidgetTP::DrawBtn(CXFA_Graphics* pGraphics,
234 const CFX_RectF* pRect,
235 FWLTHEME_STATE eState,
236 CFX_Matrix* pMatrix) {
237 InitializeArrowColorData();
238
239 CXFA_GEPath path;
240 float fRight = pRect->right();
241 float fBottom = pRect->bottom();
242 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
243 DrawAxialShading(pGraphics, pRect->left, pRect->top, fRight, fBottom,
244 m_pColorData->clrStart[eState - 1],
245 m_pColorData->clrEnd[eState - 1], &path, FXFILL_WINDING,
246 pMatrix);
247
248 pGraphics->SetStrokeColor(CXFA_GEColor(m_pColorData->clrBorder[eState - 1]));
249 pGraphics->StrokePath(&path, pMatrix);
250 }
251
DrawArrowBtn(CXFA_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)252 void CFWL_WidgetTP::DrawArrowBtn(CXFA_Graphics* pGraphics,
253 const CFX_RectF* pRect,
254 FWLTHEME_DIRECTION eDict,
255 FWLTHEME_STATE eState,
256 CFX_Matrix* pMatrix) {
257 DrawBtn(pGraphics, pRect, eState, pMatrix);
258
259 InitializeArrowColorData();
260 DrawArrow(pGraphics, pRect, eDict, m_pColorData->clrSign[eState - 1],
261 pMatrix);
262 }
263
CFWL_FontData()264 CFWL_FontData::CFWL_FontData() : m_dwStyles(0), m_dwCodePage(0) {}
265
~CFWL_FontData()266 CFWL_FontData::~CFWL_FontData() {}
267
Equal(const WideStringView & wsFontFamily,uint32_t dwFontStyles,uint16_t wCodePage)268 bool CFWL_FontData::Equal(const WideStringView& wsFontFamily,
269 uint32_t dwFontStyles,
270 uint16_t wCodePage) {
271 return m_wsFamily == wsFontFamily && m_dwStyles == dwFontStyles &&
272 m_dwCodePage == wCodePage;
273 }
274
LoadFont(const WideStringView & wsFontFamily,uint32_t dwFontStyles,uint16_t dwCodePage)275 bool CFWL_FontData::LoadFont(const WideStringView& wsFontFamily,
276 uint32_t dwFontStyles,
277 uint16_t dwCodePage) {
278 m_wsFamily = wsFontFamily;
279 m_dwStyles = dwFontStyles;
280 m_dwCodePage = dwCodePage;
281 if (!m_pFontMgr) {
282 m_pFontMgr = pdfium::MakeUnique<CFGAS_FontMgr>();
283 if (!m_pFontMgr->EnumFonts())
284 m_pFontMgr = nullptr;
285 }
286
287 // TODO(tsepez): check usage of c_str() below.
288 m_pFont = CFGAS_GEFont::LoadFont(wsFontFamily.unterminated_c_str(),
289 dwFontStyles, dwCodePage, m_pFontMgr.get());
290 return !!m_pFont;
291 }
292
GetFont() const293 RetainPtr<CFGAS_GEFont> CFWL_FontData::GetFont() const {
294 return m_pFont;
295 }
296
297 CFWL_FontManager* CFWL_FontManager::s_FontManager = nullptr;
GetInstance()298 CFWL_FontManager* CFWL_FontManager::GetInstance() {
299 if (!s_FontManager)
300 s_FontManager = new CFWL_FontManager;
301 return s_FontManager;
302 }
303
DestroyInstance()304 void CFWL_FontManager::DestroyInstance() {
305 delete s_FontManager;
306 s_FontManager = nullptr;
307 }
308
CFWL_FontManager()309 CFWL_FontManager::CFWL_FontManager() {}
310
~CFWL_FontManager()311 CFWL_FontManager::~CFWL_FontManager() {}
312
FindFont(const WideStringView & wsFontFamily,uint32_t dwFontStyles,uint16_t wCodePage)313 RetainPtr<CFGAS_GEFont> CFWL_FontManager::FindFont(
314 const WideStringView& wsFontFamily,
315 uint32_t dwFontStyles,
316 uint16_t wCodePage) {
317 for (const auto& pData : m_FontsArray) {
318 if (pData->Equal(wsFontFamily, dwFontStyles, wCodePage))
319 return pData->GetFont();
320 }
321 auto pFontData = pdfium::MakeUnique<CFWL_FontData>();
322 if (!pFontData->LoadFont(wsFontFamily, dwFontStyles, wCodePage))
323 return nullptr;
324
325 m_FontsArray.push_back(std::move(pFontData));
326 return m_FontsArray.back()->GetFont();
327 }
328
FWLTHEME_Release()329 void FWLTHEME_Release() {
330 CFWL_FontManager::DestroyInstance();
331 }
332