// Copyright 2014 PDFium Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
#include "xfa/src/foxitlib.h" | |
#include "xfa/src/fxfa/src/common/xfa_common.h" | |
#include "xfa_fwltheme.h" | |
#include "xfa_ffwidget.h" | |
#include "xfa_ffapp.h" | |
CXFA_FFWidget* XFA_ThemeGetOuterWidget(IFWL_Widget* pWidget) { | |
IFWL_Widget* pOuter = pWidget; | |
while (pOuter->GetOuter()) { | |
pOuter = pOuter->GetOuter(); | |
} | |
if (pOuter) { | |
return (CXFA_FFWidget*)pOuter->GetPrivateData(pOuter); | |
} | |
return NULL; | |
} | |
CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp) : m_pApp(pApp) { | |
m_pTextOut = NULL; | |
m_dwCapacity = 0; | |
m_fCapacity = 0; | |
m_pCalendarFont = NULL; | |
m_Rect.Set(0, 0, 0, 0); | |
m_SizeAboveBelow.Set(0, 0); | |
m_pCheckBoxTP = new CXFA_FWLCheckBoxTP; | |
m_pListBoxTP = new CFWL_ListBoxTP; | |
m_pPictureBoxTP = new CFWL_PictureBoxTP; | |
m_pSrollBarTP = new CFWL_ScrollBarTP; | |
m_pEditTP = new CXFA_FWLEditTP; | |
m_pComboBoxTP = new CFWL_ComboBoxTP; | |
m_pMonthCalendarTP = new CFWL_MonthCalendarTP; | |
m_pDateTimePickerTP = new CFWL_DateTimePickerTP; | |
m_pPushButtonTP = new CFWL_PushButtonTP; | |
m_pCaretTP = new CFWL_CaretTP; | |
m_pBarcodeTP = new CFWL_BarcodeTP; | |
Initialize(); | |
} | |
CXFA_FWLTheme::~CXFA_FWLTheme() { | |
Finalize(); | |
delete m_pCheckBoxTP; | |
delete m_pListBoxTP; | |
delete m_pPictureBoxTP; | |
delete m_pSrollBarTP; | |
delete m_pEditTP; | |
delete m_pComboBoxTP; | |
delete m_pMonthCalendarTP; | |
delete m_pDateTimePickerTP; | |
delete m_pPushButtonTP; | |
delete m_pCaretTP; | |
delete m_pBarcodeTP; | |
} | |
static const FX_WCHAR* g_FWLTheme_CalFonts[] = { | |
L"Arial", L"Courier New", L"DejaVu Sans", | |
}; | |
FWL_ERR CXFA_FWLTheme::Initialize() { | |
m_pTextOut = IFDE_TextOut::Create(); | |
for (int32_t i = 0; NULL == m_pCalendarFont && | |
i < sizeof(g_FWLTheme_CalFonts) / sizeof(const FX_WCHAR*); | |
i++) { | |
m_pCalendarFont = IFX_Font::LoadFont(g_FWLTheme_CalFonts[i], 0, 0, | |
m_pApp->GetFDEFontMgr()); | |
} | |
if (NULL == m_pCalendarFont) | |
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | |
m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetDefFontByCodePage( | |
FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL); | |
#else | |
m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage( | |
FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL); | |
#endif | |
FXSYS_assert(NULL != m_pCalendarFont); | |
FWLTHEME_Init(); | |
return FWL_ERR_Succeeded; | |
} | |
FWL_ERR CXFA_FWLTheme::Finalize() { | |
if (m_pTextOut) { | |
m_pTextOut->Release(); | |
m_pTextOut = NULL; | |
} | |
if (m_pCalendarFont) { | |
m_pCalendarFont->Release(); | |
m_pCalendarFont = NULL; | |
} | |
FWLTHEME_Release(); | |
return FWL_ERR_Succeeded; | |
} | |
FX_BOOL CXFA_FWLTheme::IsValidWidget(IFWL_Widget* pWidget) { | |
return TRUE; | |
} | |
FX_DWORD CXFA_FWLTheme::GetThemeID(IFWL_Widget* pWidget) { | |
return 0; | |
} | |
FX_DWORD CXFA_FWLTheme::SetThemeID(IFWL_Widget* pWidget, | |
FX_DWORD dwThemeID, | |
FX_BOOL bChildren) { | |
return 0; | |
} | |
FX_BOOL CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) { | |
return GetTheme(pParams->m_pWidget)->DrawBackground(pParams); | |
} | |
FX_BOOL CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) { | |
if (pParams->m_wsText.IsEmpty()) { | |
return FWL_ERR_Indefinite; | |
} | |
if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) { | |
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); | |
if (!pWidget) { | |
return FWL_ERR_Indefinite; | |
} | |
m_pTextOut->SetStyles(pParams->m_dwTTOStyles); | |
m_pTextOut->SetAlignment(pParams->m_iTTOAlign); | |
m_pTextOut->SetFont(m_pCalendarFont); | |
m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize); | |
m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor); | |
if ((pParams->m_iPart == FWL_PART_MCD_DatesIn) && | |
!(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) && | |
(pParams->m_dwStates & | |
(FWL_PARTSTATE_MCD_Hovered | FWL_PARTSTATE_MCD_Selected))) { | |
m_pTextOut->SetTextColor(0xFFFFFFFF); | |
} | |
if (pParams->m_iPart == FWL_PART_MCD_Caption) { | |
if (m_pMonthCalendarTP->GetThemeID(pParams->m_pWidget) == 0) { | |
m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255)); | |
} else { | |
m_pTextOut->SetTextColor(ArgbEncode(0xff, 128, 128, 0)); | |
} | |
} | |
CFX_Graphics* pGraphics = pParams->m_pGraphics; | |
CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice(); | |
if (!pRenderDevice) | |
return FALSE; | |
m_pTextOut->SetRenderDevice(pRenderDevice); | |
CFX_Matrix mtPart = pParams->m_matrix; | |
CFX_Matrix* pMatrix = pGraphics->GetMatrix(); | |
if (pMatrix) { | |
mtPart.Concat(*pMatrix); | |
} | |
m_pTextOut->SetMatrix(mtPart); | |
m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(), | |
pParams->m_rtPart); | |
return TRUE; | |
} | |
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); | |
if (!pWidget) { | |
return FWL_ERR_Indefinite; | |
} | |
CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc(); | |
CFX_Graphics* pGraphics = pParams->m_pGraphics; | |
CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice(); | |
if (!pRenderDevice) | |
return FALSE; | |
m_pTextOut->SetRenderDevice(pRenderDevice); | |
m_pTextOut->SetStyles(pParams->m_dwTTOStyles); | |
m_pTextOut->SetAlignment(pParams->m_iTTOAlign); | |
m_pTextOut->SetFont(pAcc->GetFDEFont()); | |
m_pTextOut->SetFontSize(pAcc->GetFontSize()); | |
m_pTextOut->SetTextColor(pAcc->GetTextColor()); | |
CFX_Matrix mtPart = pParams->m_matrix; | |
CFX_Matrix* pMatrix = pGraphics->GetMatrix(); | |
if (pMatrix) { | |
mtPart.Concat(*pMatrix); | |
} | |
m_pTextOut->SetMatrix(mtPart); | |
m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(), | |
pParams->m_rtPart); | |
return TRUE; | |
} | |
void* CXFA_FWLTheme::GetCapacity(CFWL_ThemePart* pThemePart, | |
FX_DWORD dwCapacity) { | |
switch (dwCapacity) { | |
case FWL_WGTCAPACITY_Font: { | |
if (CXFA_FFWidget* pWidget = | |
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { | |
return pWidget->GetDataAcc()->GetFDEFont(); | |
} | |
} break; | |
case FWL_WGTCAPACITY_FontSize: { | |
if (CXFA_FFWidget* pWidget = | |
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { | |
m_fCapacity = pWidget->GetDataAcc()->GetFontSize(); | |
return &m_fCapacity; | |
} | |
} break; | |
case FWL_WGTCAPACITY_TextColor: { | |
if (CXFA_FFWidget* pWidget = | |
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { | |
m_dwCapacity = pWidget->GetDataAcc()->GetTextColor(); | |
return &m_dwCapacity; | |
} | |
} break; | |
case FWL_WGTCAPACITY_LineHeight: { | |
if (CXFA_FFWidget* pWidget = | |
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { | |
m_fCapacity = pWidget->GetDataAcc()->GetLineHeight(); | |
return &m_fCapacity; | |
} | |
} break; | |
case FWL_WGTCAPACITY_ScrollBarWidth: { | |
m_fCapacity = 9; | |
return &m_fCapacity; | |
} break; | |
case FWL_WGTCAPACITY_UIMargin: { | |
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget); | |
if (pWidget) { | |
CXFA_LayoutItem* pItem = pWidget; | |
CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc(); | |
pWidgetAcc->GetUIMargin(m_Rect); | |
if (CXFA_Para para = pWidgetAcc->GetPara()) { | |
m_Rect.left += para.GetMarginLeft(); | |
if (pWidgetAcc->IsMultiLine()) { | |
m_Rect.width += para.GetMarginRight(); | |
} | |
} | |
if (pItem->GetPrev() == NULL) { | |
if (pItem->GetNext() != NULL) { | |
m_Rect.height = 0; | |
} | |
} else if (pItem->GetNext() == NULL) { | |
m_Rect.top = 0; | |
} else { | |
m_Rect.top = 0; | |
m_Rect.height = 0; | |
} | |
} | |
return &m_Rect; | |
} break; | |
case FWL_WGTCAPACITY_SpaceAboveBelow: { | |
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget); | |
if (pWidget) { | |
CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc(); | |
if (CXFA_Para para = pWidgetAcc->GetPara()) { | |
m_SizeAboveBelow.x = para.GetSpaceAbove(); | |
m_SizeAboveBelow.y = para.GetSpaceBelow(); | |
} | |
} | |
return &m_SizeAboveBelow; | |
} break; | |
default: | |
break; | |
} | |
if (pThemePart->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar && | |
dwCapacity >= FWL_MCCAPACITY_Sun && dwCapacity <= FWL_MCCAPACITY_Today) { | |
if (CXFA_FFWidget* pWidget = | |
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { | |
IXFA_AppProvider* pAppProvider = pWidget->GetAppProvider(); | |
m_wsResource.Empty(); | |
pAppProvider->LoadString( | |
XFA_IDS_StringWeekDay_Sun + dwCapacity - FWL_WGTCAPACITY_MAX - 5, | |
m_wsResource); | |
if (!m_wsResource.IsEmpty()) { | |
return &m_wsResource; | |
} | |
} | |
} | |
return GetTheme(pThemePart->m_pWidget)->GetCapacity(pThemePart, dwCapacity); | |
} | |
FX_BOOL CXFA_FWLTheme::IsCustomizedLayout(IFWL_Widget* pWidget) { | |
return GetTheme(pWidget)->IsCustomizedLayout(pWidget); | |
} | |
FWL_ERR CXFA_FWLTheme::GetPartRect(CFWL_ThemePart* pThemePart) { | |
CFX_RectF rect; | |
return GetTheme(pThemePart->m_pWidget)->GetPartRect(pThemePart, rect); | |
} | |
FX_BOOL CXFA_FWLTheme::IsInPart(CFWL_ThemePart* pThemePart, | |
FX_FLOAT fx, | |
FX_FLOAT fy) { | |
return GetTheme(pThemePart->m_pWidget)->IsInPart(pThemePart, fx, fy); | |
} | |
FX_BOOL CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) { | |
if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) { | |
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); | |
if (!pWidget) { | |
return FWL_ERR_Indefinite; | |
} | |
if (!pParams) | |
return FALSE; | |
if (!m_pTextOut) | |
return FALSE; | |
m_pTextOut->SetFont(m_pCalendarFont); | |
m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize); | |
m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor); | |
m_pTextOut->SetAlignment(pParams->m_iTTOAlign); | |
m_pTextOut->SetStyles(pParams->m_dwTTOStyles); | |
m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(), | |
rect); | |
return TRUE; | |
} | |
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); | |
if (!pWidget) { | |
return FWL_ERR_Indefinite; | |
} | |
CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc(); | |
m_pTextOut->SetFont(pAcc->GetFDEFont()); | |
m_pTextOut->SetFontSize(pAcc->GetFontSize()); | |
m_pTextOut->SetTextColor(pAcc->GetTextColor()); | |
if (!pParams) | |
return FALSE; | |
if (!m_pTextOut) | |
return FALSE; | |
m_pTextOut->SetAlignment(pParams->m_iTTOAlign); | |
m_pTextOut->SetStyles(pParams->m_dwTTOStyles); | |
m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(), | |
rect); | |
return TRUE; | |
} | |
CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(IFWL_Widget* pWidget) { | |
switch (pWidget->GetClassID()) { | |
case FWL_CLASSHASH_CheckBox: | |
return m_pCheckBoxTP; | |
case FWL_CLASSHASH_ListBox: | |
return m_pListBoxTP; | |
case FWL_CLASSHASH_PictureBox: | |
return m_pPictureBoxTP; | |
case FWL_CLASSHASH_ScrollBar: | |
return m_pSrollBarTP; | |
case FWL_CLASSHASH_Edit: | |
return m_pEditTP; | |
case FWL_CLASSHASH_ComboBox: | |
return m_pComboBoxTP; | |
case FWL_CLASSHASH_MonthCalendar: | |
return m_pMonthCalendarTP; | |
case FWL_CLASSHASH_DateTimePicker: | |
return m_pDateTimePickerTP; | |
case FWL_CLASSHASH_PushButton: | |
return m_pPushButtonTP; | |
case FWL_CLASSHASH_Caret: | |
return m_pCaretTP; | |
case FWL_CLASSHASH_Barcode: | |
return m_pBarcodeTP; | |
default: | |
break; | |
} | |
return NULL; | |
} | |
CXFA_FWLCheckBoxTP::CXFA_FWLCheckBoxTP() {} | |
FX_BOOL CXFA_FWLCheckBoxTP::DrawBackground(CFWL_ThemeBackground* pParams) { | |
if (pParams->m_iPart != FWL_PART_CKB_CheckBox) { | |
return TRUE; | |
} | |
if (((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) == | |
FWL_PARTSTATE_CKB_Checked) || | |
((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) == | |
FWL_PARTSTATE_CKB_Neutral)) { | |
DrawCheckSign(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart, | |
pParams->m_dwStates, &pParams->m_matrix); | |
} | |
return TRUE; | |
} | |
void CXFA_FWLCheckBoxTP::DrawCheckSign(IFWL_Widget* pWidget, | |
CFX_Graphics* pGraphics, | |
const CFX_RectF* pRtBox, | |
int32_t iState, | |
CFX_Matrix* pMatrix) { | |
CFX_RectF rtSign(*pRtBox); | |
FX_DWORD dwColor = 0xFF000000; | |
if ((iState & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral) { | |
dwColor = 0xFFA9A9A9; | |
} | |
{ | |
FX_DWORD dwStyle = pWidget->GetStylesEx(); | |
rtSign.Deflate(rtSign.width / 4, rtSign.height / 4); | |
switch (dwStyle & FWL_STYLEEXT_CKB_SignShapeMask) { | |
case FWL_STYLEEXT_CKB_SignShapeCheck: | |
DrawSignCheck(pGraphics, &rtSign, dwColor, pMatrix); | |
break; | |
case FWL_STYLEEXT_CKB_SignShapeCircle: | |
DrawSignCircle(pGraphics, &rtSign, dwColor, pMatrix); | |
break; | |
case FWL_STYLEEXT_CKB_SignShapeCross: | |
DrawSignCross(pGraphics, &rtSign, dwColor, pMatrix); | |
break; | |
case FWL_STYLEEXT_CKB_SignShapeDiamond: | |
DrawSignDiamond(pGraphics, &rtSign, dwColor, pMatrix); | |
break; | |
case FWL_STYLEEXT_CKB_SignShapeSquare: | |
DrawSignSquare(pGraphics, &rtSign, dwColor, pMatrix); | |
break; | |
case FWL_STYLEEXT_CKB_SignShapeStar: | |
DrawSignStar(pGraphics, &rtSign, dwColor, pMatrix); | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
CXFA_FWLEditTP::CXFA_FWLEditTP() {} | |
CXFA_FWLEditTP::~CXFA_FWLEditTP() {} | |
FX_BOOL CXFA_FWLEditTP::DrawBackground(CFWL_ThemeBackground* pParams) { | |
if (FWL_PART_EDT_CombTextLine == pParams->m_iPart) { | |
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); | |
FX_ARGB cr = 0xFF000000; | |
FX_FLOAT fWidth = 1.0f; | |
if (CXFA_Border borderUI = pWidget->GetDataAcc()->GetUIBorder()) { | |
CXFA_Edge edge = borderUI.GetEdge(0); | |
if (edge) { | |
cr = edge.GetColor(); | |
fWidth = edge.GetThickness(); | |
} | |
} | |
CFX_Color crLine(cr); | |
pParams->m_pGraphics->SetStrokeColor(&crLine); | |
pParams->m_pGraphics->SetLineWidth(fWidth); | |
pParams->m_pGraphics->StrokePath(pParams->m_pPath, &pParams->m_matrix); | |
return TRUE; | |
} | |
return CFWL_EditTP::DrawBackground(pParams); | |
} |