blob: 69b9e5f4814a4ac5737ece78292a7270488c2a5b [file] [log] [blame]
// 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);
}