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