Home | History | Annotate | Download | only in app
      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/src/foxitlib.h"
      8 #include "xfa/src/fxfa/src/common/xfa_common.h"
      9 #include "xfa_fwltheme.h"
     10 #include "xfa_ffwidget.h"
     11 #include "xfa_ffapp.h"
     12 CXFA_FFWidget* XFA_ThemeGetOuterWidget(IFWL_Widget* pWidget) {
     13   IFWL_Widget* pOuter = pWidget;
     14   while (pOuter->GetOuter()) {
     15     pOuter = pOuter->GetOuter();
     16   }
     17   if (pOuter) {
     18     return (CXFA_FFWidget*)pOuter->GetPrivateData(pOuter);
     19   }
     20   return NULL;
     21 }
     22 CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp) : m_pApp(pApp) {
     23   m_pTextOut = NULL;
     24   m_dwCapacity = 0;
     25   m_fCapacity = 0;
     26   m_pCalendarFont = NULL;
     27   m_Rect.Set(0, 0, 0, 0);
     28   m_SizeAboveBelow.Set(0, 0);
     29   m_pCheckBoxTP = new CXFA_FWLCheckBoxTP;
     30   m_pListBoxTP = new CFWL_ListBoxTP;
     31   m_pPictureBoxTP = new CFWL_PictureBoxTP;
     32   m_pSrollBarTP = new CFWL_ScrollBarTP;
     33   m_pEditTP = new CXFA_FWLEditTP;
     34   m_pComboBoxTP = new CFWL_ComboBoxTP;
     35   m_pMonthCalendarTP = new CFWL_MonthCalendarTP;
     36   m_pDateTimePickerTP = new CFWL_DateTimePickerTP;
     37   m_pPushButtonTP = new CFWL_PushButtonTP;
     38   m_pCaretTP = new CFWL_CaretTP;
     39   m_pBarcodeTP = new CFWL_BarcodeTP;
     40   Initialize();
     41 }
     42 CXFA_FWLTheme::~CXFA_FWLTheme() {
     43   Finalize();
     44   delete m_pCheckBoxTP;
     45   delete m_pListBoxTP;
     46   delete m_pPictureBoxTP;
     47   delete m_pSrollBarTP;
     48   delete m_pEditTP;
     49   delete m_pComboBoxTP;
     50   delete m_pMonthCalendarTP;
     51   delete m_pDateTimePickerTP;
     52   delete m_pPushButtonTP;
     53   delete m_pCaretTP;
     54   delete m_pBarcodeTP;
     55 }
     56 static const FX_WCHAR* g_FWLTheme_CalFonts[] = {
     57     L"Arial", L"Courier New", L"DejaVu Sans",
     58 };
     59 FWL_ERR CXFA_FWLTheme::Initialize() {
     60   m_pTextOut = IFDE_TextOut::Create();
     61   for (int32_t i = 0; NULL == m_pCalendarFont &&
     62                       i < sizeof(g_FWLTheme_CalFonts) / sizeof(const FX_WCHAR*);
     63        i++) {
     64     m_pCalendarFont = IFX_Font::LoadFont(g_FWLTheme_CalFonts[i], 0, 0,
     65                                          m_pApp->GetFDEFontMgr());
     66   }
     67   if (NULL == m_pCalendarFont)
     68 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
     69     m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetDefFontByCodePage(
     70         FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL);
     71 #else
     72     m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage(
     73         FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL);
     74 #endif
     75   FXSYS_assert(NULL != m_pCalendarFont);
     76   FWLTHEME_Init();
     77   return FWL_ERR_Succeeded;
     78 }
     79 FWL_ERR CXFA_FWLTheme::Finalize() {
     80   if (m_pTextOut) {
     81     m_pTextOut->Release();
     82     m_pTextOut = NULL;
     83   }
     84   if (m_pCalendarFont) {
     85     m_pCalendarFont->Release();
     86     m_pCalendarFont = NULL;
     87   }
     88   FWLTHEME_Release();
     89   return FWL_ERR_Succeeded;
     90 }
     91 FX_BOOL CXFA_FWLTheme::IsValidWidget(IFWL_Widget* pWidget) {
     92   return TRUE;
     93 }
     94 FX_DWORD CXFA_FWLTheme::GetThemeID(IFWL_Widget* pWidget) {
     95   return 0;
     96 }
     97 FX_DWORD CXFA_FWLTheme::SetThemeID(IFWL_Widget* pWidget,
     98                                    FX_DWORD dwThemeID,
     99                                    FX_BOOL bChildren) {
    100   return 0;
    101 }
    102 FX_BOOL CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) {
    103   return GetTheme(pParams->m_pWidget)->DrawBackground(pParams);
    104 }
    105 FX_BOOL CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) {
    106   if (pParams->m_wsText.IsEmpty()) {
    107     return FWL_ERR_Indefinite;
    108   }
    109   if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) {
    110     CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
    111     if (!pWidget) {
    112       return FWL_ERR_Indefinite;
    113     }
    114     m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
    115     m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
    116     m_pTextOut->SetFont(m_pCalendarFont);
    117     m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
    118     m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
    119     if ((pParams->m_iPart == FWL_PART_MCD_DatesIn) &&
    120         !(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) &&
    121         (pParams->m_dwStates &
    122          (FWL_PARTSTATE_MCD_Hovered | FWL_PARTSTATE_MCD_Selected))) {
    123       m_pTextOut->SetTextColor(0xFFFFFFFF);
    124     }
    125     if (pParams->m_iPart == FWL_PART_MCD_Caption) {
    126       if (m_pMonthCalendarTP->GetThemeID(pParams->m_pWidget) == 0) {
    127         m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255));
    128       } else {
    129         m_pTextOut->SetTextColor(ArgbEncode(0xff, 128, 128, 0));
    130       }
    131     }
    132     CFX_Graphics* pGraphics = pParams->m_pGraphics;
    133     CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
    134     if (!pRenderDevice)
    135       return FALSE;
    136     m_pTextOut->SetRenderDevice(pRenderDevice);
    137     CFX_Matrix mtPart = pParams->m_matrix;
    138     CFX_Matrix* pMatrix = pGraphics->GetMatrix();
    139     if (pMatrix) {
    140       mtPart.Concat(*pMatrix);
    141     }
    142     m_pTextOut->SetMatrix(mtPart);
    143     m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(),
    144                               pParams->m_rtPart);
    145     return TRUE;
    146   }
    147   CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
    148   if (!pWidget) {
    149     return FWL_ERR_Indefinite;
    150   }
    151   CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
    152   CFX_Graphics* pGraphics = pParams->m_pGraphics;
    153   CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice();
    154   if (!pRenderDevice)
    155     return FALSE;
    156   m_pTextOut->SetRenderDevice(pRenderDevice);
    157   m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
    158   m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
    159   m_pTextOut->SetFont(pAcc->GetFDEFont());
    160   m_pTextOut->SetFontSize(pAcc->GetFontSize());
    161   m_pTextOut->SetTextColor(pAcc->GetTextColor());
    162   CFX_Matrix mtPart = pParams->m_matrix;
    163   CFX_Matrix* pMatrix = pGraphics->GetMatrix();
    164   if (pMatrix) {
    165     mtPart.Concat(*pMatrix);
    166   }
    167   m_pTextOut->SetMatrix(mtPart);
    168   m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(),
    169                             pParams->m_rtPart);
    170   return TRUE;
    171 }
    172 void* CXFA_FWLTheme::GetCapacity(CFWL_ThemePart* pThemePart,
    173                                  FX_DWORD dwCapacity) {
    174   switch (dwCapacity) {
    175     case FWL_WGTCAPACITY_Font: {
    176       if (CXFA_FFWidget* pWidget =
    177               XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
    178         return pWidget->GetDataAcc()->GetFDEFont();
    179       }
    180     } break;
    181     case FWL_WGTCAPACITY_FontSize: {
    182       if (CXFA_FFWidget* pWidget =
    183               XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
    184         m_fCapacity = pWidget->GetDataAcc()->GetFontSize();
    185         return &m_fCapacity;
    186       }
    187     } break;
    188     case FWL_WGTCAPACITY_TextColor: {
    189       if (CXFA_FFWidget* pWidget =
    190               XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
    191         m_dwCapacity = pWidget->GetDataAcc()->GetTextColor();
    192         return &m_dwCapacity;
    193       }
    194     } break;
    195     case FWL_WGTCAPACITY_LineHeight: {
    196       if (CXFA_FFWidget* pWidget =
    197               XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
    198         m_fCapacity = pWidget->GetDataAcc()->GetLineHeight();
    199         return &m_fCapacity;
    200       }
    201     } break;
    202     case FWL_WGTCAPACITY_ScrollBarWidth: {
    203       m_fCapacity = 9;
    204       return &m_fCapacity;
    205     } break;
    206     case FWL_WGTCAPACITY_UIMargin: {
    207       CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget);
    208       if (pWidget) {
    209         CXFA_LayoutItem* pItem = pWidget;
    210         CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
    211         pWidgetAcc->GetUIMargin(m_Rect);
    212         if (CXFA_Para para = pWidgetAcc->GetPara()) {
    213           m_Rect.left += para.GetMarginLeft();
    214           if (pWidgetAcc->IsMultiLine()) {
    215             m_Rect.width += para.GetMarginRight();
    216           }
    217         }
    218         if (pItem->GetPrev() == NULL) {
    219           if (pItem->GetNext() != NULL) {
    220             m_Rect.height = 0;
    221           }
    222         } else if (pItem->GetNext() == NULL) {
    223           m_Rect.top = 0;
    224         } else {
    225           m_Rect.top = 0;
    226           m_Rect.height = 0;
    227         }
    228       }
    229       return &m_Rect;
    230     } break;
    231     case FWL_WGTCAPACITY_SpaceAboveBelow: {
    232       CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget);
    233       if (pWidget) {
    234         CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
    235         if (CXFA_Para para = pWidgetAcc->GetPara()) {
    236           m_SizeAboveBelow.x = para.GetSpaceAbove();
    237           m_SizeAboveBelow.y = para.GetSpaceBelow();
    238         }
    239       }
    240       return &m_SizeAboveBelow;
    241     } break;
    242     default:
    243       break;
    244   }
    245   if (pThemePart->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar &&
    246       dwCapacity >= FWL_MCCAPACITY_Sun && dwCapacity <= FWL_MCCAPACITY_Today) {
    247     if (CXFA_FFWidget* pWidget =
    248             XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
    249       IXFA_AppProvider* pAppProvider = pWidget->GetAppProvider();
    250       m_wsResource.Empty();
    251       pAppProvider->LoadString(
    252           XFA_IDS_StringWeekDay_Sun + dwCapacity - FWL_WGTCAPACITY_MAX - 5,
    253           m_wsResource);
    254       if (!m_wsResource.IsEmpty()) {
    255         return &m_wsResource;
    256       }
    257     }
    258   }
    259   return GetTheme(pThemePart->m_pWidget)->GetCapacity(pThemePart, dwCapacity);
    260 }
    261 FX_BOOL CXFA_FWLTheme::IsCustomizedLayout(IFWL_Widget* pWidget) {
    262   return GetTheme(pWidget)->IsCustomizedLayout(pWidget);
    263 }
    264 FWL_ERR CXFA_FWLTheme::GetPartRect(CFWL_ThemePart* pThemePart) {
    265   CFX_RectF rect;
    266   return GetTheme(pThemePart->m_pWidget)->GetPartRect(pThemePart, rect);
    267 }
    268 FX_BOOL CXFA_FWLTheme::IsInPart(CFWL_ThemePart* pThemePart,
    269                                 FX_FLOAT fx,
    270                                 FX_FLOAT fy) {
    271   return GetTheme(pThemePart->m_pWidget)->IsInPart(pThemePart, fx, fy);
    272 }
    273 FX_BOOL CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) {
    274   if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) {
    275     CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
    276     if (!pWidget) {
    277       return FWL_ERR_Indefinite;
    278     }
    279     if (!pParams)
    280       return FALSE;
    281     if (!m_pTextOut)
    282       return FALSE;
    283     m_pTextOut->SetFont(m_pCalendarFont);
    284     m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
    285     m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
    286     m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
    287     m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
    288     m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(),
    289                               rect);
    290     return TRUE;
    291   }
    292   CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
    293   if (!pWidget) {
    294     return FWL_ERR_Indefinite;
    295   }
    296   CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
    297   m_pTextOut->SetFont(pAcc->GetFDEFont());
    298   m_pTextOut->SetFontSize(pAcc->GetFontSize());
    299   m_pTextOut->SetTextColor(pAcc->GetTextColor());
    300   if (!pParams)
    301     return FALSE;
    302   if (!m_pTextOut)
    303     return FALSE;
    304   m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
    305   m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
    306   m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(),
    307                             rect);
    308   return TRUE;
    309 }
    310 CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(IFWL_Widget* pWidget) {
    311   switch (pWidget->GetClassID()) {
    312     case FWL_CLASSHASH_CheckBox:
    313       return m_pCheckBoxTP;
    314     case FWL_CLASSHASH_ListBox:
    315       return m_pListBoxTP;
    316     case FWL_CLASSHASH_PictureBox:
    317       return m_pPictureBoxTP;
    318     case FWL_CLASSHASH_ScrollBar:
    319       return m_pSrollBarTP;
    320     case FWL_CLASSHASH_Edit:
    321       return m_pEditTP;
    322     case FWL_CLASSHASH_ComboBox:
    323       return m_pComboBoxTP;
    324     case FWL_CLASSHASH_MonthCalendar:
    325       return m_pMonthCalendarTP;
    326     case FWL_CLASSHASH_DateTimePicker:
    327       return m_pDateTimePickerTP;
    328     case FWL_CLASSHASH_PushButton:
    329       return m_pPushButtonTP;
    330     case FWL_CLASSHASH_Caret:
    331       return m_pCaretTP;
    332     case FWL_CLASSHASH_Barcode:
    333       return m_pBarcodeTP;
    334     default:
    335       break;
    336   }
    337   return NULL;
    338 }
    339 CXFA_FWLCheckBoxTP::CXFA_FWLCheckBoxTP() {}
    340 FX_BOOL CXFA_FWLCheckBoxTP::DrawBackground(CFWL_ThemeBackground* pParams) {
    341   if (pParams->m_iPart != FWL_PART_CKB_CheckBox) {
    342     return TRUE;
    343   }
    344   if (((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) ==
    345        FWL_PARTSTATE_CKB_Checked) ||
    346       ((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) ==
    347        FWL_PARTSTATE_CKB_Neutral)) {
    348     DrawCheckSign(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart,
    349                   pParams->m_dwStates, &pParams->m_matrix);
    350   }
    351   return TRUE;
    352 }
    353 void CXFA_FWLCheckBoxTP::DrawCheckSign(IFWL_Widget* pWidget,
    354                                        CFX_Graphics* pGraphics,
    355                                        const CFX_RectF* pRtBox,
    356                                        int32_t iState,
    357                                        CFX_Matrix* pMatrix) {
    358   CFX_RectF rtSign(*pRtBox);
    359   FX_DWORD dwColor = 0xFF000000;
    360   if ((iState & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral) {
    361     dwColor = 0xFFA9A9A9;
    362   }
    363   {
    364     FX_DWORD dwStyle = pWidget->GetStylesEx();
    365     rtSign.Deflate(rtSign.width / 4, rtSign.height / 4);
    366     switch (dwStyle & FWL_STYLEEXT_CKB_SignShapeMask) {
    367       case FWL_STYLEEXT_CKB_SignShapeCheck:
    368         DrawSignCheck(pGraphics, &rtSign, dwColor, pMatrix);
    369         break;
    370       case FWL_STYLEEXT_CKB_SignShapeCircle:
    371         DrawSignCircle(pGraphics, &rtSign, dwColor, pMatrix);
    372         break;
    373       case FWL_STYLEEXT_CKB_SignShapeCross:
    374         DrawSignCross(pGraphics, &rtSign, dwColor, pMatrix);
    375         break;
    376       case FWL_STYLEEXT_CKB_SignShapeDiamond:
    377         DrawSignDiamond(pGraphics, &rtSign, dwColor, pMatrix);
    378         break;
    379       case FWL_STYLEEXT_CKB_SignShapeSquare:
    380         DrawSignSquare(pGraphics, &rtSign, dwColor, pMatrix);
    381         break;
    382       case FWL_STYLEEXT_CKB_SignShapeStar:
    383         DrawSignStar(pGraphics, &rtSign, dwColor, pMatrix);
    384         break;
    385       default:
    386         break;
    387     }
    388   }
    389 }
    390 CXFA_FWLEditTP::CXFA_FWLEditTP() {}
    391 CXFA_FWLEditTP::~CXFA_FWLEditTP() {}
    392 FX_BOOL CXFA_FWLEditTP::DrawBackground(CFWL_ThemeBackground* pParams) {
    393   if (FWL_PART_EDT_CombTextLine == pParams->m_iPart) {
    394     CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
    395     FX_ARGB cr = 0xFF000000;
    396     FX_FLOAT fWidth = 1.0f;
    397     if (CXFA_Border borderUI = pWidget->GetDataAcc()->GetUIBorder()) {
    398       CXFA_Edge edge = borderUI.GetEdge(0);
    399       if (edge) {
    400         cr = edge.GetColor();
    401         fWidth = edge.GetThickness();
    402       }
    403     }
    404     CFX_Color crLine(cr);
    405     pParams->m_pGraphics->SetStrokeColor(&crLine);
    406     pParams->m_pGraphics->SetLineWidth(fWidth);
    407     pParams->m_pGraphics->StrokePath(pParams->m_pPath, &pParams->m_matrix);
    408     return TRUE;
    409   }
    410   return CFWL_EditTP::DrawBackground(pParams);
    411 }
    412