// 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/app/xfa_ffapp.h" #include "xfa/src/fxfa/src/app/xfa_ffwidget.h" #include "xfa/src/fxfa/src/app/xfa_fwltheme.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()) { 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); }