// 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/cxfa_fwltheme.h" #include "core/fxcrt/fx_codepage.h" #include "xfa/fde/cfde_textout.h" #include "xfa/fgas/font/cfgas_gefont.h" #include "xfa/fwl/cfwl_barcode.h" #include "xfa/fwl/cfwl_caret.h" #include "xfa/fwl/cfwl_checkbox.h" #include "xfa/fwl/cfwl_combobox.h" #include "xfa/fwl/cfwl_datetimepicker.h" #include "xfa/fwl/cfwl_edit.h" #include "xfa/fwl/cfwl_listbox.h" #include "xfa/fwl/cfwl_monthcalendar.h" #include "xfa/fwl/cfwl_picturebox.h" #include "xfa/fwl/cfwl_pushbutton.h" #include "xfa/fwl/cfwl_scrollbar.h" #include "xfa/fwl/cfwl_themebackground.h" #include "xfa/fwl/cfwl_themetext.h" #include "xfa/fxfa/cxfa_ffapp.h" #include "xfa/fxfa/cxfa_ffwidget.h" #include "xfa/fxfa/parser/cxfa_para.h" #include "xfa/fxgraphics/cxfa_gecolor.h" namespace { const wchar_t* const g_FWLTheme_CalFonts[] = { L"Arial", L"Courier New", L"DejaVu Sans", }; const float kLineHeight = 12.0f; } // namespace CXFA_FFWidget* XFA_ThemeGetOuterWidget(CFWL_Widget* pWidget) { CFWL_Widget* pOuter = pWidget; while (pOuter && pOuter->GetOuter()) pOuter = pOuter->GetOuter(); return pOuter ? pOuter->GetLayoutItem() : nullptr; } CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp) : m_pCheckBoxTP(pdfium::MakeUnique<CFWL_CheckBoxTP>()), m_pListBoxTP(pdfium::MakeUnique<CFWL_ListBoxTP>()), m_pPictureBoxTP(pdfium::MakeUnique<CFWL_PictureBoxTP>()), m_pSrollBarTP(pdfium::MakeUnique<CFWL_ScrollBarTP>()), m_pEditTP(pdfium::MakeUnique<CFWL_EditTP>()), m_pComboBoxTP(pdfium::MakeUnique<CFWL_ComboBoxTP>()), m_pMonthCalendarTP(pdfium::MakeUnique<CFWL_MonthCalendarTP>()), m_pDateTimePickerTP(pdfium::MakeUnique<CFWL_DateTimePickerTP>()), m_pPushButtonTP(pdfium::MakeUnique<CFWL_PushButtonTP>()), m_pCaretTP(pdfium::MakeUnique<CFWL_CaretTP>()), m_pBarcodeTP(pdfium::MakeUnique<CFWL_BarcodeTP>()), m_pTextOut(pdfium::MakeUnique<CFDE_TextOut>()), m_pCalendarFont(nullptr), m_pApp(pApp) { m_Rect.Reset(); 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) { m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage( FX_CODEPAGE_MSWin_WesternEuropean, 0, nullptr); } ASSERT(m_pCalendarFont); } CXFA_FWLTheme::~CXFA_FWLTheme() { m_pTextOut.reset(); FWLTHEME_Release(); } void CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) { GetTheme(pParams->m_pWidget)->DrawBackground(pParams); } void CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) { if (pParams->m_wsText.IsEmpty()) return; if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) { CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); if (!pWidget) return; 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) m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255)); CXFA_Graphics* pGraphics = pParams->m_pGraphics; CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice(); if (!pRenderDevice) return; CFX_Matrix mtPart = pParams->m_matrix; const CFX_Matrix* pMatrix = pGraphics->GetMatrix(); if (pMatrix) mtPart.Concat(*pMatrix); m_pTextOut->SetMatrix(mtPart); m_pTextOut->DrawLogicText(pRenderDevice, pParams->m_wsText.AsStringView(), pParams->m_rtPart); return; } CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); if (!pWidget) return; CXFA_Node* pNode = pWidget->GetNode(); CXFA_Graphics* pGraphics = pParams->m_pGraphics; CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice(); if (!pRenderDevice) return; m_pTextOut->SetStyles(pParams->m_dwTTOStyles); m_pTextOut->SetAlignment(pParams->m_iTTOAlign); m_pTextOut->SetFont(pNode->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc())); m_pTextOut->SetFontSize(pNode->GetFontSize()); m_pTextOut->SetTextColor(pNode->GetTextColor()); CFX_Matrix mtPart = pParams->m_matrix; const CFX_Matrix* pMatrix = pGraphics->GetMatrix(); if (pMatrix) mtPart.Concat(*pMatrix); m_pTextOut->SetMatrix(mtPart); m_pTextOut->DrawLogicText(pRenderDevice, pParams->m_wsText.AsStringView(), pParams->m_rtPart); } CFX_RectF CXFA_FWLTheme::GetUIMargin(CFWL_ThemePart* pThemePart) const { CFX_RectF rect; CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget); if (!pWidget) return rect; CXFA_LayoutItem* pItem = pWidget; CXFA_WidgetAcc* pWidgetAcc = pWidget->GetNode()->GetWidgetAcc(); rect = pWidgetAcc->GetUIMargin(); CXFA_Para* para = pWidgetAcc->GetNode()->GetParaIfExists(); if (para) { rect.left += para->GetMarginLeft(); if (pWidgetAcc->IsMultiLine()) rect.width += para->GetMarginRight(); } if (!pItem->GetPrev()) { if (pItem->GetNext()) rect.height = 0; } else if (!pItem->GetNext()) { rect.top = 0; } else { rect.top = 0; rect.height = 0; } return rect; } float CXFA_FWLTheme::GetCXBorderSize() const { return 1.0f; } float CXFA_FWLTheme::GetCYBorderSize() const { return 1.0f; } float CXFA_FWLTheme::GetFontSize(CFWL_ThemePart* pThemePart) const { if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) return pWidget->GetNode()->GetFontSize(); return FWLTHEME_CAPACITY_FontSize; } RetainPtr<CFGAS_GEFont> CXFA_FWLTheme::GetFont( CFWL_ThemePart* pThemePart) const { if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) return pWidget->GetNode()->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc()); return GetTheme(pThemePart->m_pWidget)->GetFont(); } float CXFA_FWLTheme::GetLineHeight(CFWL_ThemePart* pThemePart) const { if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) return pWidget->GetNode()->GetLineHeight(); return kLineHeight; } float CXFA_FWLTheme::GetScrollBarWidth() const { return 9.0f; } FX_COLORREF CXFA_FWLTheme::GetTextColor(CFWL_ThemePart* pThemePart) const { if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) return pWidget->GetNode()->GetTextColor(); return FWLTHEME_CAPACITY_TextColor; } CFX_SizeF CXFA_FWLTheme::GetSpaceAboveBelow(CFWL_ThemePart* pThemePart) const { CFX_SizeF sizeAboveBelow; if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { CXFA_Para* para = pWidget->GetNode()->GetParaIfExists(); if (para) { sizeAboveBelow.width = para->GetSpaceAbove(); sizeAboveBelow.height = para->GetSpaceBelow(); } } return sizeAboveBelow; } void 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 || !pParams || !m_pTextOut) return; 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, rect); } CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); if (!pWidget) return; CXFA_Node* pNode = pWidget->GetNode(); m_pTextOut->SetFont(pNode->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc())); m_pTextOut->SetFontSize(pNode->GetFontSize()); m_pTextOut->SetTextColor(pNode->GetTextColor()); if (!pParams) return; m_pTextOut->SetAlignment(pParams->m_iTTOAlign); m_pTextOut->SetStyles(pParams->m_dwTTOStyles); m_pTextOut->CalcLogicSize(pParams->m_wsText, rect); } CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(CFWL_Widget* pWidget) const { 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; } }