Home | History | Annotate | Download | only in fxfa
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "xfa/fxfa/cxfa_fwltheme.h"
      8 
      9 #include "core/fxcrt/fx_codepage.h"
     10 #include "xfa/fde/cfde_textout.h"
     11 #include "xfa/fgas/font/cfgas_gefont.h"
     12 #include "xfa/fwl/cfwl_barcode.h"
     13 #include "xfa/fwl/cfwl_caret.h"
     14 #include "xfa/fwl/cfwl_checkbox.h"
     15 #include "xfa/fwl/cfwl_combobox.h"
     16 #include "xfa/fwl/cfwl_datetimepicker.h"
     17 #include "xfa/fwl/cfwl_edit.h"
     18 #include "xfa/fwl/cfwl_listbox.h"
     19 #include "xfa/fwl/cfwl_monthcalendar.h"
     20 #include "xfa/fwl/cfwl_picturebox.h"
     21 #include "xfa/fwl/cfwl_pushbutton.h"
     22 #include "xfa/fwl/cfwl_scrollbar.h"
     23 #include "xfa/fwl/cfwl_themebackground.h"
     24 #include "xfa/fwl/cfwl_themetext.h"
     25 #include "xfa/fxfa/cxfa_ffapp.h"
     26 #include "xfa/fxfa/cxfa_ffwidget.h"
     27 #include "xfa/fxfa/parser/cxfa_para.h"
     28 #include "xfa/fxgraphics/cxfa_gecolor.h"
     29 
     30 namespace {
     31 
     32 const wchar_t* const g_FWLTheme_CalFonts[] = {
     33     L"Arial", L"Courier New", L"DejaVu Sans",
     34 };
     35 
     36 const float kLineHeight = 12.0f;
     37 
     38 }  // namespace
     39 
     40 CXFA_FFWidget* XFA_ThemeGetOuterWidget(CFWL_Widget* pWidget) {
     41   CFWL_Widget* pOuter = pWidget;
     42   while (pOuter && pOuter->GetOuter())
     43     pOuter = pOuter->GetOuter();
     44   return pOuter ? pOuter->GetLayoutItem() : nullptr;
     45 }
     46 
     47 CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp)
     48     : m_pCheckBoxTP(pdfium::MakeUnique<CFWL_CheckBoxTP>()),
     49       m_pListBoxTP(pdfium::MakeUnique<CFWL_ListBoxTP>()),
     50       m_pPictureBoxTP(pdfium::MakeUnique<CFWL_PictureBoxTP>()),
     51       m_pSrollBarTP(pdfium::MakeUnique<CFWL_ScrollBarTP>()),
     52       m_pEditTP(pdfium::MakeUnique<CFWL_EditTP>()),
     53       m_pComboBoxTP(pdfium::MakeUnique<CFWL_ComboBoxTP>()),
     54       m_pMonthCalendarTP(pdfium::MakeUnique<CFWL_MonthCalendarTP>()),
     55       m_pDateTimePickerTP(pdfium::MakeUnique<CFWL_DateTimePickerTP>()),
     56       m_pPushButtonTP(pdfium::MakeUnique<CFWL_PushButtonTP>()),
     57       m_pCaretTP(pdfium::MakeUnique<CFWL_CaretTP>()),
     58       m_pBarcodeTP(pdfium::MakeUnique<CFWL_BarcodeTP>()),
     59       m_pTextOut(pdfium::MakeUnique<CFDE_TextOut>()),
     60       m_pCalendarFont(nullptr),
     61       m_pApp(pApp) {
     62   m_Rect.Reset();
     63 
     64   for (size_t i = 0; !m_pCalendarFont && i < FX_ArraySize(g_FWLTheme_CalFonts);
     65        ++i) {
     66     m_pCalendarFont = CFGAS_GEFont::LoadFont(g_FWLTheme_CalFonts[i], 0, 0,
     67                                              m_pApp->GetFDEFontMgr());
     68   }
     69   if (!m_pCalendarFont) {
     70     m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage(
     71         FX_CODEPAGE_MSWin_WesternEuropean, 0, nullptr);
     72   }
     73 
     74   ASSERT(m_pCalendarFont);
     75 }
     76 
     77 CXFA_FWLTheme::~CXFA_FWLTheme() {
     78   m_pTextOut.reset();
     79   FWLTHEME_Release();
     80 }
     81 
     82 void CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) {
     83   GetTheme(pParams->m_pWidget)->DrawBackground(pParams);
     84 }
     85 
     86 void CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) {
     87   if (pParams->m_wsText.IsEmpty())
     88     return;
     89 
     90   if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) {
     91     CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
     92     if (!pWidget)
     93       return;
     94 
     95     m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
     96     m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
     97     m_pTextOut->SetFont(m_pCalendarFont);
     98     m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
     99     m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
    100     if ((pParams->m_iPart == CFWL_Part::DatesIn) &&
    101         !(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) &&
    102         (pParams->m_dwStates &
    103          (CFWL_PartState_Hovered | CFWL_PartState_Selected))) {
    104       m_pTextOut->SetTextColor(0xFFFFFFFF);
    105     }
    106     if (pParams->m_iPart == CFWL_Part::Caption)
    107       m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255));
    108 
    109     CXFA_Graphics* pGraphics = pParams->m_pGraphics;
    110     CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
    111     if (!pRenderDevice)
    112       return;
    113 
    114     CFX_Matrix mtPart = pParams->m_matrix;
    115     const CFX_Matrix* pMatrix = pGraphics->GetMatrix();
    116     if (pMatrix)
    117       mtPart.Concat(*pMatrix);
    118 
    119     m_pTextOut->SetMatrix(mtPart);
    120     m_pTextOut->DrawLogicText(pRenderDevice, pParams->m_wsText.AsStringView(),
    121                               pParams->m_rtPart);
    122     return;
    123   }
    124   CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
    125   if (!pWidget)
    126     return;
    127 
    128   CXFA_Node* pNode = pWidget->GetNode();
    129   CXFA_Graphics* pGraphics = pParams->m_pGraphics;
    130   CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
    131   if (!pRenderDevice)
    132     return;
    133 
    134   m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
    135   m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
    136   m_pTextOut->SetFont(pNode->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc()));
    137   m_pTextOut->SetFontSize(pNode->GetFontSize());
    138   m_pTextOut->SetTextColor(pNode->GetTextColor());
    139   CFX_Matrix mtPart = pParams->m_matrix;
    140   const CFX_Matrix* pMatrix = pGraphics->GetMatrix();
    141   if (pMatrix)
    142     mtPart.Concat(*pMatrix);
    143 
    144   m_pTextOut->SetMatrix(mtPart);
    145   m_pTextOut->DrawLogicText(pRenderDevice, pParams->m_wsText.AsStringView(),
    146                             pParams->m_rtPart);
    147 }
    148 
    149 CFX_RectF CXFA_FWLTheme::GetUIMargin(CFWL_ThemePart* pThemePart) const {
    150   CFX_RectF rect;
    151   CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget);
    152   if (!pWidget)
    153     return rect;
    154 
    155   CXFA_LayoutItem* pItem = pWidget;
    156   CXFA_WidgetAcc* pWidgetAcc = pWidget->GetNode()->GetWidgetAcc();
    157   rect = pWidgetAcc->GetUIMargin();
    158   CXFA_Para* para = pWidgetAcc->GetNode()->GetParaIfExists();
    159   if (para) {
    160     rect.left += para->GetMarginLeft();
    161     if (pWidgetAcc->IsMultiLine())
    162       rect.width += para->GetMarginRight();
    163   }
    164   if (!pItem->GetPrev()) {
    165     if (pItem->GetNext())
    166       rect.height = 0;
    167   } else if (!pItem->GetNext()) {
    168     rect.top = 0;
    169   } else {
    170     rect.top = 0;
    171     rect.height = 0;
    172   }
    173   return rect;
    174 }
    175 
    176 float CXFA_FWLTheme::GetCXBorderSize() const {
    177   return 1.0f;
    178 }
    179 
    180 float CXFA_FWLTheme::GetCYBorderSize() const {
    181   return 1.0f;
    182 }
    183 
    184 float CXFA_FWLTheme::GetFontSize(CFWL_ThemePart* pThemePart) const {
    185   if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
    186     return pWidget->GetNode()->GetFontSize();
    187   return FWLTHEME_CAPACITY_FontSize;
    188 }
    189 
    190 RetainPtr<CFGAS_GEFont> CXFA_FWLTheme::GetFont(
    191     CFWL_ThemePart* pThemePart) const {
    192   if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
    193     return pWidget->GetNode()->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc());
    194   return GetTheme(pThemePart->m_pWidget)->GetFont();
    195 }
    196 
    197 float CXFA_FWLTheme::GetLineHeight(CFWL_ThemePart* pThemePart) const {
    198   if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
    199     return pWidget->GetNode()->GetLineHeight();
    200   return kLineHeight;
    201 }
    202 
    203 float CXFA_FWLTheme::GetScrollBarWidth() const {
    204   return 9.0f;
    205 }
    206 
    207 FX_COLORREF CXFA_FWLTheme::GetTextColor(CFWL_ThemePart* pThemePart) const {
    208   if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget))
    209     return pWidget->GetNode()->GetTextColor();
    210   return FWLTHEME_CAPACITY_TextColor;
    211 }
    212 
    213 CFX_SizeF CXFA_FWLTheme::GetSpaceAboveBelow(CFWL_ThemePart* pThemePart) const {
    214   CFX_SizeF sizeAboveBelow;
    215   if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
    216     CXFA_Para* para = pWidget->GetNode()->GetParaIfExists();
    217     if (para) {
    218       sizeAboveBelow.width = para->GetSpaceAbove();
    219       sizeAboveBelow.height = para->GetSpaceBelow();
    220     }
    221   }
    222   return sizeAboveBelow;
    223 }
    224 
    225 void CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) {
    226   if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) {
    227     CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
    228     if (!pWidget || !pParams || !m_pTextOut)
    229       return;
    230 
    231     m_pTextOut->SetFont(m_pCalendarFont);
    232     m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
    233     m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
    234     m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
    235     m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
    236     m_pTextOut->CalcLogicSize(pParams->m_wsText, rect);
    237   }
    238 
    239   CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
    240   if (!pWidget)
    241     return;
    242 
    243   CXFA_Node* pNode = pWidget->GetNode();
    244   m_pTextOut->SetFont(pNode->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc()));
    245   m_pTextOut->SetFontSize(pNode->GetFontSize());
    246   m_pTextOut->SetTextColor(pNode->GetTextColor());
    247   if (!pParams)
    248     return;
    249 
    250   m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
    251   m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
    252   m_pTextOut->CalcLogicSize(pParams->m_wsText, rect);
    253 }
    254 
    255 CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(CFWL_Widget* pWidget) const {
    256   switch (pWidget->GetClassID()) {
    257     case FWL_Type::CheckBox:
    258       return m_pCheckBoxTP.get();
    259     case FWL_Type::ListBox:
    260       return m_pListBoxTP.get();
    261     case FWL_Type::PictureBox:
    262       return m_pPictureBoxTP.get();
    263     case FWL_Type::ScrollBar:
    264       return m_pSrollBarTP.get();
    265     case FWL_Type::Edit:
    266       return m_pEditTP.get();
    267     case FWL_Type::ComboBox:
    268       return m_pComboBoxTP.get();
    269     case FWL_Type::MonthCalendar:
    270       return m_pMonthCalendarTP.get();
    271     case FWL_Type::DateTimePicker:
    272       return m_pDateTimePickerTP.get();
    273     case FWL_Type::PushButton:
    274       return m_pPushButtonTP.get();
    275     case FWL_Type::Caret:
    276       return m_pCaretTP.get();
    277     case FWL_Type::Barcode:
    278       return m_pBarcodeTP.get();
    279     default:
    280       return nullptr;
    281   }
    282 }
    283