blob: 45dca4d572f9d5c2ca2fcb6e4f80978576929dd8 [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/fxfa/app/xfa_fwltheme.h"
#include "xfa/fde/tto/fde_textout.h"
#include "xfa/fgas/crt/fgas_codepage.h"
#include "xfa/fgas/font/fgas_gefont.h"
#include "xfa/fwl/core/cfwl_themebackground.h"
#include "xfa/fwl/core/cfwl_themetext.h"
#include "xfa/fwl/core/ifwl_barcode.h"
#include "xfa/fwl/core/ifwl_caret.h"
#include "xfa/fwl/core/ifwl_checkbox.h"
#include "xfa/fwl/core/ifwl_combobox.h"
#include "xfa/fwl/core/ifwl_datetimepicker.h"
#include "xfa/fwl/core/ifwl_edit.h"
#include "xfa/fwl/core/ifwl_listbox.h"
#include "xfa/fwl/core/ifwl_monthcalendar.h"
#include "xfa/fwl/core/ifwl_picturebox.h"
#include "xfa/fwl/core/ifwl_pushbutton.h"
#include "xfa/fwl/core/ifwl_scrollbar.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffwidget.h"
#include "xfa/fxgraphics/cfx_color.h"
namespace {
const FX_WCHAR* const g_FWLTheme_CalFonts[] = {
L"Arial", L"Courier New", L"DejaVu Sans",
};
} // namespace
CXFA_FFWidget* XFA_ThemeGetOuterWidget(IFWL_Widget* pWidget) {
IFWL_Widget* pOuter = pWidget;
while (pOuter && pOuter->GetOuter())
pOuter = pOuter->GetOuter();
return pOuter ? static_cast<CXFA_FFWidget*>(pOuter->GetLayoutItem())
: nullptr;
}
CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp)
: m_pCheckBoxTP(new CFWL_CheckBoxTP),
m_pListBoxTP(new CFWL_ListBoxTP),
m_pPictureBoxTP(new CFWL_PictureBoxTP),
m_pSrollBarTP(new CFWL_ScrollBarTP),
m_pEditTP(new CFWL_EditTP),
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),
m_fCapacity(0.0f),
m_dwCapacity(0),
m_pCalendarFont(nullptr),
m_pApp(pApp) {
m_Rect.Reset();
Initialize();
}
CXFA_FWLTheme::~CXFA_FWLTheme() {
Finalize();
}
FWL_Error CXFA_FWLTheme::Initialize() {
m_pTextOut.reset(new CFDE_TextOut);
for (size_t i = 0; !m_pCalendarFont && i < FX_ArraySize(g_FWLTheme_CalFonts);
++i) {
m_pCalendarFont = CFGAS_GEFont::LoadFont(g_FWLTheme_CalFonts[i], 0, 0,
m_pApp->GetFDEFontMgr());
}
if (!m_pCalendarFont) {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetDefFontByCodePage(
FX_CODEPAGE_MSWin_WesternEuropean, 0, nullptr);
#else
m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage(
FX_CODEPAGE_MSWin_WesternEuropean, 0, nullptr);
#endif
}
ASSERT(m_pCalendarFont);
return FWL_Error::Succeeded;
}
FWL_Error CXFA_FWLTheme::Finalize() {
m_pTextOut.reset();
if (m_pCalendarFont) {
m_pCalendarFont->Release();
m_pCalendarFont = nullptr;
}
FWLTHEME_Release();
return FWL_Error::Succeeded;
}
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 FALSE;
if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) {
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
if (!pWidget)
return FALSE;
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 == CFWL_Part::DatesIn) &&
!(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) &&
(pParams->m_dwStates &
(CFWL_PartState_Hovered | CFWL_PartState_Selected))) {
m_pTextOut->SetTextColor(0xFFFFFFFF);
}
if (pParams->m_iPart == CFWL_Part::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.c_str(),
pParams->m_wsText.GetLength(), pParams->m_rtPart);
return TRUE;
}
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
if (!pWidget)
return FALSE;
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.c_str(),
pParams->m_wsText.GetLength(), pParams->m_rtPart);
return TRUE;
}
void* CXFA_FWLTheme::GetCapacity(CFWL_ThemePart* pThemePart,
CFWL_WidgetCapacity dwCapacity) {
switch (dwCapacity) {
case CFWL_WidgetCapacity::Font: {
if (CXFA_FFWidget* pWidget =
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
return pWidget->GetDataAcc()->GetFDEFont();
}
} break;
case CFWL_WidgetCapacity::FontSize: {
if (CXFA_FFWidget* pWidget =
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
m_fCapacity = pWidget->GetDataAcc()->GetFontSize();
return &m_fCapacity;
}
} break;
case CFWL_WidgetCapacity::TextColor: {
if (CXFA_FFWidget* pWidget =
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
m_dwCapacity = pWidget->GetDataAcc()->GetTextColor();
return &m_dwCapacity;
}
} break;
case CFWL_WidgetCapacity::LineHeight: {
if (CXFA_FFWidget* pWidget =
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
m_fCapacity = pWidget->GetDataAcc()->GetLineHeight();
return &m_fCapacity;
}
} break;
case CFWL_WidgetCapacity::ScrollBarWidth: {
m_fCapacity = 9;
return &m_fCapacity;
} break;
case CFWL_WidgetCapacity::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()) {
if (pItem->GetNext()) {
m_Rect.height = 0;
}
} else if (!pItem->GetNext()) {
m_Rect.top = 0;
} else {
m_Rect.top = 0;
m_Rect.height = 0;
}
}
return &m_Rect;
} break;
case CFWL_WidgetCapacity::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;
}
int dwCapValue = static_cast<int>(dwCapacity);
if (pThemePart->m_pWidget->GetClassID() == FWL_Type::MonthCalendar &&
dwCapValue >= static_cast<int>(CFWL_WidgetCapacity::Today) &&
dwCapValue <= static_cast<int>(CFWL_WidgetCapacity::December)) {
if (CXFA_FFWidget* pWidget =
XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
IXFA_AppProvider* pAppProvider = pWidget->GetAppProvider();
m_wsResource.clear();
switch (dwCapacity) {
case CFWL_WidgetCapacity::Sun:
pAppProvider->LoadString(XFA_IDS_StringWeekDay_Sun, m_wsResource);
break;
case CFWL_WidgetCapacity::Mon:
pAppProvider->LoadString(XFA_IDS_StringWeekDay_Mon, m_wsResource);
break;
case CFWL_WidgetCapacity::Tue:
pAppProvider->LoadString(XFA_IDS_StringWeekDay_Tue, m_wsResource);
break;
case CFWL_WidgetCapacity::Wed:
pAppProvider->LoadString(XFA_IDS_StringWeekDay_Wed, m_wsResource);
break;
case CFWL_WidgetCapacity::Thu:
pAppProvider->LoadString(XFA_IDS_StringWeekDay_Thu, m_wsResource);
break;
case CFWL_WidgetCapacity::Fri:
pAppProvider->LoadString(XFA_IDS_StringWeekDay_Fri, m_wsResource);
break;
case CFWL_WidgetCapacity::Sat:
pAppProvider->LoadString(XFA_IDS_StringWeekDay_Sat, m_wsResource);
break;
case CFWL_WidgetCapacity::January:
pAppProvider->LoadString(XFA_IDS_StringMonth_Jan, m_wsResource);
break;
case CFWL_WidgetCapacity::February:
pAppProvider->LoadString(XFA_IDS_StringMonth_Feb, m_wsResource);
break;
case CFWL_WidgetCapacity::March:
pAppProvider->LoadString(XFA_IDS_StringMonth_March, m_wsResource);
break;
case CFWL_WidgetCapacity::April:
pAppProvider->LoadString(XFA_IDS_StringMonth_April, m_wsResource);
break;
case CFWL_WidgetCapacity::May:
pAppProvider->LoadString(XFA_IDS_StringMonth_May, m_wsResource);
break;
case CFWL_WidgetCapacity::June:
pAppProvider->LoadString(XFA_IDS_StringMonth_June, m_wsResource);
break;
case CFWL_WidgetCapacity::July:
pAppProvider->LoadString(XFA_IDS_StringMonth_July, m_wsResource);
break;
case CFWL_WidgetCapacity::August:
pAppProvider->LoadString(XFA_IDS_StringMonth_Aug, m_wsResource);
break;
case CFWL_WidgetCapacity::September:
pAppProvider->LoadString(XFA_IDS_StringMonth_Sept, m_wsResource);
break;
case CFWL_WidgetCapacity::October:
pAppProvider->LoadString(XFA_IDS_StringMonth_Oct, m_wsResource);
break;
case CFWL_WidgetCapacity::November:
pAppProvider->LoadString(XFA_IDS_StringMonth_Nov, m_wsResource);
break;
case CFWL_WidgetCapacity::December:
pAppProvider->LoadString(XFA_IDS_StringMonth_Dec, m_wsResource);
break;
case CFWL_WidgetCapacity::Today:
pAppProvider->LoadString(XFA_IDS_String_Today, m_wsResource);
break;
default:
break;
}
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);
}
FX_BOOL CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) {
if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) {
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
if (!pWidget)
return FALSE;
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.c_str(),
pParams->m_wsText.GetLength(), rect);
return TRUE;
}
CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
if (!pWidget)
return FALSE;
CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
m_pTextOut->SetFont(pAcc->GetFDEFont());
m_pTextOut->SetFontSize(pAcc->GetFontSize());
m_pTextOut->SetTextColor(pAcc->GetTextColor());
if (!pParams)
return FALSE;
m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
m_pTextOut->CalcLogicSize(pParams->m_wsText.c_str(),
pParams->m_wsText.GetLength(), rect);
return TRUE;
}
CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(IFWL_Widget* pWidget) {
switch (pWidget->GetClassID()) {
case FWL_Type::CheckBox:
return m_pCheckBoxTP.get();
case FWL_Type::ListBox:
return m_pListBoxTP.get();
case FWL_Type::PictureBox:
return m_pPictureBoxTP.get();
case FWL_Type::ScrollBar:
return m_pSrollBarTP.get();
case FWL_Type::Edit:
return m_pEditTP.get();
case FWL_Type::ComboBox:
return m_pComboBoxTP.get();
case FWL_Type::MonthCalendar:
return m_pMonthCalendarTP.get();
case FWL_Type::DateTimePicker:
return m_pDateTimePickerTP.get();
case FWL_Type::PushButton:
return m_pPushButtonTP.get();
case FWL_Type::Caret:
return m_pCaretTP.get();
case FWL_Type::Barcode:
return m_pBarcodeTP.get();
default:
return nullptr;
}
}