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/tto/fde_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/cfx_color.h"
23 #include "xfa/fxgraphics/cfx_path.h"
24 #include "xfa/fxgraphics/cfx_shading.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 CFX_Graphics* pGraphics = pParams->m_pGraphics;
49 m_pTextOut->SetRenderDevice(pGraphics->GetRenderDevice());
50 m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
51 m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
52
53 CFX_Matrix* pMatrix = &pParams->m_matrix;
54 pMatrix->Concat(*pGraphics->GetMatrix());
55 m_pTextOut->SetMatrix(*pMatrix);
56 m_pTextOut->DrawLogicText(pParams->m_wsText.c_str(), iLen, pParams->m_rtPart);
57 }
58
InitializeArrowColorData()59 void CFWL_WidgetTP::InitializeArrowColorData() {
60 if (m_pColorData)
61 return;
62
63 m_pColorData = pdfium::MakeUnique<CColorData>();
64 m_pColorData->clrBorder[0] = ArgbEncode(255, 202, 216, 249);
65 m_pColorData->clrBorder[1] = ArgbEncode(255, 171, 190, 233);
66 m_pColorData->clrBorder[2] = ArgbEncode(255, 135, 147, 219);
67 m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
68 m_pColorData->clrStart[0] = ArgbEncode(255, 225, 234, 254);
69 m_pColorData->clrStart[1] = ArgbEncode(255, 253, 255, 255);
70 m_pColorData->clrStart[2] = ArgbEncode(255, 110, 142, 241);
71 m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
72 m_pColorData->clrEnd[0] = ArgbEncode(255, 175, 204, 251);
73 m_pColorData->clrEnd[1] = ArgbEncode(255, 185, 218, 251);
74 m_pColorData->clrEnd[2] = ArgbEncode(255, 210, 222, 235);
75 m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
76 m_pColorData->clrSign[0] = ArgbEncode(255, 77, 97, 133);
77 m_pColorData->clrSign[1] = ArgbEncode(255, 77, 97, 133);
78 m_pColorData->clrSign[2] = ArgbEncode(255, 77, 97, 133);
79 m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
80 }
81
82
InitTTO()83 void CFWL_WidgetTP::InitTTO() {
84 if (m_pTextOut)
85 return;
86
87 m_pFDEFont = CFWL_FontManager::GetInstance()->FindFont(L"Helvetica", 0, 0);
88 m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
89 m_pTextOut->SetFont(m_pFDEFont);
90 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
91 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
92 m_pTextOut->SetEllipsisString(L"...");
93 }
94
FinalizeTTO()95 void CFWL_WidgetTP::FinalizeTTO() {
96 m_pTextOut.reset();
97 }
98
DrawBorder(CFX_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)99 void CFWL_WidgetTP::DrawBorder(CFX_Graphics* pGraphics,
100 const CFX_RectF* pRect,
101 CFX_Matrix* pMatrix) {
102 if (!pGraphics)
103 return;
104 if (!pRect)
105 return;
106 CFX_Path path;
107 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
108 path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
109 pRect->height - 2);
110 pGraphics->SaveGraphState();
111 CFX_Color crFill(ArgbEncode(255, 0, 0, 0));
112 pGraphics->SetFillColor(&crFill);
113 pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
114 pGraphics->RestoreGraphState();
115 }
116
FillBackground(CFX_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)117 void CFWL_WidgetTP::FillBackground(CFX_Graphics* pGraphics,
118 const CFX_RectF* pRect,
119 CFX_Matrix* pMatrix) {
120 FillSoildRect(pGraphics, FWLTHEME_COLOR_Background, pRect, pMatrix);
121 }
122
FillSoildRect(CFX_Graphics * pGraphics,FX_ARGB fillColor,const CFX_RectF * pRect,CFX_Matrix * pMatrix)123 void CFWL_WidgetTP::FillSoildRect(CFX_Graphics* pGraphics,
124 FX_ARGB fillColor,
125 const CFX_RectF* pRect,
126 CFX_Matrix* pMatrix) {
127 if (!pGraphics)
128 return;
129 if (!pRect)
130 return;
131 pGraphics->SaveGraphState();
132 CFX_Color crFill(fillColor);
133 pGraphics->SetFillColor(&crFill);
134 CFX_Path path;
135 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
136 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
137 pGraphics->RestoreGraphState();
138 }
139
DrawAxialShading(CFX_Graphics * pGraphics,FX_FLOAT fx1,FX_FLOAT fy1,FX_FLOAT fx2,FX_FLOAT fy2,FX_ARGB beginColor,FX_ARGB endColor,CFX_Path * path,int32_t fillMode,CFX_Matrix * pMatrix)140 void CFWL_WidgetTP::DrawAxialShading(CFX_Graphics* pGraphics,
141 FX_FLOAT fx1,
142 FX_FLOAT fy1,
143 FX_FLOAT fx2,
144 FX_FLOAT fy2,
145 FX_ARGB beginColor,
146 FX_ARGB endColor,
147 CFX_Path* 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 CFX_Shading shading(begPoint, endPoint, false, false, beginColor, endColor);
156 pGraphics->SaveGraphState();
157 CFX_Color color1(&shading);
158 pGraphics->SetFillColor(&color1);
159 pGraphics->FillPath(path, fillMode, pMatrix);
160 pGraphics->RestoreGraphState();
161 }
162
DrawFocus(CFX_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)163 void CFWL_WidgetTP::DrawFocus(CFX_Graphics* pGraphics,
164 const CFX_RectF* pRect,
165 CFX_Matrix* pMatrix) {
166 if (!pGraphics)
167 return;
168 if (!pRect)
169 return;
170 pGraphics->SaveGraphState();
171 CFX_Color cr(0xFF000000);
172 pGraphics->SetStrokeColor(&cr);
173 FX_FLOAT DashPattern[2] = {1, 1};
174 pGraphics->SetLineDash(0.0f, DashPattern, 2);
175 CFX_Path path;
176 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
177 pGraphics->StrokePath(&path, pMatrix);
178 pGraphics->RestoreGraphState();
179 }
180
DrawArrow(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FX_ARGB argSign,CFX_Matrix * pMatrix)181 void CFWL_WidgetTP::DrawArrow(CFX_Graphics* pGraphics,
182 const CFX_RectF* pRect,
183 FWLTHEME_DIRECTION eDict,
184 FX_ARGB argSign,
185 CFX_Matrix* pMatrix) {
186 bool bVert =
187 (eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down);
188 FX_FLOAT fLeft =
189 (FX_FLOAT)(((pRect->width - (bVert ? 9 : 6)) / 2 + pRect->left) + 0.5);
190 FX_FLOAT fTop =
191 (FX_FLOAT)(((pRect->height - (bVert ? 6 : 9)) / 2 + pRect->top) + 0.5);
192 CFX_Path path;
193 switch (eDict) {
194 case FWLTHEME_DIRECTION_Down: {
195 path.MoveTo(CFX_PointF(fLeft, fTop + 1));
196 path.LineTo(CFX_PointF(fLeft + 4, fTop + 5));
197 path.LineTo(CFX_PointF(fLeft + 8, fTop + 1));
198 path.LineTo(CFX_PointF(fLeft + 7, fTop));
199 path.LineTo(CFX_PointF(fLeft + 4, fTop + 3));
200 path.LineTo(CFX_PointF(fLeft + 1, fTop));
201 break;
202 }
203 case FWLTHEME_DIRECTION_Up: {
204 path.MoveTo(CFX_PointF(fLeft, fTop + 4));
205 path.LineTo(CFX_PointF(fLeft + 4, fTop));
206 path.LineTo(CFX_PointF(fLeft + 8, fTop + 4));
207 path.LineTo(CFX_PointF(fLeft + 7, fTop + 5));
208 path.LineTo(CFX_PointF(fLeft + 4, fTop + 2));
209 path.LineTo(CFX_PointF(fLeft + 1, fTop + 5));
210 break;
211 }
212 case FWLTHEME_DIRECTION_Right: {
213 path.MoveTo(CFX_PointF(fLeft + 1, fTop));
214 path.LineTo(CFX_PointF(fLeft + 5, fTop + 4));
215 path.LineTo(CFX_PointF(fLeft + 1, fTop + 8));
216 path.LineTo(CFX_PointF(fLeft, fTop + 7));
217 path.LineTo(CFX_PointF(fLeft + 3, fTop + 4));
218 path.LineTo(CFX_PointF(fLeft, fTop + 1));
219 break;
220 }
221 case FWLTHEME_DIRECTION_Left: {
222 path.MoveTo(CFX_PointF(fLeft, fTop + 4));
223 path.LineTo(CFX_PointF(fLeft + 4, fTop));
224 path.LineTo(CFX_PointF(fLeft + 5, fTop + 1));
225 path.LineTo(CFX_PointF(fLeft + 2, fTop + 4));
226 path.LineTo(CFX_PointF(fLeft + 5, fTop + 7));
227 path.LineTo(CFX_PointF(fLeft + 4, fTop + 8));
228 break;
229 }
230 }
231 CFX_Color cr(argSign);
232 pGraphics->SetFillColor(&cr);
233 pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
234 }
235
DrawBtn(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)236 void CFWL_WidgetTP::DrawBtn(CFX_Graphics* pGraphics,
237 const CFX_RectF* pRect,
238 FWLTHEME_STATE eState,
239 CFX_Matrix* pMatrix) {
240 CFX_Path path;
241 InitializeArrowColorData();
242
243 FX_FLOAT fRight = pRect->right();
244 FX_FLOAT fBottom = pRect->bottom();
245 path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
246 DrawAxialShading(pGraphics, pRect->left, pRect->top, fRight, fBottom,
247 m_pColorData->clrStart[eState - 1],
248 m_pColorData->clrEnd[eState - 1], &path, FXFILL_WINDING,
249 pMatrix);
250
251 CFX_Color rcStroke;
252 rcStroke.Set(m_pColorData->clrBorder[eState - 1]);
253 pGraphics->SetStrokeColor(&rcStroke);
254 pGraphics->StrokePath(&path, pMatrix);
255 }
256
DrawArrowBtn(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)257 void CFWL_WidgetTP::DrawArrowBtn(CFX_Graphics* pGraphics,
258 const CFX_RectF* pRect,
259 FWLTHEME_DIRECTION eDict,
260 FWLTHEME_STATE eState,
261 CFX_Matrix* pMatrix) {
262 DrawBtn(pGraphics, pRect, eState, pMatrix);
263
264 InitializeArrowColorData();
265 DrawArrow(pGraphics, pRect, eDict, m_pColorData->clrSign[eState - 1],
266 pMatrix);
267 }
268
CFWL_FontData()269 CFWL_FontData::CFWL_FontData() : m_dwStyles(0), m_dwCodePage(0) {}
270
~CFWL_FontData()271 CFWL_FontData::~CFWL_FontData() {}
272
Equal(const CFX_WideStringC & wsFontFamily,uint32_t dwFontStyles,uint16_t wCodePage)273 bool CFWL_FontData::Equal(const CFX_WideStringC& wsFontFamily,
274 uint32_t dwFontStyles,
275 uint16_t wCodePage) {
276 return m_wsFamily == wsFontFamily && m_dwStyles == dwFontStyles &&
277 m_dwCodePage == wCodePage;
278 }
279
LoadFont(const CFX_WideStringC & wsFontFamily,uint32_t dwFontStyles,uint16_t dwCodePage)280 bool CFWL_FontData::LoadFont(const CFX_WideStringC& wsFontFamily,
281 uint32_t dwFontStyles,
282 uint16_t dwCodePage) {
283 m_wsFamily = wsFontFamily;
284 m_dwStyles = dwFontStyles;
285 m_dwCodePage = dwCodePage;
286 if (!m_pFontMgr) {
287 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
288 m_pFontMgr = CFGAS_FontMgr::Create(FX_GetDefFontEnumerator());
289 #else
290 m_pFontSource = pdfium::MakeUnique<CFX_FontSourceEnum_File>();
291 m_pFontMgr = CFGAS_FontMgr::Create(m_pFontSource.get());
292 #endif
293 }
294 m_pFont = CFGAS_GEFont::LoadFont(wsFontFamily.c_str(), dwFontStyles,
295 dwCodePage, m_pFontMgr.get());
296 return !!m_pFont;
297 }
298
299 CFWL_FontManager* CFWL_FontManager::s_FontManager = nullptr;
GetInstance()300 CFWL_FontManager* CFWL_FontManager::GetInstance() {
301 if (!s_FontManager)
302 s_FontManager = new CFWL_FontManager;
303 return s_FontManager;
304 }
305
DestroyInstance()306 void CFWL_FontManager::DestroyInstance() {
307 delete s_FontManager;
308 s_FontManager = nullptr;
309 }
310
CFWL_FontManager()311 CFWL_FontManager::CFWL_FontManager() {}
312
~CFWL_FontManager()313 CFWL_FontManager::~CFWL_FontManager() {}
314
FindFont(const CFX_WideStringC & wsFontFamily,uint32_t dwFontStyles,uint16_t wCodePage)315 CFX_RetainPtr<CFGAS_GEFont> CFWL_FontManager::FindFont(
316 const CFX_WideStringC& wsFontFamily,
317 uint32_t dwFontStyles,
318 uint16_t wCodePage) {
319 for (const auto& pData : m_FontsArray) {
320 if (pData->Equal(wsFontFamily, dwFontStyles, wCodePage))
321 return pData->GetFont();
322 }
323 auto pFontData = pdfium::MakeUnique<CFWL_FontData>();
324 if (!pFontData->LoadFont(wsFontFamily, dwFontStyles, wCodePage))
325 return nullptr;
326
327 m_FontsArray.push_back(std::move(pFontData));
328 return m_FontsArray.back()->GetFont();
329 }
330
FWLTHEME_Release()331 void FWLTHEME_Release() {
332 CFWL_FontManager::DestroyInstance();
333 }
334