// 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/include/fwl/theme/widgettp.h"

#include <algorithm>

#include "xfa/include/fwl/core/fwl_widgetmgr.h"
#include "xfa/src/fdp/include/fde_tto.h"

static void FWL_SetChildThemeID(IFWL_Widget* pParent, FX_DWORD dwThemeID) {
  IFWL_WidgetMgr* pWidgetMgr = FWL_GetWidgetMgr();
  IFWL_Widget* pChild =
      pWidgetMgr->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
  while (pChild) {
    IFWL_ThemeProvider* pTheme = pChild->GetThemeProvider();
    if (pTheme) {
      pTheme->SetThemeID(pChild, dwThemeID, FALSE);
    }
    FWL_SetChildThemeID(pChild, dwThemeID);
    pChild = pWidgetMgr->GetWidget(pChild, FWL_WGTRELATION_NextSibling);
  }
}
FX_BOOL CFWL_WidgetTP::IsValidWidget(IFWL_Widget* pWidget) {
  return FALSE;
}
FX_DWORD CFWL_WidgetTP::GetThemeID(IFWL_Widget* pWidget) {
  return m_dwThemeID;
}
FX_DWORD CFWL_WidgetTP::SetThemeID(IFWL_Widget* pWidget,
                                   FX_DWORD dwThemeID,
                                   FX_BOOL bChildren) {
  FX_DWORD dwOld = m_dwThemeID;
  m_dwThemeID = dwThemeID;
  if (CFWL_ArrowData::IsInstance()) {
    CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(dwThemeID));
  }
  if (bChildren) {
    FWL_SetChildThemeID(pWidget, dwThemeID);
  }
  return dwOld;
}
FWL_ERR CFWL_WidgetTP::GetThemeMatrix(IFWL_Widget* pWidget,
                                      CFX_Matrix& matrix) {
  matrix.Set(_ctm.a, _ctm.b, _ctm.c, _ctm.d, _ctm.e, _ctm.f);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetTP::SetThemeMatrix(IFWL_Widget* pWidget,
                                      const CFX_Matrix& matrix) {
  _ctm.Set(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
  return FWL_ERR_Succeeded;
}
FX_BOOL CFWL_WidgetTP::DrawBackground(CFWL_ThemeBackground* pParams) {
  return TRUE;
}
FX_BOOL CFWL_WidgetTP::DrawText(CFWL_ThemeText* pParams) {
  if (!m_pTextOut) {
    InitTTO();
  }
  int32_t iLen = pParams->m_wsText.GetLength();
  if (iLen <= 0)
    return FALSE;
  CFX_Graphics* pGraphics = pParams->m_pGraphics;
  m_pTextOut->SetRenderDevice(pGraphics->GetRenderDevice());
  m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
  m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
  CFX_Matrix* pMatrix = &pParams->m_matrix;
  pMatrix->Concat(*pGraphics->GetMatrix());
  m_pTextOut->SetMatrix(*pMatrix);
  m_pTextOut->DrawLogicText(pParams->m_wsText, iLen, pParams->m_rtPart);
  return TRUE;
}
void* CFWL_WidgetTP::GetCapacity(CFWL_ThemePart* pThemePart,
                                 FX_DWORD dwCapacity) {
  switch (dwCapacity) {
    case FWL_WGTCAPACITY_CXBorder: {
      m_fValue = FWLTHEME_CAPACITY_CXBorder;
      break;
    }
    case FWL_WGTCAPACITY_CYBorder: {
      m_fValue = FWLTHEME_CAPACITY_CYBorder;
      break;
    }
    case FWL_WGTCAPACITY_EdgeFlat: {
      m_fValue = FWLTHEME_CAPACITY_EdgeFlat;
      break;
    }
    case FWL_WGTCAPACITY_EdgeRaised: {
      m_fValue = FWLTHEME_CAPACITY_EdgeRaised;
      break;
    }
    case FWL_WGTCAPACITY_EdgeSunken: {
      m_fValue = FWLTHEME_CAPACITY_EdgeSunken;
      break;
    }
    case FWL_WGTCAPACITY_FontSize: {
      m_fValue = FWLTHEME_CAPACITY_FontSize;
      break;
    }
    case FWL_WGTCAPACITY_TextColor: {
      m_dwValue = FWLTHEME_CAPACITY_TextColor;
      return &m_dwValue;
    }
    case FWL_WGTCAPACITY_ScrollBarWidth: {
      m_fValue = FWLTHEME_CAPACITY_ScrollBarWidth;
      break;
    }
    case FWL_WGTCAPACITY_Font: {
      return m_pFDEFont;
    }
    case FWL_WGTCAPACITY_TextSelColor: {
      m_dwValue = (m_dwThemeID == 0) ? FWLTHEME_CAPACITY_TextSelColor
                                     : FWLTHEME_COLOR_Green_BKSelected;
      return &m_dwValue;
    }
    case FWL_WGTCAPACITY_LineHeight: {
      m_fValue = FWLTHEME_CAPACITY_LineHeight;
      break;
    }
    case FWL_WGTCAPACITY_UIMargin: {
      m_rtMargin.Set(0, 0, 0, 0);
      return &m_rtMargin;
    }
    default: { return NULL; }
  }
  return &m_fValue;
}
FX_BOOL CFWL_WidgetTP::IsCustomizedLayout(IFWL_Widget* pWidget) {
  return FWL_GetThemeLayout(m_dwThemeID);
}
FWL_ERR CFWL_WidgetTP::GetPartRect(CFWL_ThemePart* pThemePart,
                                   CFX_RectF& rect) {
  return FWL_ERR_Succeeded;
}
FX_BOOL CFWL_WidgetTP::IsInPart(CFWL_ThemePart* pThemePart,
                                FX_FLOAT fx,
                                FX_FLOAT fy) {
  return TRUE;
}
FX_BOOL CFWL_WidgetTP::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) {
  if (!pParams)
    return FALSE;
  if (!m_pTextOut)
    return FALSE;
  m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
  m_pTextOut->SetStyles(pParams->m_dwTTOStyles | FDE_TTOSTYLE_ArabicContext);
  m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(),
                            rect);
  return TRUE;
}
FWL_ERR CFWL_WidgetTP::Initialize() {
  m_dwThemeID = 0;
  _ctm.SetIdentity();
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetTP::Finalize() {
  if (!m_pTextOut) {
    FinalizeTTO();
  }
  return FWL_ERR_Succeeded;
}
CFWL_WidgetTP::~CFWL_WidgetTP() {}
FWL_ERR CFWL_WidgetTP::SetFont(IFWL_Widget* pWidget,
                               const FX_WCHAR* strFont,
                               FX_FLOAT fFontSize,
                               FX_ARGB rgbFont) {
  if (!m_pTextOut) {
    return FWL_ERR_Succeeded;
  }
  m_pFDEFont = CFWL_FontManager::GetInstance()->FindFont(strFont, 0, 0);
  m_pTextOut->SetFont(m_pFDEFont);
  m_pTextOut->SetFontSize(fFontSize);
  m_pTextOut->SetTextColor(rgbFont);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_WidgetTP::SetFont(IFWL_Widget* pWidget,
                               IFX_Font* pFont,
                               FX_FLOAT fFontSize,
                               FX_ARGB rgbFont) {
  if (!m_pTextOut) {
    return FWL_ERR_Succeeded;
  }
  m_pTextOut->SetFont(pFont);
  m_pTextOut->SetFontSize(fFontSize);
  m_pTextOut->SetTextColor(rgbFont);
  return FWL_ERR_Succeeded;
}
IFX_Font* CFWL_WidgetTP::GetFont(IFWL_Widget* pWidget) {
  return m_pFDEFont;
}
CFWL_WidgetTP::CFWL_WidgetTP()
    : m_dwRefCount(1), m_pTextOut(NULL), m_pFDEFont(NULL), m_dwThemeID(0) {}
FX_ERR CFWL_WidgetTP::InitTTO() {
  if (m_pTextOut) {
    return FWL_ERR_Succeeded;
  }
  m_pFDEFont =
      CFWL_FontManager::GetInstance()->FindFont(FX_WSTRC(L"Helvetica"), 0, 0);
  m_pTextOut = IFDE_TextOut::Create();
  m_pTextOut->SetFont(m_pFDEFont);
  m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
  m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
  m_pTextOut->SetEllipsisString(L"...");
  return FWL_ERR_Succeeded;
}
FX_ERR CFWL_WidgetTP::FinalizeTTO() {
  if (m_pTextOut) {
    m_pTextOut->Release();
    m_pTextOut = NULL;
  }
  return FWL_ERR_Succeeded;
}
#ifdef THEME_XPSimilar
void CFWL_WidgetTP::DrawEdge(CFX_Graphics* pGraphics,
                             FX_DWORD dwStyles,
                             const CFX_RectF* pRect,
                             CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  pGraphics->SaveGraphState();
  CFX_Color crStroke(FWL_GetThemeColor(m_dwThemeID) == 0
                         ? ArgbEncode(255, 127, 157, 185)
                         : FWLTHEME_COLOR_Green_BKSelected);
  pGraphics->SetStrokeColor(&crStroke);
  CFX_Path path;
  path.Create();
  path.AddRectangle(pRect->left, pRect->top, pRect->width - 1,
                    pRect->height - 1);
  pGraphics->StrokePath(&path, pMatrix);
  path.Clear();
  crStroke = ArgbEncode(255, 255, 255, 255);
  pGraphics->SetStrokeColor(&crStroke);
  path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 3,
                    pRect->height - 3);
  pGraphics->StrokePath(&path, pMatrix);
  pGraphics->RestoreGraphState();
}
#else
void CFWL_WidgetTP::DrawEdge(CFX_Graphics* pGraphics,
                             FX_DWORD dwStyles,
                             const CFX_RectF* pRect,
                             CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  FWLTHEME_EDGE eType;
  FX_FLOAT fWidth;
  switch (dwStyles & FWL_WGTSTYLE_EdgeMask) {
    case FWL_WGTSTYLE_EdgeRaised: {
      eType = FWLTHEME_EDGE_Raised, fWidth = FWLTHEME_CAPACITY_EdgeRaised;
      break;
    }
    case FWL_WGTSTYLE_EdgeSunken: {
      eType = FWLTHEME_EDGE_Sunken, fWidth = FWLTHEME_CAPACITY_EdgeSunken;
      break;
    }
    case FWL_WGTSTYLE_EdgeFlat:
    default: { return; }
  }
  Draw3DRect(pGraphics, eType, fWidth, pRect, FWLTHEME_COLOR_EDGELT1,
             FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1,
             FWLTHEME_COLOR_EDGERB2, pMatrix);
}
#endif
void CFWL_WidgetTP::Draw3DRect(CFX_Graphics* pGraphics,
                               FWLTHEME_EDGE eType,
                               FX_FLOAT fWidth,
                               const CFX_RectF* pRect,
                               FX_ARGB cr1,
                               FX_ARGB cr2,
                               FX_ARGB cr3,
                               FX_ARGB cr4,
                               CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  pGraphics->SaveGraphState();
  if (eType == FWLTHEME_EDGE_Flat) {
    CFX_Path path;
    path.Create();
    path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
    path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
                      pRect->height - 2);
    CFX_Color cr(ArgbEncode(255, 100, 100, 100));
    pGraphics->SetFillColor(&cr);
    pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
    path.Clear();
    path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
                      pRect->height - 2);
    path.AddRectangle(pRect->left + 2, pRect->top + 2, pRect->width - 4,
                      pRect->height - 4);
    cr.Set(0xFFFFFFFF);
    pGraphics->SetFillColor(&cr);
    pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
  } else {
    FX_FLOAT fLeft = pRect->left;
    FX_FLOAT fRight = pRect->right();
    FX_FLOAT fTop = pRect->top;
    FX_FLOAT fBottom = pRect->bottom();
    FX_FLOAT fHalfWidth = fWidth / 2.0f;
    CFX_Color crLT(eType == FWLTHEME_EDGE_Raised ? cr4 : cr1);
    pGraphics->SetFillColor(&crLT);
    CFX_Path pathLT;
    pathLT.Create();
    pathLT.MoveTo(fLeft, fBottom - fHalfWidth);
    pathLT.LineTo(fLeft, fTop);
    pathLT.LineTo(fRight - fHalfWidth, fTop);
    pathLT.LineTo(fRight - fHalfWidth, fTop + fHalfWidth);
    pathLT.LineTo(fLeft + fHalfWidth, fTop + fHalfWidth);
    pathLT.LineTo(fLeft + fHalfWidth, fBottom - fHalfWidth);
    pathLT.LineTo(fLeft, fBottom - fHalfWidth);
    pGraphics->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
    crLT = CFX_Color(eType == FWLTHEME_EDGE_Raised ? cr3 : cr2);
    pGraphics->SetFillColor(&crLT);
    pathLT.Clear();
    pathLT.MoveTo(fLeft + fHalfWidth, fBottom - fWidth);
    pathLT.LineTo(fLeft + fHalfWidth, fTop + fHalfWidth);
    pathLT.LineTo(fRight - fWidth, fTop + fHalfWidth);
    pathLT.LineTo(fRight - fWidth, fTop + fWidth);
    pathLT.LineTo(fLeft + fWidth, fTop + fWidth);
    pathLT.LineTo(fLeft + fWidth, fBottom - fWidth);
    pathLT.LineTo(fLeft + fHalfWidth, fBottom - fWidth);
    pGraphics->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
    CFX_Color crRB(eType == FWLTHEME_EDGE_Raised ? cr1 : cr3);
    pGraphics->SetFillColor(&crRB);
    CFX_Path pathRB;
    pathRB.Create();
    pathRB.MoveTo(fRight - fHalfWidth, fTop + fHalfWidth);
    pathRB.LineTo(fRight - fHalfWidth, fBottom - fHalfWidth);
    pathRB.LineTo(fLeft + fHalfWidth, fBottom - fHalfWidth);
    pathRB.LineTo(fLeft + fHalfWidth, fBottom - fWidth);
    pathRB.LineTo(fRight - fWidth, fBottom - fWidth);
    pathRB.LineTo(fRight - fWidth, fTop + fHalfWidth);
    pathRB.LineTo(fRight - fHalfWidth, fTop + fHalfWidth);
    pGraphics->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
    crRB = CFX_Color(eType == FWLTHEME_EDGE_Raised ? cr2 : cr4);
    pGraphics->SetFillColor(&crRB);
    pathRB.Clear();
    pathRB.MoveTo(fRight, fTop);
    pathRB.LineTo(fRight, fBottom);
    pathRB.LineTo(fLeft, fBottom);
    pathRB.LineTo(fLeft, fBottom - fHalfWidth);
    pathRB.LineTo(fRight - fHalfWidth, fBottom - fHalfWidth);
    pathRB.LineTo(fRight - fHalfWidth, fTop);
    pathRB.LineTo(fRight, fTop);
    pGraphics->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
  }
  pGraphics->RestoreGraphState();
}
void CFWL_WidgetTP::Draw3DCircle(CFX_Graphics* pGraphics,
                                 FWLTHEME_EDGE eType,
                                 FX_FLOAT fWidth,
                                 const CFX_RectF* pRect,
                                 FX_ARGB cr1,
                                 FX_ARGB cr2,
                                 FX_ARGB cr3,
                                 FX_ARGB cr4,
                                 CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  pGraphics->SaveGraphState();
  CFX_Path path;
  path.Create();
  path.AddArc(pRect->left, pRect->top, pRect->width, pRect->height,
              FWLTHEME_PI * 3 / 4, FWLTHEME_PI);
  CFX_Color crFill1(eType == FWLTHEME_EDGE_Raised ? cr4 : cr1);
  pGraphics->SetStrokeColor(&crFill1);
  pGraphics->StrokePath(&path, pMatrix);
  CFX_RectF rtInner(*pRect);
  rtInner.Deflate(pRect->width / 4, pRect->height / 4);
  path.Clear();
  path.AddArc(rtInner.left, rtInner.top, rtInner.width, rtInner.height,
              FWLTHEME_PI * 3 / 4, FWLTHEME_PI);
  CFX_Color crFill2(eType == FWLTHEME_EDGE_Raised ? cr3 : cr2);
  pGraphics->SetStrokeColor(&crFill2);
  pGraphics->StrokePath(&path, pMatrix);
  path.Clear();
  path.AddArc(pRect->left, pRect->top, pRect->width, pRect->height,
              FWLTHEME_PI * 7 / 4, FWLTHEME_PI);
  CFX_Color crFill3(eType == FWLTHEME_EDGE_Raised ? cr1 : cr3);
  pGraphics->SetStrokeColor(&crFill3);
  pGraphics->StrokePath(&path, pMatrix);
  path.AddArc(rtInner.left, rtInner.top, rtInner.width, rtInner.height,
              FWLTHEME_PI * 7 / 4, FWLTHEME_PI);
  CFX_Color crFill4(eType == FWLTHEME_EDGE_Raised ? cr2 : cr4);
  pGraphics->SetStrokeColor(&crFill4);
  pGraphics->StrokePath(&path, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_WidgetTP::DrawBorder(CFX_Graphics* pGraphics,
                               const CFX_RectF* pRect,
                               CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  CFX_Path path;
  path.Create();
  path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
  path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2,
                    pRect->height - 2);
  pGraphics->SaveGraphState();
  CFX_Color crFill(ArgbEncode(255, 0, 0, 0));
  pGraphics->SetFillColor(&crFill);
  pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_WidgetTP::FillBackground(CFX_Graphics* pGraphics,
                                   const CFX_RectF* pRect,
                                   CFX_Matrix* pMatrix) {
  FillSoildRect(pGraphics, FWLTHEME_COLOR_Background, pRect, pMatrix);
}
void CFWL_WidgetTP::FillSoildRect(CFX_Graphics* pGraphics,
                                  FX_ARGB fillColor,
                                  const CFX_RectF* pRect,
                                  CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  pGraphics->SaveGraphState();
  CFX_Color crFill(fillColor);
  pGraphics->SetFillColor(&crFill);
  CFX_Path path;
  path.Create();
  path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_WidgetTP::DrawAxialShading(CFX_Graphics* pGraphics,
                                     FX_FLOAT fx1,
                                     FX_FLOAT fy1,
                                     FX_FLOAT fx2,
                                     FX_FLOAT fy2,
                                     FX_ARGB beginColor,
                                     FX_ARGB endColor,
                                     CFX_Path* path,
                                     int32_t fillMode,
                                     CFX_Matrix* pMatrix) {
  if (!pGraphics || !path)
    return;

  CFX_PointF begPoint(fx1, fy1);
  CFX_PointF endPoint(fx2, fy2);
  CFX_Shading shading;
  shading.CreateAxial(begPoint, endPoint, FALSE, FALSE, beginColor, endColor);
  pGraphics->SaveGraphState();
  CFX_Color color1(&shading);
  pGraphics->SetFillColor(&color1);
  pGraphics->FillPath(path, fillMode, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_WidgetTP::DrawAnnulusRect(CFX_Graphics* pGraphics,
                                    FX_ARGB fillColor,
                                    const CFX_RectF* pRect,
                                    FX_FLOAT fRingWidth,
                                    CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  pGraphics->SaveGraphState();
  CFX_Color cr(fillColor);
  pGraphics->SetFillColor(&cr);
  CFX_Path path;
  path.Create();
  CFX_RectF rtInner(*pRect);
  rtInner.Deflate(fRingWidth, fRingWidth);
  path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
  path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
  pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_WidgetTP::DrawAnnulusCircle(CFX_Graphics* pGraphics,
                                      FX_ARGB fillColor,
                                      const CFX_RectF* pRect,
                                      FX_FLOAT fWidth,
                                      CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  if (fWidth > pRect->width / 2) {
    return;
  }
  pGraphics->SaveGraphState();
  CFX_Color cr(fillColor);
  pGraphics->SetFillColor(&cr);
  CFX_Path path;
  path.Create();
  path.AddEllipse(*pRect);
  CFX_RectF rtIn(*pRect);
  rtIn.Inflate(-fWidth, -fWidth);
  path.AddEllipse(rtIn);
  pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_WidgetTP::DrawFocus(CFX_Graphics* pGraphics,
                              const CFX_RectF* pRect,
                              CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return;
  if (!pRect)
    return;
  pGraphics->SaveGraphState();
  CFX_Color cr(0xFF000000);
  pGraphics->SetStrokeColor(&cr);
  FX_FLOAT DashPattern[2] = {1, 1};
  pGraphics->SetLineDash(0.0f, DashPattern, 2);
  CFX_Path path;
  path.Create();
  path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
  pGraphics->StrokePath(&path, pMatrix);
  pGraphics->RestoreGraphState();
}
#define FWLTHEME_ARROW_Denominator 3
void CFWL_WidgetTP::DrawArrow(CFX_Graphics* pGraphics,
                              const CFX_RectF* pRect,
                              FWLTHEME_DIRECTION eDict,
                              FX_ARGB argbFill,
                              FX_BOOL bPressed,
                              CFX_Matrix* pMatrix) {
  CFX_RectF rtArrow(*pRect);
  CFX_Path path;
  path.Create();
  FX_FLOAT fBtn =
      std::min(pRect->width, pRect->height) / FWLTHEME_ARROW_Denominator;
  rtArrow.left = pRect->left + (pRect->width - fBtn) / 2;
  rtArrow.top = pRect->top + (pRect->height - fBtn) / 2;
  rtArrow.width = fBtn;
  rtArrow.height = fBtn;
  if (bPressed) {
    rtArrow.Offset(1, 1);
  }
  switch (eDict) {
    case FWLTHEME_DIRECTION_Up: {
      path.MoveTo(rtArrow.left, rtArrow.bottom());
      path.LineTo(rtArrow.right(), rtArrow.bottom());
      path.LineTo(rtArrow.left + fBtn / 2, rtArrow.top);
      path.LineTo(rtArrow.left, rtArrow.bottom());
      break;
    }
    case FWLTHEME_DIRECTION_Left: {
      path.MoveTo(rtArrow.right(), rtArrow.top);
      path.LineTo(rtArrow.right(), rtArrow.bottom());
      path.LineTo(rtArrow.left, rtArrow.top + fBtn / 2);
      path.LineTo(rtArrow.right(), rtArrow.top);
      break;
    }
    case FWLTHEME_DIRECTION_Right: {
      path.MoveTo(rtArrow.left, rtArrow.top);
      path.LineTo(rtArrow.left, rtArrow.bottom());
      path.LineTo(rtArrow.right(), rtArrow.top + fBtn / 2);
      path.LineTo(rtArrow.left, rtArrow.top);
      break;
    }
    case FWLTHEME_DIRECTION_Down:
    default: {
      path.MoveTo(rtArrow.left, rtArrow.top);
      path.LineTo(rtArrow.right(), rtArrow.top);
      path.LineTo(rtArrow.left + fBtn / 2, rtArrow.bottom());
      path.LineTo(rtArrow.left, rtArrow.top);
    }
  }
  pGraphics->SaveGraphState();
  CFX_Color cr(argbFill);
  pGraphics->SetFillColor(&cr);
  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_WidgetTP::DrawArrow(CFX_Graphics* pGraphics,
                              const CFX_RectF* pRect,
                              FWLTHEME_DIRECTION eDict,
                              FX_ARGB argSign,
                              CFX_Matrix* pMatrix) {
  FX_BOOL bVert =
      (eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down);
  FX_FLOAT fLeft =
      (FX_FLOAT)(((pRect->width - (bVert ? 9 : 6)) / 2 + pRect->left) + 0.5);
  FX_FLOAT fTop =
      (FX_FLOAT)(((pRect->height - (bVert ? 6 : 9)) / 2 + pRect->top) + 0.5);
  CFX_Path path;
  path.Create();
  switch (eDict) {
    case FWLTHEME_DIRECTION_Down: {
      path.MoveTo(fLeft, fTop + 1);
      path.LineTo(fLeft + 4, fTop + 5);
      path.LineTo(fLeft + 8, fTop + 1);
      path.LineTo(fLeft + 7, fTop);
      path.LineTo(fLeft + 4, fTop + 3);
      path.LineTo(fLeft + 1, fTop);
      break;
    }
    case FWLTHEME_DIRECTION_Up: {
      path.MoveTo(fLeft, fTop + 4);
      path.LineTo(fLeft + 4, fTop);
      path.LineTo(fLeft + 8, fTop + 4);
      path.LineTo(fLeft + 7, fTop + 5);
      path.LineTo(fLeft + 4, fTop + 2);
      path.LineTo(fLeft + 1, fTop + 5);
      break;
    }
    case FWLTHEME_DIRECTION_Right: {
      path.MoveTo(fLeft + 1, fTop);
      path.LineTo(fLeft + 5, fTop + 4);
      path.LineTo(fLeft + 1, fTop + 8);
      path.LineTo(fLeft, fTop + 7);
      path.LineTo(fLeft + 3, fTop + 4);
      path.LineTo(fLeft, fTop + 1);
      break;
    }
    case FWLTHEME_DIRECTION_Left: {
      path.MoveTo(fLeft, fTop + 4);
      path.LineTo(fLeft + 4, fTop);
      path.LineTo(fLeft + 5, fTop + 1);
      path.LineTo(fLeft + 2, fTop + 4);
      path.LineTo(fLeft + 5, fTop + 7);
      path.LineTo(fLeft + 4, fTop + 8);
      break;
    }
  }
  CFX_Color cr(argSign);
  pGraphics->SetFillColor(&cr);
  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
}
void CFWL_WidgetTP::DrawBtn(CFX_Graphics* pGraphics,
                            const CFX_RectF* pRect,
                            FWLTHEME_STATE eState,
                            CFX_Matrix* pMatrix) {
  CFX_Path path;
  path.Create();
  if (!CFWL_ArrowData::IsInstance()) {
    CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(m_dwThemeID));
  }
  CFWL_ArrowData::CColorData* pColorData =
      CFWL_ArrowData::GetInstance()->m_pColorData;
  FX_FLOAT fRight = pRect->right();
  FX_FLOAT fBottom = pRect->bottom();
  path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
  DrawAxialShading(pGraphics, pRect->left, pRect->top, fRight, fBottom,
                   pColorData->clrStart[eState - 1],
                   pColorData->clrEnd[eState - 1], &path, FXFILL_WINDING,
                   pMatrix);
  CFX_Color rcStroke;
  rcStroke.Set(pColorData->clrBorder[eState - 1]);
  pGraphics->SetStrokeColor(&rcStroke);
  pGraphics->StrokePath(&path, pMatrix);
}
void CFWL_WidgetTP::DrawArrowBtn(CFX_Graphics* pGraphics,
                                 const CFX_RectF* pRect,
                                 FWLTHEME_DIRECTION eDict,
                                 FWLTHEME_STATE eState,
                                 CFX_Matrix* pMatrix) {
  DrawBtn(pGraphics, pRect, eState, pMatrix);
  if (!CFWL_ArrowData::IsInstance()) {
    CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(m_dwThemeID));
  }
  CFWL_ArrowData::CColorData* pColorData =
      CFWL_ArrowData::GetInstance()->m_pColorData;
  DrawArrow(pGraphics, pRect, eDict, pColorData->clrSign[eState - 1], pMatrix);
}
FWLCOLOR CFWL_WidgetTP::BlendColor(FWLCOLOR srcColor,
                                   FWLCOLOR renderColor,
                                   uint8_t scale) {
  FWLCOLOR dstColor;
  uint8_t n = 255 - scale;
  dstColor.a = (uint8_t)(
      ((FX_WORD)srcColor.a * n + (FX_WORD)renderColor.a * scale) >> 8);
  dstColor.r = (uint8_t)(
      ((FX_WORD)srcColor.r * n + (FX_WORD)renderColor.r * scale) >> 8);
  dstColor.g = (uint8_t)(
      ((FX_WORD)srcColor.g * n + (FX_WORD)renderColor.g * scale) >> 8);
  dstColor.b = (uint8_t)(
      ((FX_WORD)srcColor.b * n + (FX_WORD)renderColor.b * scale) >> 8);
  return dstColor;
}
CFWL_ArrowData::CFWL_ArrowData() : m_pColorData(NULL) {
  SetColorData(0);
}
CFWL_FontData::CFWL_FontData()
    : m_dwStyles(0),
      m_dwCodePage(0),
      m_pFont(0),
      m_pFontMgr(NULL)
#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
      ,
      m_pFontSource(NULL)
#endif
{
}
CFWL_FontData::~CFWL_FontData() {
  if (m_pFont) {
    m_pFont->Release();
  }
  if (m_pFontMgr) {
    m_pFontMgr->Release();
  }
#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
  if (m_pFontSource != NULL) {
    m_pFontSource->Release();
  }
#endif
}
FX_BOOL CFWL_FontData::Equal(const CFX_WideStringC& wsFontFamily,
                             FX_DWORD dwFontStyles,
                             FX_WORD wCodePage) {
  return m_wsFamily == wsFontFamily && m_dwStyles == dwFontStyles &&
         m_dwCodePage == wCodePage;
}
FX_BOOL CFWL_FontData::LoadFont(const CFX_WideStringC& wsFontFamily,
                                FX_DWORD dwFontStyles,
                                FX_WORD dwCodePage) {
  m_wsFamily = wsFontFamily;
  m_dwStyles = dwFontStyles;
  m_dwCodePage = dwCodePage;
  if (!m_pFontMgr) {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    m_pFontMgr = IFX_FontMgr::Create(FX_GetDefFontEnumerator());
#else
    m_pFontSource = FX_CreateDefaultFontSourceEnum();
    m_pFontMgr = IFX_FontMgr::Create(m_pFontSource);
#endif
  }
  m_pFont = IFX_Font::LoadFont(wsFontFamily.GetPtr(), dwFontStyles, dwCodePage,
                               m_pFontMgr);
  return m_pFont != NULL;
}

CFWL_FontManager* CFWL_FontManager::s_FontManager = nullptr;
CFWL_FontManager* CFWL_FontManager::GetInstance() {
  if (!s_FontManager)
    s_FontManager = new CFWL_FontManager;
  return s_FontManager;
}
void CFWL_FontManager::DestroyInstance() {
  delete s_FontManager;
  s_FontManager = nullptr;
}
CFWL_FontManager::CFWL_FontManager() {}
CFWL_FontManager::~CFWL_FontManager() {}
IFX_Font* CFWL_FontManager::FindFont(const CFX_WideStringC& wsFontFamily,
                                     FX_DWORD dwFontStyles,
                                     FX_WORD wCodePage) {
  for (const auto& pData : m_FontsArray) {
    if (pData->Equal(wsFontFamily, dwFontStyles, wCodePage))
      return pData->GetFont();
  }
  std::unique_ptr<CFWL_FontData> pFontData(new CFWL_FontData);
  if (!pFontData->LoadFont(wsFontFamily, dwFontStyles, wCodePage))
    return nullptr;
  m_FontsArray.push_back(std::move(pFontData));
  return m_FontsArray.back()->GetFont();
}
FX_BOOL FWLTHEME_Init() {
  return TRUE;
}
void FWLTHEME_Release() {
  CFWL_ArrowData::DestroyInstance();
  CFWL_FontManager::DestroyInstance();
}
FX_DWORD FWL_GetThemeLayout(FX_DWORD dwThemeID) {
  return 0xffff0000 & dwThemeID;
}
FX_DWORD FWL_GetThemeColor(FX_DWORD dwThemeID) {
  return 0x0000ffff & dwThemeID;
}
FX_DWORD FWL_MakeThemeID(FX_DWORD dwLayout, FX_DWORD dwColor) {
  return (dwLayout << 16) | (0x0000FFFF & dwColor);
}
CFWL_ArrowData* CFWL_ArrowData::m_pInstance = NULL;
CFWL_ArrowData* CFWL_ArrowData::GetInstance() {
  if (!m_pInstance) {
    m_pInstance = new CFWL_ArrowData;
  }
  return m_pInstance;
}
FX_BOOL CFWL_ArrowData::IsInstance() {
  return (m_pInstance != NULL);
}
void CFWL_ArrowData::DestroyInstance() {
  if (m_pInstance) {
    delete m_pInstance;
    m_pInstance = NULL;
  }
}
CFWL_ArrowData::~CFWL_ArrowData() {
  if (m_pColorData) {
    delete m_pColorData;
    m_pColorData = NULL;
  }
}
void CFWL_ArrowData::SetColorData(FX_DWORD dwID) {
  if (!m_pColorData) {
    m_pColorData = new CColorData;
  }
  if (dwID) {
    m_pColorData->clrBorder[0] = ArgbEncode(255, 142, 153, 125);
    m_pColorData->clrBorder[1] = ArgbEncode(255, 157, 171, 119);
    m_pColorData->clrBorder[2] = ArgbEncode(255, 118, 131, 97);
    m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
    m_pColorData->clrStart[0] = ArgbEncode(255, 203, 215, 186);
    m_pColorData->clrStart[1] = ArgbEncode(255, 218, 232, 185);
    m_pColorData->clrStart[2] = ArgbEncode(255, 203, 215, 186);
    m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
    m_pColorData->clrEnd[0] = ArgbEncode(255, 149, 167, 117);
    m_pColorData->clrEnd[1] = ArgbEncode(255, 198, 211, 155);
    m_pColorData->clrEnd[2] = ArgbEncode(255, 149, 167, 117);
    m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
    m_pColorData->clrSign[0] = ArgbEncode(255, 255, 255, 255);
    m_pColorData->clrSign[1] = ArgbEncode(255, 255, 255, 255);
    m_pColorData->clrSign[2] = ArgbEncode(255, 255, 255, 255);
    m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
  } else {
    m_pColorData->clrBorder[0] = ArgbEncode(255, 202, 216, 249);
    m_pColorData->clrBorder[1] = ArgbEncode(255, 171, 190, 233);
    m_pColorData->clrBorder[2] = ArgbEncode(255, 135, 147, 219);
    m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
    m_pColorData->clrStart[0] = ArgbEncode(255, 225, 234, 254);
    m_pColorData->clrStart[1] = ArgbEncode(255, 253, 255, 255);
    m_pColorData->clrStart[2] = ArgbEncode(255, 110, 142, 241);
    m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
    m_pColorData->clrEnd[0] = ArgbEncode(255, 175, 204, 251);
    m_pColorData->clrEnd[1] = ArgbEncode(255, 185, 218, 251);
    m_pColorData->clrEnd[2] = ArgbEncode(255, 210, 222, 235);
    m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
    m_pColorData->clrSign[0] = ArgbEncode(255, 77, 97, 133);
    m_pColorData->clrSign[1] = ArgbEncode(255, 77, 97, 133);
    m_pColorData->clrSign[2] = ArgbEncode(255, 77, 97, 133);
    m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
  }
}
