Home | History | Annotate | Download | only in theme
      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/fwl/theme/cfwl_widgettp.h"
      8 
      9 #include <algorithm>
     10 #include <utility>
     11 
     12 #include "third_party/base/ptr_util.h"
     13 #include "xfa/fde/cfde_textout.h"
     14 #include "xfa/fgas/font/cfgas_fontmgr.h"
     15 #include "xfa/fgas/font/cfgas_gefont.h"
     16 #include "xfa/fwl/cfwl_themebackground.h"
     17 #include "xfa/fwl/cfwl_themepart.h"
     18 #include "xfa/fwl/cfwl_themetext.h"
     19 #include "xfa/fwl/cfwl_widget.h"
     20 #include "xfa/fwl/cfwl_widgetmgr.h"
     21 #include "xfa/fwl/ifwl_themeprovider.h"
     22 #include "xfa/fxgraphics/cxfa_gecolor.h"
     23 #include "xfa/fxgraphics/cxfa_gepath.h"
     24 #include "xfa/fxgraphics/cxfa_geshading.h"
     25 
     26 CFWL_WidgetTP::CFWL_WidgetTP()
     27     : m_dwRefCount(1), m_pFDEFont(nullptr), m_pColorData(nullptr) {}
     28 
     29 CFWL_WidgetTP::~CFWL_WidgetTP() {}
     30 
     31 void CFWL_WidgetTP::Initialize() {}
     32 
     33 void CFWL_WidgetTP::Finalize() {
     34   if (m_pTextOut)
     35     FinalizeTTO();
     36 }
     37 
     38 void CFWL_WidgetTP::DrawBackground(CFWL_ThemeBackground* pParams) {}
     39 
     40 void CFWL_WidgetTP::DrawText(CFWL_ThemeText* pParams) {
     41   if (!m_pTextOut)
     42     InitTTO();
     43 
     44   int32_t iLen = pParams->m_wsText.GetLength();
     45   if (iLen <= 0)
     46     return;
     47 
     48   CXFA_Graphics* pGraphics = pParams->m_pGraphics;
     49   m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
     50   m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
     51 
     52   CFX_Matrix* pMatrix = &pParams->m_matrix;
     53   pMatrix->Concat(*pGraphics->GetMatrix());
     54   m_pTextOut->SetMatrix(*pMatrix);
     55   m_pTextOut->DrawLogicText(pGraphics->GetRenderDevice(),
     56                             WideStringView(pParams->m_wsText.c_str(), iLen),
     57                             pParams->m_rtPart);
     58 }
     59 
     60 const RetainPtr<CFGAS_GEFont>& CFWL_WidgetTP::GetFont() const {
     61   return m_pFDEFont;
     62 }
     63 
     64 void CFWL_WidgetTP::InitializeArrowColorData() {
     65   if (m_pColorData)
     66     return;
     67 
     68   m_pColorData = pdfium::MakeUnique<CColorData>();
     69   m_pColorData->clrBorder[0] = ArgbEncode(255, 202, 216, 249);
     70   m_pColorData->clrBorder[1] = ArgbEncode(255, 171, 190, 233);
     71   m_pColorData->clrBorder[2] = ArgbEncode(255, 135, 147, 219);
     72   m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
     73   m_pColorData->clrStart[0] = ArgbEncode(255, 225, 234, 254);
     74   m_pColorData->clrStart[1] = ArgbEncode(255, 253, 255, 255);
     75   m_pColorData->clrStart[2] = ArgbEncode(255, 110, 142, 241);
     76   m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
     77   m_pColorData->clrEnd[0] = ArgbEncode(255, 175, 204, 251);
     78   m_pColorData->clrEnd[1] = ArgbEncode(255, 185, 218, 251);
     79   m_pColorData->clrEnd[2] = ArgbEncode(255, 210, 222, 235);
     80   m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
     81   m_pColorData->clrSign[0] = ArgbEncode(255, 77, 97, 133);
     82   m_pColorData->clrSign[1] = ArgbEncode(255, 77, 97, 133);
     83   m_pColorData->clrSign[2] = ArgbEncode(255, 77, 97, 133);
     84   m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
     85 }
     86 
     87 
     88 void CFWL_WidgetTP::InitTTO() {
     89   if (m_pTextOut)
     90     return;
     91 
     92   m_pFDEFont = CFWL_FontManager::GetInstance()->FindFont(L"Helvetica", 0, 0);
     93   m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>();
     94   m_pTextOut->SetFont(m_pFDEFont);
     95   m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
     96   m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
     97 }
     98 
     99 void CFWL_WidgetTP::FinalizeTTO() {
    100   m_pTextOut.reset();
    101 }
    102 
    103 void CFWL_WidgetTP::DrawBorder(CXFA_Graphics* pGraphics,
    104                                const CFX_RectF* pRect,
    105                                CFX_Matrix* pMatrix) {
    106   if (!pGraphics || !pRect)
    107     return;
    108 
    109   CXFA_GEPath path;
    110   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
    111   path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
    112                     pRect->height - 2);
    113   pGraphics->SaveGraphState();
    114   pGraphics->SetFillColor(CXFA_GEColor(ArgbEncode(255, 0, 0, 0)));
    115   pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
    116   pGraphics->RestoreGraphState();
    117 }
    118 
    119 void CFWL_WidgetTP::FillBackground(CXFA_Graphics* pGraphics,
    120                                    const CFX_RectF* pRect,
    121                                    CFX_Matrix* pMatrix) {
    122   FillSoildRect(pGraphics, FWLTHEME_COLOR_Background, pRect, pMatrix);
    123 }
    124 
    125 void CFWL_WidgetTP::FillSoildRect(CXFA_Graphics* pGraphics,
    126                                   FX_ARGB fillColor,
    127                                   const CFX_RectF* pRect,
    128                                   CFX_Matrix* pMatrix) {
    129   if (!pGraphics || !pRect)
    130     return;
    131 
    132   CXFA_GEPath path;
    133   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
    134   pGraphics->SaveGraphState();
    135   pGraphics->SetFillColor(CXFA_GEColor(fillColor));
    136   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
    137   pGraphics->RestoreGraphState();
    138 }
    139 
    140 void CFWL_WidgetTP::DrawAxialShading(CXFA_Graphics* pGraphics,
    141                                      float fx1,
    142                                      float fy1,
    143                                      float fx2,
    144                                      float fy2,
    145                                      FX_ARGB beginColor,
    146                                      FX_ARGB endColor,
    147                                      CXFA_GEPath* path,
    148                                      int32_t fillMode,
    149                                      CFX_Matrix* pMatrix) {
    150   if (!pGraphics || !path)
    151     return;
    152 
    153   CFX_PointF begPoint(fx1, fy1);
    154   CFX_PointF endPoint(fx2, fy2);
    155   CXFA_GEShading shading(begPoint, endPoint, false, false, beginColor,
    156                          endColor);
    157   pGraphics->SaveGraphState();
    158   pGraphics->SetFillColor(CXFA_GEColor(&shading));
    159   pGraphics->FillPath(path, fillMode, pMatrix);
    160   pGraphics->RestoreGraphState();
    161 }
    162 
    163 void CFWL_WidgetTP::DrawFocus(CXFA_Graphics* pGraphics,
    164                               const CFX_RectF* pRect,
    165                               CFX_Matrix* pMatrix) {
    166   if (!pGraphics || !pRect)
    167     return;
    168 
    169   float DashPattern[2] = {1, 1};
    170   CXFA_GEPath path;
    171   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
    172   pGraphics->SaveGraphState();
    173   pGraphics->SetStrokeColor(CXFA_GEColor(0xFF000000));
    174   pGraphics->SetLineDash(0.0f, DashPattern, 2);
    175   pGraphics->StrokePath(&path, pMatrix);
    176   pGraphics->RestoreGraphState();
    177 }
    178 
    179 void CFWL_WidgetTP::DrawArrow(CXFA_Graphics* pGraphics,
    180                               const CFX_RectF* pRect,
    181                               FWLTHEME_DIRECTION eDict,
    182                               FX_ARGB argSign,
    183                               CFX_Matrix* pMatrix) {
    184   bool bVert =
    185       (eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down);
    186   float fLeft =
    187       (float)(((pRect->width - (bVert ? 9 : 6)) / 2 + pRect->left) + 0.5);
    188   float fTop =
    189       (float)(((pRect->height - (bVert ? 6 : 9)) / 2 + pRect->top) + 0.5);
    190   CXFA_GEPath path;
    191   switch (eDict) {
    192     case FWLTHEME_DIRECTION_Down: {
    193       path.MoveTo(CFX_PointF(fLeft, fTop + 1));
    194       path.LineTo(CFX_PointF(fLeft + 4, fTop + 5));
    195       path.LineTo(CFX_PointF(fLeft + 8, fTop + 1));
    196       path.LineTo(CFX_PointF(fLeft + 7, fTop));
    197       path.LineTo(CFX_PointF(fLeft + 4, fTop + 3));
    198       path.LineTo(CFX_PointF(fLeft + 1, fTop));
    199       break;
    200     }
    201     case FWLTHEME_DIRECTION_Up: {
    202       path.MoveTo(CFX_PointF(fLeft, fTop + 4));
    203       path.LineTo(CFX_PointF(fLeft + 4, fTop));
    204       path.LineTo(CFX_PointF(fLeft + 8, fTop + 4));
    205       path.LineTo(CFX_PointF(fLeft + 7, fTop + 5));
    206       path.LineTo(CFX_PointF(fLeft + 4, fTop + 2));
    207       path.LineTo(CFX_PointF(fLeft + 1, fTop + 5));
    208       break;
    209     }
    210     case FWLTHEME_DIRECTION_Right: {
    211       path.MoveTo(CFX_PointF(fLeft + 1, fTop));
    212       path.LineTo(CFX_PointF(fLeft + 5, fTop + 4));
    213       path.LineTo(CFX_PointF(fLeft + 1, fTop + 8));
    214       path.LineTo(CFX_PointF(fLeft, fTop + 7));
    215       path.LineTo(CFX_PointF(fLeft + 3, fTop + 4));
    216       path.LineTo(CFX_PointF(fLeft, fTop + 1));
    217       break;
    218     }
    219     case FWLTHEME_DIRECTION_Left: {
    220       path.MoveTo(CFX_PointF(fLeft, fTop + 4));
    221       path.LineTo(CFX_PointF(fLeft + 4, fTop));
    222       path.LineTo(CFX_PointF(fLeft + 5, fTop + 1));
    223       path.LineTo(CFX_PointF(fLeft + 2, fTop + 4));
    224       path.LineTo(CFX_PointF(fLeft + 5, fTop + 7));
    225       path.LineTo(CFX_PointF(fLeft + 4, fTop + 8));
    226       break;
    227     }
    228   }
    229   pGraphics->SetFillColor(CXFA_GEColor(argSign));
    230   pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
    231 }
    232 
    233 void CFWL_WidgetTP::DrawBtn(CXFA_Graphics* pGraphics,
    234                             const CFX_RectF* pRect,
    235                             FWLTHEME_STATE eState,
    236                             CFX_Matrix* pMatrix) {
    237   InitializeArrowColorData();
    238 
    239   CXFA_GEPath path;
    240   float fRight = pRect->right();
    241   float fBottom = pRect->bottom();
    242   path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
    243   DrawAxialShading(pGraphics, pRect->left, pRect->top, fRight, fBottom,
    244                    m_pColorData->clrStart[eState - 1],
    245                    m_pColorData->clrEnd[eState - 1], &path, FXFILL_WINDING,
    246                    pMatrix);
    247 
    248   pGraphics->SetStrokeColor(CXFA_GEColor(m_pColorData->clrBorder[eState - 1]));
    249   pGraphics->StrokePath(&path, pMatrix);
    250 }
    251 
    252 void CFWL_WidgetTP::DrawArrowBtn(CXFA_Graphics* pGraphics,
    253                                  const CFX_RectF* pRect,
    254                                  FWLTHEME_DIRECTION eDict,
    255                                  FWLTHEME_STATE eState,
    256                                  CFX_Matrix* pMatrix) {
    257   DrawBtn(pGraphics, pRect, eState, pMatrix);
    258 
    259   InitializeArrowColorData();
    260   DrawArrow(pGraphics, pRect, eDict, m_pColorData->clrSign[eState - 1],
    261             pMatrix);
    262 }
    263 
    264 CFWL_FontData::CFWL_FontData() : m_dwStyles(0), m_dwCodePage(0) {}
    265 
    266 CFWL_FontData::~CFWL_FontData() {}
    267 
    268 bool CFWL_FontData::Equal(const WideStringView& wsFontFamily,
    269                           uint32_t dwFontStyles,
    270                           uint16_t wCodePage) {
    271   return m_wsFamily == wsFontFamily && m_dwStyles == dwFontStyles &&
    272          m_dwCodePage == wCodePage;
    273 }
    274 
    275 bool CFWL_FontData::LoadFont(const WideStringView& wsFontFamily,
    276                              uint32_t dwFontStyles,
    277                              uint16_t dwCodePage) {
    278   m_wsFamily = wsFontFamily;
    279   m_dwStyles = dwFontStyles;
    280   m_dwCodePage = dwCodePage;
    281   if (!m_pFontMgr) {
    282     m_pFontMgr = pdfium::MakeUnique<CFGAS_FontMgr>();
    283     if (!m_pFontMgr->EnumFonts())
    284       m_pFontMgr = nullptr;
    285   }
    286 
    287   // TODO(tsepez): check usage of c_str() below.
    288   m_pFont = CFGAS_GEFont::LoadFont(wsFontFamily.unterminated_c_str(),
    289                                    dwFontStyles, dwCodePage, m_pFontMgr.get());
    290   return !!m_pFont;
    291 }
    292 
    293 RetainPtr<CFGAS_GEFont> CFWL_FontData::GetFont() const {
    294   return m_pFont;
    295 }
    296 
    297 CFWL_FontManager* CFWL_FontManager::s_FontManager = nullptr;
    298 CFWL_FontManager* CFWL_FontManager::GetInstance() {
    299   if (!s_FontManager)
    300     s_FontManager = new CFWL_FontManager;
    301   return s_FontManager;
    302 }
    303 
    304 void CFWL_FontManager::DestroyInstance() {
    305   delete s_FontManager;
    306   s_FontManager = nullptr;
    307 }
    308 
    309 CFWL_FontManager::CFWL_FontManager() {}
    310 
    311 CFWL_FontManager::~CFWL_FontManager() {}
    312 
    313 RetainPtr<CFGAS_GEFont> CFWL_FontManager::FindFont(
    314     const WideStringView& wsFontFamily,
    315     uint32_t dwFontStyles,
    316     uint16_t wCodePage) {
    317   for (const auto& pData : m_FontsArray) {
    318     if (pData->Equal(wsFontFamily, dwFontStyles, wCodePage))
    319       return pData->GetFont();
    320   }
    321   auto pFontData = pdfium::MakeUnique<CFWL_FontData>();
    322   if (!pFontData->LoadFont(wsFontFamily, dwFontStyles, wCodePage))
    323     return nullptr;
    324 
    325   m_FontsArray.push_back(std::move(pFontData));
    326   return m_FontsArray.back()->GetFont();
    327 }
    328 
    329 void FWLTHEME_Release() {
    330   CFWL_FontManager::DestroyInstance();
    331 }
    332