• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <algorithm>
8 
9 #include "xfa/src/foxitlib.h"
FWL_SetChildThemeID(IFWL_Widget * pParent,FX_DWORD dwThemeID)10 static void FWL_SetChildThemeID(IFWL_Widget* pParent, FX_DWORD dwThemeID) {
11   IFWL_WidgetMgr* pWidgetMgr = FWL_GetWidgetMgr();
12   IFWL_Widget* pChild =
13       pWidgetMgr->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
14   while (pChild) {
15     IFWL_ThemeProvider* pTheme = pChild->GetThemeProvider();
16     if (pTheme) {
17       pTheme->SetThemeID(pChild, dwThemeID, FALSE);
18     }
19     FWL_SetChildThemeID(pChild, dwThemeID);
20     pChild = pWidgetMgr->GetWidget(pChild, FWL_WGTRELATION_NextSibling);
21   }
22 }
IsValidWidget(IFWL_Widget * pWidget)23 FX_BOOL CFWL_WidgetTP::IsValidWidget(IFWL_Widget* pWidget) {
24   return FALSE;
25 }
GetThemeID(IFWL_Widget * pWidget)26 FX_DWORD CFWL_WidgetTP::GetThemeID(IFWL_Widget* pWidget) {
27   return m_dwThemeID;
28 }
SetThemeID(IFWL_Widget * pWidget,FX_DWORD dwThemeID,FX_BOOL bChildren)29 FX_DWORD CFWL_WidgetTP::SetThemeID(IFWL_Widget* pWidget,
30                                    FX_DWORD dwThemeID,
31                                    FX_BOOL bChildren) {
32   FX_DWORD dwOld = m_dwThemeID;
33   m_dwThemeID = dwThemeID;
34   if (CFWL_ArrowData::IsInstance()) {
35     CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(dwThemeID));
36   }
37   if (bChildren) {
38     FWL_SetChildThemeID(pWidget, dwThemeID);
39   }
40   return dwOld;
41 }
GetThemeMatrix(IFWL_Widget * pWidget,CFX_Matrix & matrix)42 FWL_ERR CFWL_WidgetTP::GetThemeMatrix(IFWL_Widget* pWidget,
43                                       CFX_Matrix& matrix) {
44   matrix.Set(_ctm.a, _ctm.b, _ctm.c, _ctm.d, _ctm.e, _ctm.f);
45   return FWL_ERR_Succeeded;
46 }
SetThemeMatrix(IFWL_Widget * pWidget,const CFX_Matrix & matrix)47 FWL_ERR CFWL_WidgetTP::SetThemeMatrix(IFWL_Widget* pWidget,
48                                       const CFX_Matrix& matrix) {
49   _ctm.Set(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
50   return FWL_ERR_Succeeded;
51 }
DrawBackground(CFWL_ThemeBackground * pParams)52 FX_BOOL CFWL_WidgetTP::DrawBackground(CFWL_ThemeBackground* pParams) {
53   return TRUE;
54 }
DrawText(CFWL_ThemeText * pParams)55 FX_BOOL CFWL_WidgetTP::DrawText(CFWL_ThemeText* pParams) {
56   if (!m_pTextOut) {
57     InitTTO();
58   }
59   int32_t iLen = pParams->m_wsText.GetLength();
60   if (iLen <= 0)
61     return FALSE;
62   CFX_Graphics* pGraphics = pParams->m_pGraphics;
63   m_pTextOut->SetRenderDevice(pGraphics->GetRenderDevice());
64   m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
65   m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
66   CFX_Matrix* pMatrix = &pParams->m_matrix;
67   pMatrix->Concat(*pGraphics->GetMatrix());
68   m_pTextOut->SetMatrix(*pMatrix);
69   m_pTextOut->DrawLogicText(pParams->m_wsText, iLen, pParams->m_rtPart);
70   return TRUE;
71 }
GetCapacity(CFWL_ThemePart * pThemePart,FX_DWORD dwCapacity)72 void* CFWL_WidgetTP::GetCapacity(CFWL_ThemePart* pThemePart,
73                                  FX_DWORD dwCapacity) {
74   switch (dwCapacity) {
75     case FWL_WGTCAPACITY_CXBorder: {
76       m_fValue = FWLTHEME_CAPACITY_CXBorder;
77       break;
78     }
79     case FWL_WGTCAPACITY_CYBorder: {
80       m_fValue = FWLTHEME_CAPACITY_CYBorder;
81       break;
82     }
83     case FWL_WGTCAPACITY_EdgeFlat: {
84       m_fValue = FWLTHEME_CAPACITY_EdgeFlat;
85       break;
86     }
87     case FWL_WGTCAPACITY_EdgeRaised: {
88       m_fValue = FWLTHEME_CAPACITY_EdgeRaised;
89       break;
90     }
91     case FWL_WGTCAPACITY_EdgeSunken: {
92       m_fValue = FWLTHEME_CAPACITY_EdgeSunken;
93       break;
94     }
95     case FWL_WGTCAPACITY_FontSize: {
96       m_fValue = FWLTHEME_CAPACITY_FontSize;
97       break;
98     }
99     case FWL_WGTCAPACITY_TextColor: {
100       m_dwValue = FWLTHEME_CAPACITY_TextColor;
101       return &m_dwValue;
102     }
103     case FWL_WGTCAPACITY_ScrollBarWidth: {
104       m_fValue = FWLTHEME_CAPACITY_ScrollBarWidth;
105       break;
106     }
107     case FWL_WGTCAPACITY_Font: {
108       return m_pFDEFont;
109     }
110     case FWL_WGTCAPACITY_TextSelColor: {
111       m_dwValue = (m_dwThemeID == 0) ? FWLTHEME_CAPACITY_TextSelColor
112                                      : FWLTHEME_COLOR_Green_BKSelected;
113       return &m_dwValue;
114     }
115     case FWL_WGTCAPACITY_LineHeight: {
116       m_fValue = FWLTHEME_CAPACITY_LineHeight;
117       break;
118     }
119     case FWL_WGTCAPACITY_UIMargin: {
120       m_rtMargin.Set(0, 0, 0, 0);
121       return &m_rtMargin;
122     }
123     default: { return NULL; }
124   }
125   return &m_fValue;
126 }
IsCustomizedLayout(IFWL_Widget * pWidget)127 FX_BOOL CFWL_WidgetTP::IsCustomizedLayout(IFWL_Widget* pWidget) {
128   return FWL_GetThemeLayout(m_dwThemeID);
129 }
GetPartRect(CFWL_ThemePart * pThemePart,CFX_RectF & rect)130 FWL_ERR CFWL_WidgetTP::GetPartRect(CFWL_ThemePart* pThemePart,
131                                    CFX_RectF& rect) {
132   return FWL_ERR_Succeeded;
133 }
IsInPart(CFWL_ThemePart * pThemePart,FX_FLOAT fx,FX_FLOAT fy)134 FX_BOOL CFWL_WidgetTP::IsInPart(CFWL_ThemePart* pThemePart,
135                                 FX_FLOAT fx,
136                                 FX_FLOAT fy) {
137   return TRUE;
138 }
CalcTextRect(CFWL_ThemeText * pParams,CFX_RectF & rect)139 FX_BOOL CFWL_WidgetTP::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) {
140   if (!pParams)
141     return FALSE;
142   if (!m_pTextOut)
143     return FALSE;
144   m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
145   m_pTextOut->SetStyles(pParams->m_dwTTOStyles | FDE_TTOSTYLE_ArabicContext);
146   m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(),
147                             rect);
148   return TRUE;
149 }
Initialize()150 FWL_ERR CFWL_WidgetTP::Initialize() {
151   m_dwThemeID = 0;
152   _ctm.SetIdentity();
153   return FWL_ERR_Succeeded;
154 }
Finalize()155 FWL_ERR CFWL_WidgetTP::Finalize() {
156   if (!m_pTextOut) {
157     FinalizeTTO();
158   }
159   return FWL_ERR_Succeeded;
160 }
~CFWL_WidgetTP()161 CFWL_WidgetTP::~CFWL_WidgetTP() {}
SetFont(IFWL_Widget * pWidget,const FX_WCHAR * strFont,FX_FLOAT fFontSize,FX_ARGB rgbFont)162 FWL_ERR CFWL_WidgetTP::SetFont(IFWL_Widget* pWidget,
163                                const FX_WCHAR* strFont,
164                                FX_FLOAT fFontSize,
165                                FX_ARGB rgbFont) {
166   if (!m_pTextOut) {
167     return FWL_ERR_Succeeded;
168   }
169   m_pFDEFont = FWL_GetFontManager()->FindFont(strFont, 0, 0);
170   m_pTextOut->SetFont(m_pFDEFont);
171   m_pTextOut->SetFontSize(fFontSize);
172   m_pTextOut->SetTextColor(rgbFont);
173   return FWL_ERR_Succeeded;
174 }
SetFont(IFWL_Widget * pWidget,IFX_Font * pFont,FX_FLOAT fFontSize,FX_ARGB rgbFont)175 FWL_ERR CFWL_WidgetTP::SetFont(IFWL_Widget* pWidget,
176                                IFX_Font* pFont,
177                                FX_FLOAT fFontSize,
178                                FX_ARGB rgbFont) {
179   if (!m_pTextOut) {
180     return FWL_ERR_Succeeded;
181   }
182   m_pTextOut->SetFont(pFont);
183   m_pTextOut->SetFontSize(fFontSize);
184   m_pTextOut->SetTextColor(rgbFont);
185   return FWL_ERR_Succeeded;
186 }
GetFont(IFWL_Widget * pWidget)187 IFX_Font* CFWL_WidgetTP::GetFont(IFWL_Widget* pWidget) {
188   return m_pFDEFont;
189 }
CFWL_WidgetTP()190 CFWL_WidgetTP::CFWL_WidgetTP()
191     : m_dwRefCount(1), m_pTextOut(NULL), m_pFDEFont(NULL), m_dwThemeID(0) {}
InitTTO()192 FX_ERR CFWL_WidgetTP::InitTTO() {
193   if (m_pTextOut) {
194     return FWL_ERR_Succeeded;
195   }
196   m_pFDEFont = FWL_GetFontManager()->FindFont(FX_WSTRC(L"Helvetica"), 0, 0);
197   m_pTextOut = IFDE_TextOut::Create();
198   m_pTextOut->SetFont(m_pFDEFont);
199   m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
200   m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
201   m_pTextOut->SetEllipsisString(L"...");
202   return FWL_ERR_Succeeded;
203 }
FinalizeTTO()204 FX_ERR CFWL_WidgetTP::FinalizeTTO() {
205   if (m_pTextOut) {
206     m_pTextOut->Release();
207     m_pTextOut = NULL;
208   }
209   return FWL_ERR_Succeeded;
210 }
211 #ifdef THEME_XPSimilar
DrawEdge(CFX_Graphics * pGraphics,FX_DWORD dwStyles,const CFX_RectF * pRect,CFX_Matrix * pMatrix)212 void CFWL_WidgetTP::DrawEdge(CFX_Graphics* pGraphics,
213                              FX_DWORD dwStyles,
214                              const CFX_RectF* pRect,
215                              CFX_Matrix* pMatrix) {
216   if (!pGraphics)
217     return;
218   if (!pRect)
219     return;
220   pGraphics->SaveGraphState();
221   CFX_Color crStroke(FWL_GetThemeColor(m_dwThemeID) == 0
222                          ? ArgbEncode(255, 127, 157, 185)
223                          : FWLTHEME_COLOR_Green_BKSelected);
224   pGraphics->SetStrokeColor(&crStroke);
225   CFX_Path path;
226   path.Create();
227   path.AddRectangle(pRect->left, pRect->top, pRect->width - 1,
228                     pRect->height - 1);
229   pGraphics->StrokePath(&path, pMatrix);
230   path.Clear();
231   crStroke = ArgbEncode(255, 255, 255, 255);
232   pGraphics->SetStrokeColor(&crStroke);
233   path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 3,
234                     pRect->height - 3);
235   pGraphics->StrokePath(&path, pMatrix);
236   pGraphics->RestoreGraphState();
237 }
238 #else
DrawEdge(CFX_Graphics * pGraphics,FX_DWORD dwStyles,const CFX_RectF * pRect,CFX_Matrix * pMatrix)239 void CFWL_WidgetTP::DrawEdge(CFX_Graphics* pGraphics,
240                              FX_DWORD dwStyles,
241                              const CFX_RectF* pRect,
242                              CFX_Matrix* pMatrix) {
243   if (!pGraphics)
244     return;
245   if (!pRect)
246     return;
247   FWLTHEME_EDGE eType;
248   FX_FLOAT fWidth;
249   switch (dwStyles & FWL_WGTSTYLE_EdgeMask) {
250     case FWL_WGTSTYLE_EdgeRaised: {
251       eType = FWLTHEME_EDGE_Raised, fWidth = FWLTHEME_CAPACITY_EdgeRaised;
252       break;
253     }
254     case FWL_WGTSTYLE_EdgeSunken: {
255       eType = FWLTHEME_EDGE_Sunken, fWidth = FWLTHEME_CAPACITY_EdgeSunken;
256       break;
257     }
258     case FWL_WGTSTYLE_EdgeFlat:
259     default: { return; }
260   }
261   Draw3DRect(pGraphics, eType, fWidth, pRect, FWLTHEME_COLOR_EDGELT1,
262              FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1,
263              FWLTHEME_COLOR_EDGERB2, pMatrix);
264 }
265 #endif
Draw3DRect(CFX_Graphics * pGraphics,FWLTHEME_EDGE eType,FX_FLOAT fWidth,const CFX_RectF * pRect,FX_ARGB cr1,FX_ARGB cr2,FX_ARGB cr3,FX_ARGB cr4,CFX_Matrix * pMatrix)266 void CFWL_WidgetTP::Draw3DRect(CFX_Graphics* pGraphics,
267                                FWLTHEME_EDGE eType,
268                                FX_FLOAT fWidth,
269                                const CFX_RectF* pRect,
270                                FX_ARGB cr1,
271                                FX_ARGB cr2,
272                                FX_ARGB cr3,
273                                FX_ARGB cr4,
274                                CFX_Matrix* pMatrix) {
275   if (!pGraphics)
276     return;
277   if (!pRect)
278     return;
279   pGraphics->SaveGraphState();
280   if (eType == FWLTHEME_EDGE_Flat) {
281     CFX_Path path;
282     path.Create();
283     path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
284     path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
285                       pRect->height - 2);
286     CFX_Color cr(ArgbEncode(255, 100, 100, 100));
287     pGraphics->SetFillColor(&cr);
288     pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
289     path.Clear();
290     path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
291                       pRect->height - 2);
292     path.AddRectangle(pRect->left + 2, pRect->top + 2, pRect->width - 4,
293                       pRect->height - 4);
294     cr.Set(0xFFFFFFFF);
295     pGraphics->SetFillColor(&cr);
296     pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
297   } else {
298     FX_FLOAT fLeft = pRect->left;
299     FX_FLOAT fRight = pRect->right();
300     FX_FLOAT fTop = pRect->top;
301     FX_FLOAT fBottom = pRect->bottom();
302     FX_FLOAT fHalfWidth = fWidth / 2.0f;
303     CFX_Color crLT(eType == FWLTHEME_EDGE_Raised ? cr4 : cr1);
304     pGraphics->SetFillColor(&crLT);
305     CFX_Path pathLT;
306     pathLT.Create();
307     pathLT.MoveTo(fLeft, fBottom - fHalfWidth);
308     pathLT.LineTo(fLeft, fTop);
309     pathLT.LineTo(fRight - fHalfWidth, fTop);
310     pathLT.LineTo(fRight - fHalfWidth, fTop + fHalfWidth);
311     pathLT.LineTo(fLeft + fHalfWidth, fTop + fHalfWidth);
312     pathLT.LineTo(fLeft + fHalfWidth, fBottom - fHalfWidth);
313     pathLT.LineTo(fLeft, fBottom - fHalfWidth);
314     pGraphics->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
315     crLT = CFX_Color(eType == FWLTHEME_EDGE_Raised ? cr3 : cr2);
316     pGraphics->SetFillColor(&crLT);
317     pathLT.Clear();
318     pathLT.MoveTo(fLeft + fHalfWidth, fBottom - fWidth);
319     pathLT.LineTo(fLeft + fHalfWidth, fTop + fHalfWidth);
320     pathLT.LineTo(fRight - fWidth, fTop + fHalfWidth);
321     pathLT.LineTo(fRight - fWidth, fTop + fWidth);
322     pathLT.LineTo(fLeft + fWidth, fTop + fWidth);
323     pathLT.LineTo(fLeft + fWidth, fBottom - fWidth);
324     pathLT.LineTo(fLeft + fHalfWidth, fBottom - fWidth);
325     pGraphics->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
326     CFX_Color crRB(eType == FWLTHEME_EDGE_Raised ? cr1 : cr3);
327     pGraphics->SetFillColor(&crRB);
328     CFX_Path pathRB;
329     pathRB.Create();
330     pathRB.MoveTo(fRight - fHalfWidth, fTop + fHalfWidth);
331     pathRB.LineTo(fRight - fHalfWidth, fBottom - fHalfWidth);
332     pathRB.LineTo(fLeft + fHalfWidth, fBottom - fHalfWidth);
333     pathRB.LineTo(fLeft + fHalfWidth, fBottom - fWidth);
334     pathRB.LineTo(fRight - fWidth, fBottom - fWidth);
335     pathRB.LineTo(fRight - fWidth, fTop + fHalfWidth);
336     pathRB.LineTo(fRight - fHalfWidth, fTop + fHalfWidth);
337     pGraphics->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
338     crRB = CFX_Color(eType == FWLTHEME_EDGE_Raised ? cr2 : cr4);
339     pGraphics->SetFillColor(&crRB);
340     pathRB.Clear();
341     pathRB.MoveTo(fRight, fTop);
342     pathRB.LineTo(fRight, fBottom);
343     pathRB.LineTo(fLeft, fBottom);
344     pathRB.LineTo(fLeft, fBottom - fHalfWidth);
345     pathRB.LineTo(fRight - fHalfWidth, fBottom - fHalfWidth);
346     pathRB.LineTo(fRight - fHalfWidth, fTop);
347     pathRB.LineTo(fRight, fTop);
348     pGraphics->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
349   }
350   pGraphics->RestoreGraphState();
351 }
Draw3DCircle(CFX_Graphics * pGraphics,FWLTHEME_EDGE eType,FX_FLOAT fWidth,const CFX_RectF * pRect,FX_ARGB cr1,FX_ARGB cr2,FX_ARGB cr3,FX_ARGB cr4,CFX_Matrix * pMatrix)352 void CFWL_WidgetTP::Draw3DCircle(CFX_Graphics* pGraphics,
353                                  FWLTHEME_EDGE eType,
354                                  FX_FLOAT fWidth,
355                                  const CFX_RectF* pRect,
356                                  FX_ARGB cr1,
357                                  FX_ARGB cr2,
358                                  FX_ARGB cr3,
359                                  FX_ARGB cr4,
360                                  CFX_Matrix* pMatrix) {
361   if (!pGraphics)
362     return;
363   if (!pRect)
364     return;
365   pGraphics->SaveGraphState();
366   CFX_Path path;
367   path.Create();
368   path.AddArc(pRect->left, pRect->top, pRect->width, pRect->height,
369               FWLTHEME_PI * 3 / 4, FWLTHEME_PI);
370   CFX_Color crFill1(eType == FWLTHEME_EDGE_Raised ? cr4 : cr1);
371   pGraphics->SetStrokeColor(&crFill1);
372   pGraphics->StrokePath(&path, pMatrix);
373   CFX_RectF rtInner(*pRect);
374   rtInner.Deflate(pRect->width / 4, pRect->height / 4);
375   path.Clear();
376   path.AddArc(rtInner.left, rtInner.top, rtInner.width, rtInner.height,
377               FWLTHEME_PI * 3 / 4, FWLTHEME_PI);
378   CFX_Color crFill2(eType == FWLTHEME_EDGE_Raised ? cr3 : cr2);
379   pGraphics->SetStrokeColor(&crFill2);
380   pGraphics->StrokePath(&path, pMatrix);
381   path.Clear();
382   path.AddArc(pRect->left, pRect->top, pRect->width, pRect->height,
383               FWLTHEME_PI * 7 / 4, FWLTHEME_PI);
384   CFX_Color crFill3(eType == FWLTHEME_EDGE_Raised ? cr1 : cr3);
385   pGraphics->SetStrokeColor(&crFill3);
386   pGraphics->StrokePath(&path, pMatrix);
387   path.AddArc(rtInner.left, rtInner.top, rtInner.width, rtInner.height,
388               FWLTHEME_PI * 7 / 4, FWLTHEME_PI);
389   CFX_Color crFill4(eType == FWLTHEME_EDGE_Raised ? cr2 : cr4);
390   pGraphics->SetStrokeColor(&crFill4);
391   pGraphics->StrokePath(&path, pMatrix);
392   pGraphics->RestoreGraphState();
393 }
DrawBorder(CFX_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)394 void CFWL_WidgetTP::DrawBorder(CFX_Graphics* pGraphics,
395                                const CFX_RectF* pRect,
396                                CFX_Matrix* pMatrix) {
397   if (!pGraphics)
398     return;
399   if (!pRect)
400     return;
401   CFX_Path path;
402   path.Create();
403   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
404   path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
405                     pRect->height - 2);
406   pGraphics->SaveGraphState();
407   CFX_Color crFill(ArgbEncode(255, 0, 0, 0));
408   pGraphics->SetFillColor(&crFill);
409   pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
410   pGraphics->RestoreGraphState();
411 }
FillBackground(CFX_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)412 void CFWL_WidgetTP::FillBackground(CFX_Graphics* pGraphics,
413                                    const CFX_RectF* pRect,
414                                    CFX_Matrix* pMatrix) {
415   FillSoildRect(pGraphics, FWLTHEME_COLOR_Background, pRect, pMatrix);
416 }
FillSoildRect(CFX_Graphics * pGraphics,FX_ARGB fillColor,const CFX_RectF * pRect,CFX_Matrix * pMatrix)417 void CFWL_WidgetTP::FillSoildRect(CFX_Graphics* pGraphics,
418                                   FX_ARGB fillColor,
419                                   const CFX_RectF* pRect,
420                                   CFX_Matrix* pMatrix) {
421   if (!pGraphics)
422     return;
423   if (!pRect)
424     return;
425   pGraphics->SaveGraphState();
426   CFX_Color crFill(fillColor);
427   pGraphics->SetFillColor(&crFill);
428   CFX_Path path;
429   path.Create();
430   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
431   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
432   pGraphics->RestoreGraphState();
433 }
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)434 void CFWL_WidgetTP::DrawAxialShading(CFX_Graphics* pGraphics,
435                                      FX_FLOAT fx1,
436                                      FX_FLOAT fy1,
437                                      FX_FLOAT fx2,
438                                      FX_FLOAT fy2,
439                                      FX_ARGB beginColor,
440                                      FX_ARGB endColor,
441                                      CFX_Path* path,
442                                      int32_t fillMode,
443                                      CFX_Matrix* pMatrix) {
444   if (!pGraphics)
445     return;
446   if (!path)
447     return;
448   CFX_PointF begPoint, endPoint;
449   begPoint.Set(fx1, fy1);
450   endPoint.Set(fx2, fy2);
451   CFX_Shading shading;
452   shading.CreateAxial(begPoint, endPoint, FALSE, FALSE, beginColor, endColor);
453   pGraphics->SaveGraphState();
454   CFX_Color color1(&shading);
455   pGraphics->SetFillColor(&color1);
456   pGraphics->FillPath(path, fillMode, pMatrix);
457   pGraphics->RestoreGraphState();
458 }
DrawAnnulusRect(CFX_Graphics * pGraphics,FX_ARGB fillColor,const CFX_RectF * pRect,FX_FLOAT fRingWidth,CFX_Matrix * pMatrix)459 void CFWL_WidgetTP::DrawAnnulusRect(CFX_Graphics* pGraphics,
460                                     FX_ARGB fillColor,
461                                     const CFX_RectF* pRect,
462                                     FX_FLOAT fRingWidth,
463                                     CFX_Matrix* pMatrix) {
464   if (!pGraphics)
465     return;
466   if (!pRect)
467     return;
468   pGraphics->SaveGraphState();
469   CFX_Color cr(fillColor);
470   pGraphics->SetFillColor(&cr);
471   CFX_Path path;
472   path.Create();
473   CFX_RectF rtInner(*pRect);
474   rtInner.Deflate(fRingWidth, fRingWidth);
475   path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
476   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
477   pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
478   pGraphics->RestoreGraphState();
479 }
DrawAnnulusCircle(CFX_Graphics * pGraphics,FX_ARGB fillColor,const CFX_RectF * pRect,FX_FLOAT fWidth,CFX_Matrix * pMatrix)480 void CFWL_WidgetTP::DrawAnnulusCircle(CFX_Graphics* pGraphics,
481                                       FX_ARGB fillColor,
482                                       const CFX_RectF* pRect,
483                                       FX_FLOAT fWidth,
484                                       CFX_Matrix* pMatrix) {
485   if (!pGraphics)
486     return;
487   if (!pRect)
488     return;
489   if (fWidth > pRect->width / 2) {
490     return;
491   }
492   pGraphics->SaveGraphState();
493   CFX_Color cr(fillColor);
494   pGraphics->SetFillColor(&cr);
495   CFX_Path path;
496   path.Create();
497   path.AddEllipse(*pRect);
498   CFX_RectF rtIn(*pRect);
499   rtIn.Inflate(-fWidth, -fWidth);
500   path.AddEllipse(rtIn);
501   pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
502   pGraphics->RestoreGraphState();
503 }
DrawFocus(CFX_Graphics * pGraphics,const CFX_RectF * pRect,CFX_Matrix * pMatrix)504 void CFWL_WidgetTP::DrawFocus(CFX_Graphics* pGraphics,
505                               const CFX_RectF* pRect,
506                               CFX_Matrix* pMatrix) {
507   if (!pGraphics)
508     return;
509   if (!pRect)
510     return;
511   pGraphics->SaveGraphState();
512   CFX_Color cr(0xFF000000);
513   pGraphics->SetStrokeColor(&cr);
514   FX_FLOAT DashPattern[2] = {1, 1};
515   pGraphics->SetLineDash(0.0f, DashPattern, 2);
516   CFX_Path path;
517   path.Create();
518   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
519   pGraphics->StrokePath(&path, pMatrix);
520   pGraphics->RestoreGraphState();
521 }
522 #define FWLTHEME_ARROW_Denominator 3
DrawArrow(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FX_ARGB argbFill,FX_BOOL bPressed,CFX_Matrix * pMatrix)523 void CFWL_WidgetTP::DrawArrow(CFX_Graphics* pGraphics,
524                               const CFX_RectF* pRect,
525                               FWLTHEME_DIRECTION eDict,
526                               FX_ARGB argbFill,
527                               FX_BOOL bPressed,
528                               CFX_Matrix* pMatrix) {
529   CFX_RectF rtArrow(*pRect);
530   CFX_Path path;
531   path.Create();
532   FX_FLOAT fBtn =
533       std::min(pRect->width, pRect->height) / FWLTHEME_ARROW_Denominator;
534   rtArrow.left = pRect->left + (pRect->width - fBtn) / 2;
535   rtArrow.top = pRect->top + (pRect->height - fBtn) / 2;
536   rtArrow.width = fBtn;
537   rtArrow.height = fBtn;
538   if (bPressed) {
539     rtArrow.Offset(1, 1);
540   }
541   switch (eDict) {
542     case FWLTHEME_DIRECTION_Up: {
543       path.MoveTo(rtArrow.left, rtArrow.bottom());
544       path.LineTo(rtArrow.right(), rtArrow.bottom());
545       path.LineTo(rtArrow.left + fBtn / 2, rtArrow.top);
546       path.LineTo(rtArrow.left, rtArrow.bottom());
547       break;
548     }
549     case FWLTHEME_DIRECTION_Left: {
550       path.MoveTo(rtArrow.right(), rtArrow.top);
551       path.LineTo(rtArrow.right(), rtArrow.bottom());
552       path.LineTo(rtArrow.left, rtArrow.top + fBtn / 2);
553       path.LineTo(rtArrow.right(), rtArrow.top);
554       break;
555     }
556     case FWLTHEME_DIRECTION_Right: {
557       path.MoveTo(rtArrow.left, rtArrow.top);
558       path.LineTo(rtArrow.left, rtArrow.bottom());
559       path.LineTo(rtArrow.right(), rtArrow.top + fBtn / 2);
560       path.LineTo(rtArrow.left, rtArrow.top);
561       break;
562     }
563     case FWLTHEME_DIRECTION_Down:
564     default: {
565       path.MoveTo(rtArrow.left, rtArrow.top);
566       path.LineTo(rtArrow.right(), rtArrow.top);
567       path.LineTo(rtArrow.left + fBtn / 2, rtArrow.bottom());
568       path.LineTo(rtArrow.left, rtArrow.top);
569     }
570   }
571   pGraphics->SaveGraphState();
572   CFX_Color cr(argbFill);
573   pGraphics->SetFillColor(&cr);
574   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
575   pGraphics->RestoreGraphState();
576 }
DrawArrow(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FX_ARGB argSign,CFX_Matrix * pMatrix)577 void CFWL_WidgetTP::DrawArrow(CFX_Graphics* pGraphics,
578                               const CFX_RectF* pRect,
579                               FWLTHEME_DIRECTION eDict,
580                               FX_ARGB argSign,
581                               CFX_Matrix* pMatrix) {
582   FX_BOOL bVert =
583       (eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down);
584   FX_FLOAT fLeft =
585       (FX_FLOAT)(((pRect->width - (bVert ? 9 : 6)) / 2 + pRect->left) + 0.5);
586   FX_FLOAT fTop =
587       (FX_FLOAT)(((pRect->height - (bVert ? 6 : 9)) / 2 + pRect->top) + 0.5);
588   CFX_Path path;
589   path.Create();
590   switch (eDict) {
591     case FWLTHEME_DIRECTION_Down: {
592       path.MoveTo(fLeft, fTop + 1);
593       path.LineTo(fLeft + 4, fTop + 5);
594       path.LineTo(fLeft + 8, fTop + 1);
595       path.LineTo(fLeft + 7, fTop);
596       path.LineTo(fLeft + 4, fTop + 3);
597       path.LineTo(fLeft + 1, fTop);
598       break;
599     }
600     case FWLTHEME_DIRECTION_Up: {
601       path.MoveTo(fLeft, fTop + 4);
602       path.LineTo(fLeft + 4, fTop);
603       path.LineTo(fLeft + 8, fTop + 4);
604       path.LineTo(fLeft + 7, fTop + 5);
605       path.LineTo(fLeft + 4, fTop + 2);
606       path.LineTo(fLeft + 1, fTop + 5);
607       break;
608     }
609     case FWLTHEME_DIRECTION_Right: {
610       path.MoveTo(fLeft + 1, fTop);
611       path.LineTo(fLeft + 5, fTop + 4);
612       path.LineTo(fLeft + 1, fTop + 8);
613       path.LineTo(fLeft, fTop + 7);
614       path.LineTo(fLeft + 3, fTop + 4);
615       path.LineTo(fLeft, fTop + 1);
616       break;
617     }
618     case FWLTHEME_DIRECTION_Left: {
619       path.MoveTo(fLeft, fTop + 4);
620       path.LineTo(fLeft + 4, fTop);
621       path.LineTo(fLeft + 5, fTop + 1);
622       path.LineTo(fLeft + 2, fTop + 4);
623       path.LineTo(fLeft + 5, fTop + 7);
624       path.LineTo(fLeft + 4, fTop + 8);
625       break;
626     }
627   }
628   CFX_Color cr(argSign);
629   pGraphics->SetFillColor(&cr);
630   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
631 }
DrawBtn(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)632 void CFWL_WidgetTP::DrawBtn(CFX_Graphics* pGraphics,
633                             const CFX_RectF* pRect,
634                             FWLTHEME_STATE eState,
635                             CFX_Matrix* pMatrix) {
636   CFX_Path path;
637   path.Create();
638   if (!CFWL_ArrowData::IsInstance()) {
639     CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(m_dwThemeID));
640   }
641   CFWL_ArrowData::CColorData* pColorData =
642       CFWL_ArrowData::GetInstance()->m_pColorData;
643   FX_FLOAT fRight = pRect->right();
644   FX_FLOAT fBottom = pRect->bottom();
645   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
646   DrawAxialShading(pGraphics, pRect->left, pRect->top, fRight, fBottom,
647                    pColorData->clrStart[eState - 1],
648                    pColorData->clrEnd[eState - 1], &path, FXFILL_WINDING,
649                    pMatrix);
650   CFX_Color rcStroke;
651   rcStroke.Set(pColorData->clrBorder[eState - 1]);
652   pGraphics->SetStrokeColor(&rcStroke);
653   pGraphics->StrokePath(&path, pMatrix);
654 }
DrawArrowBtn(CFX_Graphics * pGraphics,const CFX_RectF * pRect,FWLTHEME_DIRECTION eDict,FWLTHEME_STATE eState,CFX_Matrix * pMatrix)655 void CFWL_WidgetTP::DrawArrowBtn(CFX_Graphics* pGraphics,
656                                  const CFX_RectF* pRect,
657                                  FWLTHEME_DIRECTION eDict,
658                                  FWLTHEME_STATE eState,
659                                  CFX_Matrix* pMatrix) {
660   DrawBtn(pGraphics, pRect, eState, pMatrix);
661   if (!CFWL_ArrowData::IsInstance()) {
662     CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(m_dwThemeID));
663   }
664   CFWL_ArrowData::CColorData* pColorData =
665       CFWL_ArrowData::GetInstance()->m_pColorData;
666   DrawArrow(pGraphics, pRect, eDict, pColorData->clrSign[eState - 1], pMatrix);
667 }
BlendColor(FWLCOLOR srcColor,FWLCOLOR renderColor,uint8_t scale)668 FWLCOLOR CFWL_WidgetTP::BlendColor(FWLCOLOR srcColor,
669                                    FWLCOLOR renderColor,
670                                    uint8_t scale) {
671   FWLCOLOR dstColor;
672   uint8_t n = 255 - scale;
673   dstColor.a = (uint8_t)(
674       ((FX_WORD)srcColor.a * n + (FX_WORD)renderColor.a * scale) >> 8);
675   dstColor.r = (uint8_t)(
676       ((FX_WORD)srcColor.r * n + (FX_WORD)renderColor.r * scale) >> 8);
677   dstColor.g = (uint8_t)(
678       ((FX_WORD)srcColor.g * n + (FX_WORD)renderColor.g * scale) >> 8);
679   dstColor.b = (uint8_t)(
680       ((FX_WORD)srcColor.b * n + (FX_WORD)renderColor.b * scale) >> 8);
681   return dstColor;
682 }
CFWL_ArrowData()683 CFWL_ArrowData::CFWL_ArrowData() : m_pColorData(NULL) {
684   SetColorData(0);
685 }
FWL_GetFontManager()686 CFWL_FontManager* FWL_GetFontManager() {
687   static CFWL_FontManager* _fontManager = NULL;
688   if (_fontManager == NULL) {
689     _fontManager = new CFWL_FontManager;
690   }
691   return _fontManager;
692 }
FWL_ReleaseFontManager()693 void FWL_ReleaseFontManager() {
694   CFWL_FontManager* fontManager = FWL_GetFontManager();
695   delete fontManager;
696 }
CFWL_FontData()697 CFWL_FontData::CFWL_FontData()
698     : m_dwStyles(0),
699       m_dwCodePage(0),
700       m_pFont(0),
701       m_pFontMgr(NULL)
702 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
703       ,
704       m_pFontSource(NULL)
705 #endif
706 {
707 }
~CFWL_FontData()708 CFWL_FontData::~CFWL_FontData() {
709   if (m_pFont) {
710     m_pFont->Release();
711   }
712   if (m_pFontMgr) {
713     m_pFontMgr->Release();
714   }
715 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
716   if (m_pFontSource != NULL) {
717     m_pFontSource->Release();
718   }
719 #endif
720 }
Equal(const CFX_WideStringC & wsFontFamily,FX_DWORD dwFontStyles,FX_WORD wCodePage)721 FX_BOOL CFWL_FontData::Equal(const CFX_WideStringC& wsFontFamily,
722                              FX_DWORD dwFontStyles,
723                              FX_WORD wCodePage) {
724   return m_wsFamily == wsFontFamily && m_dwStyles == dwFontStyles &&
725          m_dwCodePage == wCodePage;
726 }
LoadFont(const CFX_WideStringC & wsFontFamily,FX_DWORD dwFontStyles,FX_WORD dwCodePage)727 FX_BOOL CFWL_FontData::LoadFont(const CFX_WideStringC& wsFontFamily,
728                                 FX_DWORD dwFontStyles,
729                                 FX_WORD dwCodePage) {
730   m_wsFamily = wsFontFamily;
731   m_dwStyles = dwFontStyles;
732   m_dwCodePage = dwCodePage;
733   if (!m_pFontMgr) {
734 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
735     m_pFontMgr = IFX_FontMgr::Create(FX_GetDefFontEnumerator());
736 #else
737     m_pFontSource = FX_CreateDefaultFontSourceEnum();
738     m_pFontMgr = IFX_FontMgr::Create(m_pFontSource);
739 #endif
740   }
741   m_pFont = IFX_Font::LoadFont(wsFontFamily.GetPtr(), dwFontStyles, dwCodePage,
742                                m_pFontMgr);
743   return m_pFont != NULL;
744 }
CFWL_FontManager()745 CFWL_FontManager::CFWL_FontManager() {}
~CFWL_FontManager()746 CFWL_FontManager::~CFWL_FontManager() {
747   for (int32_t i = 0; i < m_arrFonts.GetSize(); i++) {
748     delete static_cast<CFWL_FontData*>(m_arrFonts[i]);
749   }
750   m_arrFonts.RemoveAll();
751 }
FindFont(const CFX_WideStringC & wsFontFamily,FX_DWORD dwFontStyles,FX_WORD wCodePage)752 IFX_Font* CFWL_FontManager::FindFont(const CFX_WideStringC& wsFontFamily,
753                                      FX_DWORD dwFontStyles,
754                                      FX_WORD wCodePage) {
755   for (int32_t i = 0; i < m_arrFonts.GetSize(); i++) {
756     CFWL_FontData* data = static_cast<CFWL_FontData*>(m_arrFonts[i]);
757     if (data->Equal(wsFontFamily, dwFontStyles, wCodePage)) {
758       return data->GetFont();
759     }
760   }
761   CFWL_FontData* fontData = new CFWL_FontData;
762   if (!fontData->LoadFont(wsFontFamily, dwFontStyles, wCodePage)) {
763     delete fontData;
764     return NULL;
765   }
766   m_arrFonts.Add(fontData);
767   return fontData->GetFont();
768 }
FWLTHEME_Init()769 FX_BOOL FWLTHEME_Init() {
770   return TRUE;
771 }
FWLTHEME_Release()772 void FWLTHEME_Release() {
773   CFWL_ArrowData::DestroyInstance();
774   FWL_ReleaseFontManager();
775 }
FWL_GetThemeLayout(FX_DWORD dwThemeID)776 FX_DWORD FWL_GetThemeLayout(FX_DWORD dwThemeID) {
777   return 0xffff0000 & dwThemeID;
778 }
FWL_GetThemeColor(FX_DWORD dwThemeID)779 FX_DWORD FWL_GetThemeColor(FX_DWORD dwThemeID) {
780   return 0x0000ffff & dwThemeID;
781 }
FWL_MakeThemeID(FX_DWORD dwLayout,FX_DWORD dwColor)782 FX_DWORD FWL_MakeThemeID(FX_DWORD dwLayout, FX_DWORD dwColor) {
783   return (dwLayout << 16) | (0x0000FFFF & dwColor);
784 }
785 CFWL_ArrowData* CFWL_ArrowData::m_pInstance = NULL;
GetInstance()786 CFWL_ArrowData* CFWL_ArrowData::GetInstance() {
787   if (!m_pInstance) {
788     m_pInstance = new CFWL_ArrowData;
789   }
790   return m_pInstance;
791 }
IsInstance()792 FX_BOOL CFWL_ArrowData::IsInstance() {
793   return (m_pInstance != NULL);
794 }
DestroyInstance()795 void CFWL_ArrowData::DestroyInstance() {
796   if (m_pInstance) {
797     delete m_pInstance;
798     m_pInstance = NULL;
799   }
800 }
~CFWL_ArrowData()801 CFWL_ArrowData::~CFWL_ArrowData() {
802   if (m_pColorData) {
803     delete m_pColorData;
804     m_pColorData = NULL;
805   }
806 }
SetColorData(FX_DWORD dwID)807 void CFWL_ArrowData::SetColorData(FX_DWORD dwID) {
808   if (!m_pColorData) {
809     m_pColorData = new CColorData;
810   }
811   if (dwID) {
812     m_pColorData->clrBorder[0] = ArgbEncode(255, 142, 153, 125);
813     m_pColorData->clrBorder[1] = ArgbEncode(255, 157, 171, 119);
814     m_pColorData->clrBorder[2] = ArgbEncode(255, 118, 131, 97);
815     m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
816     m_pColorData->clrStart[0] = ArgbEncode(255, 203, 215, 186);
817     m_pColorData->clrStart[1] = ArgbEncode(255, 218, 232, 185);
818     m_pColorData->clrStart[2] = ArgbEncode(255, 203, 215, 186);
819     m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
820     m_pColorData->clrEnd[0] = ArgbEncode(255, 149, 167, 117);
821     m_pColorData->clrEnd[1] = ArgbEncode(255, 198, 211, 155);
822     m_pColorData->clrEnd[2] = ArgbEncode(255, 149, 167, 117);
823     m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
824     m_pColorData->clrSign[0] = ArgbEncode(255, 255, 255, 255);
825     m_pColorData->clrSign[1] = ArgbEncode(255, 255, 255, 255);
826     m_pColorData->clrSign[2] = ArgbEncode(255, 255, 255, 255);
827     m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
828   } else {
829     m_pColorData->clrBorder[0] = ArgbEncode(255, 202, 216, 249);
830     m_pColorData->clrBorder[1] = ArgbEncode(255, 171, 190, 233);
831     m_pColorData->clrBorder[2] = ArgbEncode(255, 135, 147, 219);
832     m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
833     m_pColorData->clrStart[0] = ArgbEncode(255, 225, 234, 254);
834     m_pColorData->clrStart[1] = ArgbEncode(255, 253, 255, 255);
835     m_pColorData->clrStart[2] = ArgbEncode(255, 110, 142, 241);
836     m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
837     m_pColorData->clrEnd[0] = ArgbEncode(255, 175, 204, 251);
838     m_pColorData->clrEnd[1] = ArgbEncode(255, 185, 218, 251);
839     m_pColorData->clrEnd[2] = ArgbEncode(255, 210, 222, 235);
840     m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
841     m_pColorData->clrSign[0] = ArgbEncode(255, 77, 97, 133);
842     m_pColorData->clrSign[1] = ArgbEncode(255, 77, 97, 133);
843     m_pColorData->clrSign[2] = ArgbEncode(255, 77, 97, 133);
844     m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
845   }
846 }
847