// 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/app/xfa_ffwidget.h"

#include <algorithm>

#include "core/include/fpdfapi/fpdf_page.h"
#include "core/include/fxcodec/fx_codec.h"
#include "xfa/fxfa/app/xfa_ffapp.h"
#include "xfa/fxfa/app/xfa_ffdoc.h"
#include "xfa/fxfa/app/xfa_ffdocview.h"
#include "xfa/fxfa/app/xfa_ffpageview.h"
#include "xfa/fxfa/app/xfa_textlayout.h"
#include "xfa/include/fxgraphics/fx_graphics.h"

CXFA_FFWidget::CXFA_FFWidget(CXFA_FFPageView* pPageView,
                             CXFA_WidgetAcc* pDataAcc)
    : CXFA_ContentLayoutItem(pDataAcc->GetNode()),
      m_pPageView(pPageView),
      m_pDataAcc(pDataAcc) {
  m_rtWidget.Set(0, 0, 0, 0);
}
CXFA_FFWidget::~CXFA_FFWidget() {}
IXFA_PageView* CXFA_FFWidget::GetPageView() {
  return m_pPageView;
}
void CXFA_FFWidget::SetPageView(IXFA_PageView* pPageView) {
  m_pPageView = static_cast<CXFA_FFPageView*>(pPageView);
}
void CXFA_FFWidget::GetWidgetRect(CFX_RectF& rtWidget) {
  if ((m_dwStatus & XFA_WIDGETSTATUS_RectCached) == 0) {
    m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
    GetRect(m_rtWidget);
  }
  rtWidget = m_rtWidget;
}
CFX_RectF CXFA_FFWidget::ReCacheWidgetRect() {
  m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
  GetRect(m_rtWidget);
  return m_rtWidget;
}
void CXFA_FFWidget::GetRectWithoutRotate(CFX_RectF& rtWidget) {
  GetWidgetRect(rtWidget);
  FX_FLOAT fValue = 0;
  switch (m_pDataAcc->GetRotate()) {
    case 90:
      rtWidget.top = rtWidget.bottom();
      fValue = rtWidget.width;
      rtWidget.width = rtWidget.height;
      rtWidget.height = fValue;
      break;
    case 180:
      rtWidget.left = rtWidget.right();
      rtWidget.top = rtWidget.bottom();
      break;
    case 270:
      rtWidget.left = rtWidget.right();
      fValue = rtWidget.width;
      rtWidget.width = rtWidget.height;
      rtWidget.height = fValue;
      break;
  }
}
FX_DWORD CXFA_FFWidget::GetStatus() {
  return m_dwStatus;
}

void CXFA_FFWidget::ModifyStatus(FX_DWORD dwAdded, FX_DWORD dwRemoved) {
  m_dwStatus = (m_dwStatus & ~dwRemoved) | dwAdded;
}

FX_BOOL CXFA_FFWidget::GetBBox(CFX_RectF& rtBox,
                               FX_DWORD dwStatus,
                               FX_BOOL bDrawFocus) {
  if (bDrawFocus)
    return FALSE;
  if (m_pPageView)
    m_pPageView->GetPageViewRect(rtBox);
  return TRUE;
}

CXFA_WidgetAcc* CXFA_FFWidget::GetDataAcc() {
  return m_pDataAcc;
}
FX_BOOL CXFA_FFWidget::GetToolTip(CFX_WideString& wsToolTip) {
  if (CXFA_Assist assist = m_pDataAcc->GetAssist()) {
    if (CXFA_ToolTip toolTip = assist.GetToolTip()) {
      return toolTip.GetTip(wsToolTip);
    }
  }
  return GetCaptionText(wsToolTip);
}
void CXFA_FFWidget::RenderWidget(CFX_Graphics* pGS,
                                 CFX_Matrix* pMatrix,
                                 FX_DWORD dwStatus,
                                 int32_t iRotate) {
  if (!IsMatchVisibleStatus(dwStatus)) {
    return;
  }
  CXFA_Border border = m_pDataAcc->GetBorder();
  if (border) {
    CFX_RectF rtBorder;
    GetRectWithoutRotate(rtBorder);
    CXFA_Margin margin = border.GetMargin();
    if (margin) {
      XFA_RectWidthoutMargin(rtBorder, margin);
    }
    rtBorder.Normalize();
    DrawBorder(pGS, border, rtBorder, pMatrix);
  }
}
FX_BOOL CXFA_FFWidget::IsLoaded() {
  return m_pPageView != NULL;
}
FX_BOOL CXFA_FFWidget::LoadWidget() {
  PerformLayout();
  return TRUE;
}
void CXFA_FFWidget::UnloadWidget() {}
FX_BOOL CXFA_FFWidget::PerformLayout() {
  ReCacheWidgetRect();
  return TRUE;
}
FX_BOOL CXFA_FFWidget::UpdateFWLData() {
  return FALSE;
}
void CXFA_FFWidget::UpdateWidgetProperty() {}
void CXFA_FFWidget::DrawBorder(CFX_Graphics* pGS,
                               CXFA_Box box,
                               const CFX_RectF& rtBorder,
                               CFX_Matrix* pMatrix,
                               FX_DWORD dwFlags) {
  XFA_DrawBox(box, pGS, rtBorder, pMatrix, dwFlags);
}
void CXFA_FFWidget::InvalidateWidget(const CFX_RectF* pRect) {
  if (!pRect) {
    CFX_RectF rtWidget;
    GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
    rtWidget.Inflate(2, 2);
    GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, rtWidget,
                                               XFA_INVALIDATE_CurrentPage);
  } else {
    GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, *pRect,
                                               XFA_INVALIDATE_CurrentPage);
  }
}
void CXFA_FFWidget::AddInvalidateRect(const CFX_RectF* pRect) {
  CFX_RectF rtWidget;
  if (pRect) {
    rtWidget = *pRect;
  } else {
    GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
    rtWidget.Inflate(2, 2);
  }
  m_pDocView->AddInvalidateRect(m_pPageView, rtWidget);
}
FX_BOOL CXFA_FFWidget::GetCaptionText(CFX_WideString& wsCap) {
  CXFA_TextLayout* pCapTextlayout = m_pDataAcc->GetCaptionTextLayout();
  if (!pCapTextlayout) {
    return FALSE;
  }
  pCapTextlayout->GetText(wsCap);
  return TRUE;
}
FX_BOOL CXFA_FFWidget::IsFocused() {
  return m_dwStatus & XFA_WIDGETSTATUS_Focused;
}
FX_BOOL CXFA_FFWidget::OnMouseEnter() {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnMouseExit() {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnLButtonDown(FX_DWORD dwFlags,
                                     FX_FLOAT fx,
                                     FX_FLOAT fy) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnLButtonDblClk(FX_DWORD dwFlags,
                                       FX_FLOAT fx,
                                       FX_FLOAT fy) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnMouseWheel(FX_DWORD dwFlags,
                                    int16_t zDelta,
                                    FX_FLOAT fx,
                                    FX_FLOAT fy) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnRButtonDown(FX_DWORD dwFlags,
                                     FX_FLOAT fx,
                                     FX_FLOAT fy) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnRButtonDblClk(FX_DWORD dwFlags,
                                       FX_FLOAT fx,
                                       FX_FLOAT fy) {
  return FALSE;
}

FX_BOOL CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
  CXFA_FFWidget* pParent = GetParent();
  if (pParent && !pParent->IsAncestorOf(pOldWidget)) {
    pParent->OnSetFocus(pOldWidget);
  }
  m_dwStatus |= XFA_WIDGETSTATUS_Focused;
  CXFA_EventParam eParam;
  eParam.m_eType = XFA_EVENT_Enter;
  eParam.m_pTarget = m_pDataAcc;
  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Enter, &eParam);
  return TRUE;
}
FX_BOOL CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
  m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
  EventKillFocus();
  if (pNewWidget) {
    CXFA_FFWidget* pParent = GetParent();
    if (pParent && !pParent->IsAncestorOf(pNewWidget)) {
      pParent->OnKillFocus(pNewWidget);
    }
  }
  return TRUE;
}
FX_BOOL CXFA_FFWidget::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags) {
  return FALSE;
}
FX_DWORD CXFA_FFWidget::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
  return FALSE;
}
FX_BOOL CXFA_FFWidget::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) {
  return FALSE;
}
void CXFA_FFWidget::Rotate2Normal(FX_FLOAT& fx, FX_FLOAT& fy) {
  CFX_Matrix mt;
  GetRotateMatrix(mt);
  if (mt.IsIdentity()) {
    return;
  }
  CFX_Matrix mtReverse;
  mtReverse.SetReverse(mt);
  mtReverse.TransformPoint(fx, fy);
}
static void XFA_GetMatrix(CFX_Matrix& m,
                          int32_t iRotate,
                          int32_t at,
                          const CFX_RectF& rt) {
  if (!iRotate) {
    return;
  }
  FX_FLOAT fAnchorX, fAnchorY;
  switch (at) {
    case XFA_ATTRIBUTEENUM_TopLeft:
      fAnchorX = rt.left, fAnchorY = rt.top;
      break;
    case XFA_ATTRIBUTEENUM_TopCenter:
      fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.top;
      break;
    case XFA_ATTRIBUTEENUM_TopRight:
      fAnchorX = rt.right(), fAnchorY = rt.top;
      break;
    case XFA_ATTRIBUTEENUM_MiddleLeft:
      fAnchorX = rt.left, fAnchorY = (rt.top + rt.bottom()) / 2;
      break;
    case XFA_ATTRIBUTEENUM_MiddleCenter:
      fAnchorX = (rt.left + rt.right()) / 2,
      fAnchorY = (rt.top + rt.bottom()) / 2;
      break;
    case XFA_ATTRIBUTEENUM_MiddleRight:
      fAnchorX = rt.right(), fAnchorY = (rt.top + rt.bottom()) / 2;
      break;
    case XFA_ATTRIBUTEENUM_BottomLeft:
      fAnchorX = rt.left, fAnchorY = rt.bottom();
      break;
    case XFA_ATTRIBUTEENUM_BottomCenter:
      fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.bottom();
      break;
    case XFA_ATTRIBUTEENUM_BottomRight:
      fAnchorX = rt.right(), fAnchorY = rt.bottom();
      break;
  }
  switch (iRotate) {
    case 90:
      m.a = 0, m.b = -1, m.c = 1, m.d = 0, m.e = fAnchorX - fAnchorY,
      m.f = fAnchorX + fAnchorY;
      break;
    case 180:
      m.a = -1, m.b = 0, m.c = 0, m.d = -1, m.e = fAnchorX * 2,
      m.f = fAnchorY * 2;
      break;
    case 270:
      m.a = 0, m.b = 1, m.c = -1, m.d = 0, m.e = fAnchorX + fAnchorY,
      m.f = fAnchorY - fAnchorX;
      break;
  }
}
void CXFA_FFWidget::GetRotateMatrix(CFX_Matrix& mt) {
  mt.Set(1, 0, 0, 1, 0, 0);
  int32_t iRotate = m_pDataAcc->GetRotate();
  if (!iRotate) {
    return;
  }
  CFX_RectF rcWidget;
  GetRectWithoutRotate(rcWidget);
  XFA_ATTRIBUTEENUM at = XFA_ATTRIBUTEENUM_TopLeft;
  XFA_GetMatrix(mt, iRotate, at, rcWidget);
}
FX_BOOL CXFA_FFWidget::IsLayoutRectEmpty() {
  CFX_RectF rtLayout;
  GetRectWithoutRotate(rtLayout);
  return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
}
CXFA_FFWidget* CXFA_FFWidget::GetParent() {
  CXFA_Node* pParentNode =
      m_pDataAcc->GetNode()->GetNodeItem(XFA_NODEITEM_Parent);
  if (pParentNode) {
    CXFA_WidgetAcc* pParentWidgetAcc =
        (CXFA_WidgetAcc*)pParentNode->GetWidgetData();
    if (pParentWidgetAcc) {
      return pParentWidgetAcc->GetNextWidget(NULL);
    }
  }
  return NULL;
}
FX_BOOL CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
  if (!pWidget) {
    return FALSE;
  }
  CXFA_Node* pNode = m_pDataAcc->GetNode();
  CXFA_Node* pChildNode = pWidget->GetDataAcc()->GetNode();
  while (pChildNode) {
    if (pChildNode == pNode) {
      return TRUE;
    }
    pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_Parent);
  }
  return FALSE;
}
FX_BOOL CXFA_FFWidget::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
  CFX_RectF rtWidget;
  GetWidgetRect(rtWidget);
  if (rtWidget.Contains(fx, fy)) {
    return TRUE;
  }
  return FALSE;
}
CXFA_FFDocView* CXFA_FFWidget::GetDocView() {
  return m_pDocView;
}
CXFA_FFDoc* CXFA_FFWidget::GetDoc() {
  return (CXFA_FFDoc*)m_pDocView->GetDoc();
}
CXFA_FFApp* CXFA_FFWidget::GetApp() {
  return GetDoc()->GetApp();
}
IXFA_AppProvider* CXFA_FFWidget::GetAppProvider() {
  return GetApp()->GetAppProvider();
}
void CXFA_FFWidget::GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth) {
  fMinWidth = fMaxWidth = 0;
  FX_FLOAT fWidth = 0;
  if (m_pDataAcc->GetWidth(fWidth)) {
    fMinWidth = fMaxWidth = fWidth;
  } else {
    m_pDataAcc->GetMinWidth(fMinWidth);
    m_pDataAcc->GetMaxWidth(fMaxWidth);
  }
}
void CXFA_FFWidget::GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight) {
  fMinHeight = fMaxHeight = 0;
  FX_FLOAT fHeight = 0;
  if (m_pDataAcc->GetHeight(fHeight)) {
    fMinHeight = fMaxHeight = fHeight;
  } else {
    m_pDataAcc->GetMinHeight(fMinHeight);
    m_pDataAcc->GetMaxHeight(fMaxHeight);
  }
}
FX_BOOL CXFA_FFWidget::IsMatchVisibleStatus(FX_DWORD dwStatus) {
  return m_dwStatus & XFA_WIDGETSTATUS_Visible;
}
void CXFA_FFWidget::EventKillFocus() {
  if (m_dwStatus & XFA_WIDGETSTATUS_Access) {
    m_dwStatus &= ~XFA_WIDGETSTATUS_Access;
    return;
  }
  CXFA_EventParam eParam;
  eParam.m_eType = XFA_EVENT_Exit;
  eParam.m_pTarget = m_pDataAcc;
  m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Exit, &eParam);
}
FX_BOOL CXFA_FFWidget::IsButtonDown() {
  return (m_dwStatus & XFA_WIDGETSTATUS_ButtonDown) != 0;
}
void CXFA_FFWidget::SetButtonDown(FX_BOOL bSet) {
  bSet ? m_dwStatus |= XFA_WIDGETSTATUS_ButtonDown
       : m_dwStatus &= ~XFA_WIDGETSTATUS_ButtonDown;
}
int32_t XFA_StrokeTypeSetLineDash(CFX_Graphics* pGraphics,
                                  int32_t iStrokeType,
                                  int32_t iCapType) {
  switch (iStrokeType) {
    case XFA_ATTRIBUTEENUM_DashDot: {
      FX_FLOAT dashArray[] = {4, 1, 2, 1};
      if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
        dashArray[1] = 2;
        dashArray[3] = 2;
      }
      pGraphics->SetLineDash(0, dashArray, 4);
      return FX_DASHSTYLE_DashDot;
    }
    case XFA_ATTRIBUTEENUM_DashDotDot: {
      FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
      if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
        dashArray[1] = 2;
        dashArray[3] = 2;
        dashArray[5] = 2;
      }
      pGraphics->SetLineDash(0, dashArray, 6);
      return FX_DASHSTYLE_DashDotDot;
    }
    case XFA_ATTRIBUTEENUM_Dashed: {
      FX_FLOAT dashArray[] = {5, 1};
      if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
        dashArray[1] = 2;
      }
      pGraphics->SetLineDash(0, dashArray, 2);
      return FX_DASHSTYLE_Dash;
    }
    case XFA_ATTRIBUTEENUM_Dotted: {
      FX_FLOAT dashArray[] = {2, 1};
      if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
        dashArray[1] = 2;
      }
      pGraphics->SetLineDash(0, dashArray, 2);
      return FX_DASHSTYLE_Dot;
    }
    default:
      break;
  }
  pGraphics->SetLineDash(FX_DASHSTYLE_Solid);
  return FX_DASHSTYLE_Solid;
}
CFX_GraphStateData::LineCap XFA_LineCapToFXGE(int32_t iLineCap) {
  switch (iLineCap) {
    case XFA_ATTRIBUTEENUM_Round:
      return CFX_GraphStateData::LineCapRound;
    case XFA_ATTRIBUTEENUM_Butt:
      return CFX_GraphStateData::LineCapButt;
    default:
      break;
  }
  return CFX_GraphStateData::LineCapSquare;
}
class CXFA_ImageRenderer {
 public:
  CXFA_ImageRenderer();
  ~CXFA_ImageRenderer();
  FX_BOOL Start(CFX_RenderDevice* pDevice,
                CFX_DIBSource* pDIBSource,
                FX_ARGB bitmap_argb,
                int bitmap_alpha,
                const CFX_Matrix* pImage2Device,
                FX_DWORD flags,
                int blendType = FXDIB_BLEND_NORMAL);
  FX_BOOL Continue(IFX_Pause* pPause);

 protected:
  CFX_RenderDevice* m_pDevice;
  int m_Status;
  CFX_Matrix m_ImageMatrix;
  CFX_DIBSource* m_pDIBSource;
  CFX_DIBitmap* m_pCloneConvert;
  int m_BitmapAlpha;
  FX_ARGB m_FillArgb;
  FX_DWORD m_Flags;
  CFX_ImageTransformer* m_pTransformer;
  void* m_DeviceHandle;
  int32_t m_BlendType;
  FX_BOOL m_Result;
  FX_BOOL m_bPrint;
  FX_BOOL StartDIBSource();
  void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
                         int left,
                         int top,
                         FX_ARGB mask_argb,
                         int bitmap_alpha,
                         int blend_mode,
                         int Transparency);
};
CXFA_ImageRenderer::CXFA_ImageRenderer() {
  m_pDevice = NULL;
  m_Status = 0;
  m_pDIBSource = NULL;
  m_pCloneConvert = NULL;
  m_BitmapAlpha = 255;
  m_FillArgb = 0;
  m_Flags = 0;
  m_pTransformer = NULL;
  m_DeviceHandle = NULL;
  m_BlendType = FXDIB_BLEND_NORMAL;
  m_Result = TRUE;
  m_bPrint = FALSE;
}
CXFA_ImageRenderer::~CXFA_ImageRenderer() {
  if (m_pCloneConvert) {
    delete m_pCloneConvert;
  }
  if (m_pTransformer) {
    delete m_pTransformer;
  }
  if (m_DeviceHandle) {
    m_pDevice->CancelDIBits(m_DeviceHandle);
  }
}
FX_BOOL CXFA_ImageRenderer::Start(CFX_RenderDevice* pDevice,
                                  CFX_DIBSource* pDIBSource,
                                  FX_ARGB bitmap_argb,
                                  int bitmap_alpha,
                                  const CFX_Matrix* pImage2Device,
                                  FX_DWORD flags,
                                  int blendType) {
  m_pDevice = pDevice;
  m_pDIBSource = pDIBSource;
  m_FillArgb = bitmap_argb;
  m_BitmapAlpha = bitmap_alpha;
  m_ImageMatrix = *pImage2Device;
  m_Flags = flags;
  m_BlendType = blendType;
  return StartDIBSource();
}
FX_BOOL CXFA_ImageRenderer::StartDIBSource() {
  if (m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb,
                             &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL,
                             m_BlendType)) {
    if (m_DeviceHandle) {
      m_Status = 3;
      return TRUE;
    }
    return FALSE;
  }
  CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
  FX_RECT image_rect = image_rect_f.GetOutterRect();
  int dest_width = image_rect.Width();
  int dest_height = image_rect.Height();
  if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
      (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) {
    if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
      m_Result = FALSE;
      return FALSE;
    }
    CFX_DIBSource* pDib = m_pDIBSource;
    if (m_pDIBSource->HasAlpha() &&
        !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE) &&
        !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
      m_pCloneConvert = m_pDIBSource->CloneConvert(FXDIB_Rgb);
      if (!m_pCloneConvert) {
        m_Result = FALSE;
        return FALSE;
      }
      pDib = m_pCloneConvert;
    }
    FX_RECT clip_box = m_pDevice->GetClipBox();
    clip_box.Intersect(image_rect);
    m_Status = 2;
    m_pTransformer = new CFX_ImageTransformer;
    m_pTransformer->Start(pDib, &m_ImageMatrix, m_Flags, &clip_box);
    return TRUE;
  }
  if (m_ImageMatrix.a < 0) {
    dest_width = -dest_width;
  }
  if (m_ImageMatrix.d > 0) {
    dest_height = -dest_height;
  }
  int dest_left, dest_top;
  dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
  dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
  if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
    if (m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top, dest_width,
                                 dest_height, m_Flags, NULL, m_BlendType)) {
      return FALSE;
    }
  }
  if (m_pDIBSource->IsAlphaMask()) {
    if (m_BitmapAlpha != 255) {
      m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
    }
    if (m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width,
                                  dest_height, m_FillArgb, m_Flags)) {
      return FALSE;
    }
  }
  if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
    m_Result = FALSE;
    return TRUE;
  }
  FX_RECT clip_box = m_pDevice->GetClipBox();
  FX_RECT dest_rect = clip_box;
  dest_rect.Intersect(image_rect);
  FX_RECT dest_clip(
      dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
      dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
  CFX_DIBitmap* pStretched =
      m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip);
  if (pStretched) {
    CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb,
                      m_BitmapAlpha, m_BlendType, FALSE);
    delete pStretched;
    pStretched = NULL;
  }
  return FALSE;
}
FX_BOOL CXFA_ImageRenderer::Continue(IFX_Pause* pPause) {
  if (m_Status == 2) {
    if (m_pTransformer->Continue(pPause)) {
      return TRUE;
    }
    CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
    if (pBitmap == NULL) {
      return FALSE;
    }
    if (pBitmap->IsAlphaMask()) {
      if (m_BitmapAlpha != 255) {
        m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
      }
      m_Result = m_pDevice->SetBitMask(pBitmap, m_pTransformer->m_ResultLeft,
                                       m_pTransformer->m_ResultTop, m_FillArgb);
    } else {
      if (m_BitmapAlpha != 255) {
        pBitmap->MultiplyAlpha(m_BitmapAlpha);
      }
      m_Result = m_pDevice->SetDIBits(pBitmap, m_pTransformer->m_ResultLeft,
                                      m_pTransformer->m_ResultTop, m_BlendType);
    }
    delete pBitmap;
    return FALSE;
  } else if (m_Status == 3) {
    return m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
  }
  return FALSE;
}
void CXFA_ImageRenderer::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
                                           int left,
                                           int top,
                                           FX_ARGB mask_argb,
                                           int bitmap_alpha,
                                           int blend_mode,
                                           int Transparency) {
  if (pDIBitmap == NULL) {
    return;
  }
  FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
  FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
  if (blend_mode == FXDIB_BLEND_NORMAL) {
    if (!pDIBitmap->IsAlphaMask()) {
      if (bitmap_alpha < 255) {
        pDIBitmap->MultiplyAlpha(bitmap_alpha);
      }
      if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
        return;
      }
    } else {
      FX_DWORD fill_argb = (mask_argb);
      if (bitmap_alpha < 255) {
        ((uint8_t*)&fill_argb)[3] =
            ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
      }
      if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
        return;
      }
    }
  }
  FX_BOOL bBackAlphaRequired = blend_mode && bIsolated;
  FX_BOOL bGetBackGround =
      ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
      (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
       (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired);
  if (bGetBackGround) {
    if (bIsolated || !bGroup) {
      if (pDIBitmap->IsAlphaMask()) {
        return;
      }
      m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
    } else {
      FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
                   top + pDIBitmap->GetHeight());
      rect.Intersect(m_pDevice->GetClipBox());
      CFX_DIBitmap* pClone = NULL;
      FX_BOOL bClone = FALSE;
      if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
        bClone = TRUE;
        pClone = m_pDevice->GetBackDrop()->Clone(&rect);
        CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap();
        pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                pForeBitmap, rect.left, rect.top);
        left = left >= 0 ? 0 : left;
        top = top >= 0 ? 0 : top;
        if (!pDIBitmap->IsAlphaMask())
          pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                  pDIBitmap, left, top, blend_mode);
        else
          pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(),
                                pDIBitmap, mask_argb, left, top, blend_mode);
      } else {
        pClone = pDIBitmap;
      }
      if (m_pDevice->GetBackDrop()) {
        m_pDevice->SetDIBits(pClone, rect.left, rect.top);
      } else {
        if (pDIBitmap->IsAlphaMask()) {
          return;
        }
        m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
      }
      if (bClone) {
        delete pClone;
      }
    }
    return;
  }
  if (pDIBitmap->HasAlpha() &&
      !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE)) {
    CFX_DIBitmap* pCloneConvert = pDIBitmap->CloneConvert(FXDIB_Rgb);
    if (!pCloneConvert) {
      return;
    }
    CXFA_ImageRenderer imageRender;
    FX_BOOL bRet = imageRender.Start(m_pDevice, pCloneConvert, m_FillArgb,
                                     m_BitmapAlpha, &m_ImageMatrix, m_Flags);
    while (bRet) {
      bRet = imageRender.Continue(NULL);
    }
    delete pCloneConvert;
    return;
  }
}
void XFA_DrawImage(CFX_Graphics* pGS,
                   const CFX_RectF& rtImage,
                   CFX_Matrix* pMatrix,
                   CFX_DIBitmap* pDIBitmap,
                   int32_t iAspect,
                   int32_t iImageXDpi,
                   int32_t iImageYDpi,
                   int32_t iHorzAlign,
                   int32_t iVertAlign) {
  if (rtImage.IsEmpty()) {
    return;
  }
  if (!pDIBitmap || !pDIBitmap->GetBuffer()) {
    return;
  }
  FX_FLOAT fWidth =
      XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
  FX_FLOAT fHeight =
      XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
  CFX_RectF rtFit;
  rtFit.Set(rtImage.left, rtImage.top, fWidth, fHeight);
  switch (iAspect) {
    case XFA_ATTRIBUTEENUM_Fit: {
      FX_FLOAT f1 = rtImage.height / rtFit.height;
      FX_FLOAT f2 = rtImage.width / rtFit.width;
      f1 = std::min(f1, f2);
      rtFit.height = rtFit.height * f1;
      rtFit.width = rtFit.width * f1;
    } break;
    case XFA_ATTRIBUTEENUM_Actual:
      break;
    case XFA_ATTRIBUTEENUM_Height: {
      FX_FLOAT f1 = rtImage.height / rtFit.height;
      rtFit.height = rtImage.height;
      rtFit.width = f1 * rtFit.width;
    } break;
    case XFA_ATTRIBUTEENUM_None:
      rtFit.height = rtImage.height;
      rtFit.width = rtImage.width;
      break;
    case XFA_ATTRIBUTEENUM_Width: {
      FX_FLOAT f1 = rtImage.width / rtFit.width;
      rtFit.width = rtImage.width;
      rtFit.height = rtFit.height * f1;
    } break;
  }
  if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
    rtFit.left += (rtImage.width - rtFit.width) / 2;
  } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
    rtFit.left = rtImage.right() - rtFit.width;
  }
  if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
    rtFit.top += (rtImage.height - rtFit.height) / 2;
  } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
    rtFit.top = rtImage.bottom() - rtImage.height;
  }
  CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
  pRenderDevice->SaveState();
  CFX_PathData path;
  path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
  pRenderDevice->SetClip_PathFill(&path, pMatrix, FXFILL_WINDING);
  CFX_Matrix mtImage(1, 0, 0, -1, 0, 1);
  mtImage.Concat(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top);
  mtImage.Concat(*pMatrix);
  CXFA_ImageRenderer imageRender;
  FX_BOOL bRet = imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage,
                                   FXDIB_INTERPOL);
  while (bRet) {
    bRet = imageRender.Continue(NULL);
  }
  pRenderDevice->RestoreState();
}

static const uint8_t g_inv_base64[128] = {
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62,  255,
    255, 255, 63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  255, 255,
    255, 255, 255, 255, 255, 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
    10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,
    25,  255, 255, 255, 255, 255, 255, 26,  27,  28,  29,  30,  31,  32,  33,
    34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
    49,  50,  51,  255, 255, 255, 255, 255,
};

static uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
  uint8_t* pCP;
  int32_t i = 0, j = 0;
  if (iLen == 0) {
    iLen = FXSYS_strlen((FX_CHAR*)pStr);
  }
  pCP = FX_Alloc(uint8_t, iLen + 1);
  for (; i < iLen; i++) {
    if ((pStr[i] & 128) == 0) {
      if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
        pCP[j++] = pStr[i];
      }
    }
  }
  pCP[j] = '\0';
  return pCP;
}
static int32_t XFA_Base64Decode(const FX_CHAR* pStr, uint8_t* pOutBuffer) {
  if (pStr == NULL) {
    return 0;
  }
  uint8_t* pBuffer =
      XFA_RemoveBase64Whitespace((uint8_t*)pStr, FXSYS_strlen((FX_CHAR*)pStr));
  if (pBuffer == NULL) {
    return 0;
  }
  int32_t iLen = FXSYS_strlen((FX_CHAR*)pBuffer);
  int32_t i = 0, j = 0;
  FX_DWORD dwLimb = 0;
  for (; i + 3 < iLen; i += 4) {
    if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
        pBuffer[i + 3] == '=') {
      if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
        break;
      }
      if (pBuffer[i + 2] == '=') {
        dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 6) |
                 ((FX_DWORD)g_inv_base64[pBuffer[i + 1]]);
        pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
        j++;
      } else {
        dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 12) |
                 ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 6) |
                 ((FX_DWORD)g_inv_base64[pBuffer[i + 2]]);
        pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
        pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
        j += 2;
      }
    } else {
      dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 18) |
               ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 12) |
               ((FX_DWORD)g_inv_base64[pBuffer[i + 2]] << 6) |
               ((FX_DWORD)g_inv_base64[pBuffer[i + 3]]);
      pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
      pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
      pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
      j += 3;
    }
  }
  FX_Free(pBuffer);
  return j;
}
static FX_CHAR g_base64_chars[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
FX_CHAR* XFA_Base64Encode(const uint8_t* buf, int32_t buf_len) {
  FX_CHAR* out = NULL;
  int i, j;
  FX_DWORD limb;
  out = FX_Alloc(FX_CHAR, ((buf_len * 8 + 5) / 6) + 5);
  for (i = 0, j = 0, limb = 0; i + 2 < buf_len; i += 3, j += 4) {
    limb = ((FX_DWORD)buf[i] << 16) | ((FX_DWORD)buf[i + 1] << 8) |
           ((FX_DWORD)buf[i + 2]);
    out[j] = g_base64_chars[(limb >> 18) & 63];
    out[j + 1] = g_base64_chars[(limb >> 12) & 63];
    out[j + 2] = g_base64_chars[(limb >> 6) & 63];
    out[j + 3] = g_base64_chars[(limb)&63];
  }
  switch (buf_len - i) {
    case 0:
      break;
    case 1:
      limb = ((FX_DWORD)buf[i]);
      out[j++] = g_base64_chars[(limb >> 2) & 63];
      out[j++] = g_base64_chars[(limb << 4) & 63];
      out[j++] = '=';
      out[j++] = '=';
      break;
    case 2:
      limb = ((FX_DWORD)buf[i] << 8) | ((FX_DWORD)buf[i + 1]);
      out[j++] = g_base64_chars[(limb >> 10) & 63];
      out[j++] = g_base64_chars[(limb >> 4) & 63];
      out[j++] = g_base64_chars[(limb << 2) & 63];
      out[j++] = '=';
      break;
    default:
      break;
  }
  out[j] = '\0';
  return out;
}
FXCODEC_IMAGE_TYPE XFA_GetImageType(const CFX_WideStringC& wsType) {
  CFX_WideString wsContentType(wsType);
  wsContentType.MakeLower();
  if (wsContentType == FX_WSTRC(L"image/jpg")) {
    return FXCODEC_IMAGE_JPG;
  }
  if (wsContentType == FX_WSTRC(L"image/png")) {
    return FXCODEC_IMAGE_PNG;
  }
  if (wsContentType == FX_WSTRC(L"image/gif")) {
    return FXCODEC_IMAGE_GIF;
  }
  if (wsContentType == FX_WSTRC(L"image/bmp")) {
    return FXCODEC_IMAGE_BMP;
  }
  if (wsContentType == FX_WSTRC(L"image/tif")) {
    return FXCODEC_IMAGE_TIF;
  }
  return FXCODEC_IMAGE_UNKNOWN;
}
CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc,
                                CXFA_Image* pImage,
                                FX_BOOL& bNameImage,
                                int32_t& iImageXDpi,
                                int32_t& iImageYDpi) {
  CFX_WideString wsHref;
  pImage->GetHref(wsHref);
  CFX_WideString wsImage;
  pImage->GetContent(wsImage);
  if (wsHref.IsEmpty() && wsImage.IsEmpty()) {
    return NULL;
  }
  CFX_WideString wsContentType;
  pImage->GetContentType(wsContentType);
  FXCODEC_IMAGE_TYPE type = XFA_GetImageType(wsContentType);
  CFX_ByteString bsContent;
  uint8_t* pImageBuffer = NULL;
  IFX_FileRead* pImageFileRead = NULL;
  if (wsImage.GetLength() > 0) {
    XFA_ATTRIBUTEENUM iEncoding =
        (XFA_ATTRIBUTEENUM)pImage->GetTransferEncoding();
    if (iEncoding == XFA_ATTRIBUTEENUM_Base64) {
      CFX_ByteString bsData = wsImage.UTF8Encode();
      int32_t iLength = bsData.GetLength();
      pImageBuffer = FX_Alloc(uint8_t, iLength);
      int32_t iRead = XFA_Base64Decode((const FX_CHAR*)bsData, pImageBuffer);
      if (iRead > 0) {
        pImageFileRead = FX_CreateMemoryStream(pImageBuffer, iRead);
      }
    } else {
      bsContent = CFX_ByteString::FromUnicode(wsImage);
      pImageFileRead = FX_CreateMemoryStream(
          (uint8_t*)(const uint8_t*)bsContent, bsContent.GetLength());
    }
  } else {
    CFX_WideString wsURL = wsHref;
    if (wsURL.Left(7) != FX_WSTRC(L"http://") &&
        wsURL.Left(6) != FX_WSTRC(L"ftp://")) {
      CFX_DIBitmap* pBitmap =
          pDoc->GetPDFNamedImage(wsURL, iImageXDpi, iImageYDpi);
      if (pBitmap) {
        bNameImage = TRUE;
        return pBitmap;
      }
    }
    pImageFileRead = pDoc->GetDocProvider()->OpenLinkedFile(pDoc, wsURL);
  }
  if (!pImageFileRead) {
    FX_Free(pImageBuffer);
    return NULL;
  }
  bNameImage = FALSE;
  CFX_DIBitmap* pBitmap =
      XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
  FX_Free(pImageBuffer);
  pImageFileRead->Release();
  return pBitmap;
}
static FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,
                                     int32_t iComponents,
                                     int32_t iBitsPerComponent) {
  FXDIB_Format dibFormat = FXDIB_Argb;
  switch (type) {
    case FXCODEC_IMAGE_BMP:
    case FXCODEC_IMAGE_JPG:
    case FXCODEC_IMAGE_TIF: {
      dibFormat = FXDIB_Rgb32;
      int32_t bpp = iComponents * iBitsPerComponent;
      if (bpp <= 24) {
        dibFormat = FXDIB_Rgb;
      }
    } break;
    case FXCODEC_IMAGE_PNG:
    default:
      break;
  }
  return dibFormat;
}
CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_FileRead* pImageFileRead,
                                      FXCODEC_IMAGE_TYPE type,
                                      int32_t& iImageXDpi,
                                      int32_t& iImageYDpi) {
  CFX_GEModule* pGeModule = CFX_GEModule::Get();
  if (!pGeModule) {
    return NULL;
  }
  CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
  if (!pCodecMgr) {
    return NULL;
  }
  CFX_DIBAttribute dibAttr;
  CFX_DIBitmap* pBitmap = NULL;
  ICodec_ProgressiveDecoder* pProgressiveDecoder =
      pCodecMgr->CreateProgressiveDecoder();
  pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr);
  switch (dibAttr.m_wDPIUnit) {
    case FXCODEC_RESUNIT_CENTIMETER:
      dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI * 2.54f);
      dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI * 2.54f);
      break;
    case FXCODEC_RESUNIT_METER:
      dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI / (FX_FLOAT)100 * 2.54f);
      dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI / (FX_FLOAT)100 * 2.54f);
      break;
    default:
      break;
  }
  iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
  iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
  if (pProgressiveDecoder->GetWidth() > 0 &&
      pProgressiveDecoder->GetHeight() > 0) {
    type = pProgressiveDecoder->GetType();
    int32_t iComponents = pProgressiveDecoder->GetNumComponents();
    int32_t iBpc = pProgressiveDecoder->GetBPC();
    FXDIB_Format dibFormat = XFA_GetDIBFormat(type, iComponents, iBpc);
    pBitmap = new CFX_DIBitmap();
    pBitmap->Create(pProgressiveDecoder->GetWidth(),
                    pProgressiveDecoder->GetHeight(), dibFormat);
    pBitmap->Clear(0xffffffff);
    int32_t nFrames;
    if ((pProgressiveDecoder->GetFrames(nFrames) ==
         FXCODEC_STATUS_DECODE_READY) &&
        (nFrames > 0)) {
      pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(),
                                       pBitmap->GetHeight());
      pProgressiveDecoder->ContinueDecode();
    }
  }
  delete pProgressiveDecoder;
  return pBitmap;
}
void XFA_RectWidthoutMargin(CFX_RectF& rt, const CXFA_Margin& mg, FX_BOOL bUI) {
  if (!mg) {
    return;
  }
  FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
  mg.GetLeftInset(fLeftInset);
  mg.GetTopInset(fTopInset);
  mg.GetRightInset(fRightInset);
  mg.GetBottomInset(fBottomInset);
  rt.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
}
CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
  XFA_ELEMENT iType = pLayoutItem->GetFormNode()->GetClassID();
  if (XFA_IsCreateWidget(iType)) {
    return static_cast<CXFA_FFWidget*>(pLayoutItem);
  }
  return nullptr;
}
FX_BOOL XFA_IsCreateWidget(XFA_ELEMENT iType) {
  return iType == XFA_ELEMENT_Field || iType == XFA_ELEMENT_Draw ||
         iType == XFA_ELEMENT_Subform || iType == XFA_ELEMENT_ExclGroup;
}
static void XFA_BOX_GetPath_Arc(CXFA_Box box,
                                CFX_RectF rtDraw,
                                CFX_Path& fillPath,
                                FX_DWORD dwFlags) {
  FX_FLOAT a, b;
  a = rtDraw.width / 2.0f;
  b = rtDraw.height / 2.0f;
  if (box.IsCircular() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
    a = b = std::min(a, b);
  }
  CFX_PointF center = rtDraw.Center();
  rtDraw.left = center.x - a;
  rtDraw.top = center.y - b;
  rtDraw.width = a + a;
  rtDraw.height = b + b;
  FX_FLOAT startAngle = 0, sweepAngle = 360;
  FX_BOOL bStart = box.GetStartAngle(startAngle);
  FX_BOOL bEnd = box.GetSweepAngle(sweepAngle);
  if (!bStart && !bEnd) {
    fillPath.AddEllipse(rtDraw);
    return;
  }
  startAngle = -startAngle * FX_PI / 180.0f;
  sweepAngle = -sweepAngle * FX_PI / 180.0f;
  fillPath.AddArc(rtDraw.left, rtDraw.top, rtDraw.width, rtDraw.height,
                  startAngle, sweepAngle);
}
static void XFA_BOX_GetPath(CXFA_Box box,
                            const CXFA_StrokeArray& strokes,
                            CFX_RectF rtWidget,
                            CFX_Path& path,
                            int32_t nIndex,
                            FX_BOOL bStart,
                            FX_BOOL bCorner) {
  FXSYS_assert(nIndex >= 0 && nIndex < 8);
  FX_BOOL bInverted, bRound;
  FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny, offsetY, offsetX,
      offsetEX, offsetEY;
  CFX_PointF cpStart, cp, cp1, cp2;
  CFX_RectF rtRadius;
  int32_t n = (nIndex & 1) ? nIndex - 1 : nIndex;
  CXFA_Corner corner1(strokes[n].GetNode());
  CXFA_Corner corner2(strokes[(n + 2) % 8].GetNode());
  fRadius1 = bCorner ? corner1.GetRadius() : 0;
  fRadius2 = bCorner ? corner2.GetRadius() : 0;
  bInverted = corner1.IsInverted();
  offsetY = 0.0f;
  offsetX = 0.0f;
  bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
  FX_FLOAT halfAfter = 0.0f;
  FX_FLOAT halfBefore = 0.0f;
  CXFA_Stroke stroke = strokes[nIndex];
  if (stroke.IsCorner()) {
    CXFA_Stroke edgeBefore = strokes[(nIndex + 1 * 8 - 1) % 8];
    CXFA_Stroke edgeAfter = strokes[nIndex + 1];
    if (stroke.IsInverted()) {
      if (!stroke.SameStyles(edgeBefore)) {
        halfBefore = edgeBefore.GetThickness() / 2;
      }
      if (!stroke.SameStyles(edgeAfter)) {
        halfAfter = edgeAfter.GetThickness() / 2;
      }
    }
  } else {
    CXFA_Stroke edgeBefore = strokes[(nIndex + 8 - 2) % 8];
    CXFA_Stroke edgeAfter = strokes[(nIndex + 2) % 8];
    if (!bRound && !bInverted) {
      { halfBefore = edgeBefore.GetThickness() / 2; }
      { halfAfter = edgeAfter.GetThickness() / 2; }
    }
  }
  offsetEX = 0.0f;
  offsetEY = 0.0f;
  if (bRound) {
    sy = FX_PI / 2;
  }
  switch (nIndex) {
    case 0:
    case 1:
      cp1 = rtWidget.TopLeft();
      cp2 = rtWidget.TopRight();
      if (nIndex == 0) {
        cpStart.x = cp1.x - halfBefore;
        cpStart.y = cp1.y + fRadius1, offsetY = -halfAfter;
      } else {
        cpStart.x = cp1.x + fRadius1 - halfBefore, cpStart.y = cp1.y,
        offsetEX = halfAfter;
      }
      vx = 1, vy = 1;
      nx = -1, ny = 0;
      if (bRound) {
        sx = bInverted ? FX_PI / 2 : FX_PI;
      } else {
        sx = 1, sy = 0;
      }
      break;
    case 2:
    case 3:
      cp1 = rtWidget.TopRight();
      cp2 = rtWidget.BottomRight();
      if (nIndex == 2) {
        cpStart.x = cp1.x - fRadius1, cpStart.y = cp1.y - halfBefore,
        offsetX = halfAfter;
      } else {
        cpStart.x = cp1.x, cpStart.y = cp1.y + fRadius1 - halfBefore,
        offsetEY = halfAfter;
      }
      vx = -1, vy = 1;
      nx = 0, ny = -1;
      if (bRound) {
        sx = bInverted ? FX_PI : FX_PI * 3 / 2;
      } else {
        sx = 0, sy = 1;
      }
      break;
    case 4:
    case 5:
      cp1 = rtWidget.BottomRight();
      cp2 = rtWidget.BottomLeft();
      if (nIndex == 4) {
        cpStart.x = cp1.x + halfBefore, cpStart.y = cp1.y - fRadius1,
        offsetY = halfAfter;
      } else {
        cpStart.x = cp1.x - fRadius1 + halfBefore, cpStart.y = cp1.y,
        offsetEX = -halfAfter;
      }
      vx = -1, vy = -1;
      nx = 1, ny = 0;
      if (bRound) {
        sx = bInverted ? FX_PI * 3 / 2 : 0;
      } else {
        sx = -1, sy = 0;
      }
      break;
    case 6:
    case 7:
      cp1 = rtWidget.BottomLeft();
      cp2 = rtWidget.TopLeft();
      if (nIndex == 6) {
        cpStart.x = cp1.x + fRadius1, cpStart.y = cp1.y + halfBefore,
        offsetX = -halfAfter;
      } else {
        cpStart.x = cp1.x, cpStart.y = cp1.y - fRadius1 + halfBefore,
        offsetEY = -halfAfter;
      }
      vx = 1, vy = -1;
      nx = 0, ny = 1;
      if (bRound) {
        sx = bInverted ? 0 : FX_PI / 2;
      } else {
        sx = 0, sy = -1;
      }
      break;
  }
  if (bStart) {
    path.MoveTo(cpStart.x, cpStart.y);
  }
  if (nIndex & 1) {
    path.LineTo(cp2.x + fRadius2 * nx + offsetEX,
                cp2.y + fRadius2 * ny + offsetEY);
    return;
  }
  if (bRound) {
    if (fRadius1 < 0) {
      sx -= FX_PI;
    }
    if (bInverted) {
      sy *= -1;
    }
    rtRadius.Set(cp1.x + offsetX * 2, cp1.y + offsetY * 2,
                 fRadius1 * 2 * vx - offsetX * 2,
                 fRadius1 * 2 * vy - offsetY * 2);
    rtRadius.Normalize();
    if (bInverted) {
      rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
    }
    path.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, rtRadius.height, sx,
               sy);
  } else {
    if (bInverted) {
      cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
    } else {
      cp = cp1;
    }
    path.LineTo(cp.x, cp.y);
    path.LineTo(cp1.x + fRadius1 * sx + offsetX,
                cp1.y + fRadius1 * sy + offsetY);
  }
}
static void XFA_BOX_GetFillPath(CXFA_Box box,
                                const CXFA_StrokeArray& strokes,
                                CFX_RectF rtWidget,
                                CFX_Path& fillPath,
                                FX_WORD dwFlags) {
  if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
    CXFA_Edge edge = box.GetEdge(0);
    FX_FLOAT fThickness = edge.GetThickness();
    if (fThickness < 0) {
      fThickness = 0;
    }
    FX_FLOAT fHalf = fThickness / 2;
    int32_t iHand = box.GetHand();
    if (iHand == XFA_ATTRIBUTEENUM_Left) {
      rtWidget.Inflate(fHalf, fHalf);
    } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
      rtWidget.Deflate(fHalf, fHalf);
    }
    XFA_BOX_GetPath_Arc(box, rtWidget, fillPath, dwFlags);
    return;
  }
  FX_BOOL bSameStyles = TRUE;
  int32_t i;
  CXFA_Stroke stroke1 = strokes[0];
  for (i = 1; i < 8; i++) {
    CXFA_Stroke stroke2 = strokes[i];
    if (!stroke1.SameStyles(stroke2)) {
      bSameStyles = FALSE;
      break;
    }
    stroke1 = stroke2;
  }
  if (bSameStyles) {
    stroke1 = strokes[0];
    for (i = 2; i < 8; i += 2) {
      CXFA_Stroke stroke2 = strokes[i];
      if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
                                           XFA_STROKE_SAMESTYLE_Corner)) {
        bSameStyles = FALSE;
        break;
      }
      stroke1 = stroke2;
    }
    if (bSameStyles) {
      stroke1 = strokes[0];
      if (stroke1.IsInverted()) {
        bSameStyles = FALSE;
      }
      if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
        bSameStyles = FALSE;
      }
    }
  }
  if (bSameStyles) {
    fillPath.AddRectangle(rtWidget.left, rtWidget.top, rtWidget.width,
                          rtWidget.height);
    return;
  }
  FX_BOOL bInverted, bRound;
  FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny;
  CFX_PointF cp, cp1, cp2;
  CFX_RectF rtRadius;
  for (int32_t i = 0; i < 8; i += 2) {
    CXFA_Corner corner1(strokes[i].GetNode());
    CXFA_Corner corner2(strokes[(i + 2) % 8].GetNode());
    fRadius1 = corner1.GetRadius();
    fRadius2 = corner2.GetRadius();
    bInverted = corner1.IsInverted();
    bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
    if (bRound) {
      sy = FX_PI / 2;
    }
    switch (i) {
      case 0:
        cp1 = rtWidget.TopLeft();
        cp2 = rtWidget.TopRight();
        vx = 1, vy = 1;
        nx = -1, ny = 0;
        if (bRound) {
          sx = bInverted ? FX_PI / 2 : FX_PI;
        } else {
          sx = 1, sy = 0;
        }
        break;
      case 2:
        cp1 = rtWidget.TopRight();
        cp2 = rtWidget.BottomRight();
        vx = -1, vy = 1;
        nx = 0, ny = -1;
        if (bRound) {
          sx = bInverted ? FX_PI : FX_PI * 3 / 2;
        } else {
          sx = 0, sy = 1;
        }
        break;
      case 4:
        cp1 = rtWidget.BottomRight();
        cp2 = rtWidget.BottomLeft();
        vx = -1, vy = -1;
        nx = 1, ny = 0;
        if (bRound) {
          sx = bInverted ? FX_PI * 3 / 2 : 0;
        } else {
          sx = -1, sy = 0;
        }
        break;
      case 6:
        cp1 = rtWidget.BottomLeft();
        cp2 = rtWidget.TopLeft();
        vx = 1, vy = -1;
        nx = 0, ny = 1;
        if (bRound) {
          sx = bInverted ? 0 : FX_PI / 2;
        } else {
          sx = 0, sy = -1;
        }
        break;
    }
    if (i == 0) {
      fillPath.MoveTo(cp1.x, cp1.y + fRadius1);
    }
    if (bRound) {
      if (fRadius1 < 0) {
        sx -= FX_PI;
      }
      if (bInverted) {
        sy *= -1;
      }
      rtRadius.Set(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy);
      rtRadius.Normalize();
      if (bInverted) {
        rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
      }
      fillPath.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width,
                     rtRadius.height, sx, sy);
    } else {
      if (bInverted) {
        cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
      } else {
        cp = cp1;
      }
      fillPath.LineTo(cp.x, cp.y);
      fillPath.LineTo(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy);
    }
    fillPath.LineTo(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny);
  }
}
static void XFA_BOX_Fill_Radial(CXFA_Box box,
                                CFX_Graphics* pGS,
                                CFX_Path& fillPath,
                                CFX_RectF rtFill,
                                CFX_Matrix* pMatrix) {
  CXFA_Fill fill = box.GetFill();
  FX_ARGB crStart, crEnd;
  crStart = fill.GetColor();
  int32_t iType = fill.GetRadial(crEnd);
  CFX_Shading shading;
  if (iType != XFA_ATTRIBUTEENUM_ToEdge) {
    FX_ARGB temp = crEnd;
    crEnd = crStart;
    crStart = temp;
  }
  shading.CreateRadial(rtFill.Center(), rtFill.Center(), 0,
                       FXSYS_sqrt(rtFill.Width() * rtFill.Width() +
                                  rtFill.Height() * rtFill.Height()) /
                           2,
                       TRUE, TRUE, crStart, crEnd);
  CFX_Color cr(&shading);
  pGS->SetFillColor(&cr);
  pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
}
static void XFA_BOX_Fill_Pattern(CXFA_Box box,
                                 CFX_Graphics* pGS,
                                 CFX_Path& fillPath,
                                 CFX_RectF rtFill,
                                 CFX_Matrix* pMatrix) {
  CXFA_Fill fill = box.GetFill();
  FX_ARGB crStart, crEnd;
  crStart = fill.GetColor();
  int32_t iType = fill.GetPattern(crEnd);
  int32_t iHatch = FX_HATCHSTYLE_Cross;
  switch (iType) {
    case XFA_ATTRIBUTEENUM_CrossDiagonal:
      iHatch = FX_HATCHSTYLE_DiagonalCross;
      break;
    case XFA_ATTRIBUTEENUM_DiagonalLeft:
      iHatch = FX_HATCHSTYLE_ForwardDiagonal;
      break;
    case XFA_ATTRIBUTEENUM_DiagonalRight:
      iHatch = FX_HATCHSTYLE_BackwardDiagonal;
      break;
    case XFA_ATTRIBUTEENUM_Horizontal:
      iHatch = FX_HATCHSTYLE_Horizontal;
      break;
    case XFA_ATTRIBUTEENUM_Vertical:
      iHatch = FX_HATCHSTYLE_Vertical;
      break;
    default:
      break;
  }
  CFX_Pattern pattern;
  pattern.Create(iHatch, crEnd, crStart);
  CFX_Color cr(&pattern);
  pGS->SetFillColor(&cr);
  pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
}
static void XFA_BOX_Fill_Linear(CXFA_Box box,
                                CFX_Graphics* pGS,
                                CFX_Path& fillPath,
                                CFX_RectF rtFill,
                                CFX_Matrix* pMatrix) {
  CXFA_Fill fill = box.GetFill();
  FX_ARGB crStart = fill.GetColor();
  FX_ARGB crEnd;
  int32_t iType = fill.GetLinear(crEnd);
  CFX_PointF ptStart;
  CFX_PointF ptEnd;
  switch (iType) {
    case XFA_ATTRIBUTEENUM_ToRight:
      ptStart = CFX_PointF(rtFill.left, rtFill.top);
      ptEnd = CFX_PointF(rtFill.right(), rtFill.top);
      break;
    case XFA_ATTRIBUTEENUM_ToBottom:
      ptStart = CFX_PointF(rtFill.left, rtFill.top);
      ptEnd = CFX_PointF(rtFill.left, rtFill.bottom());
      break;
    case XFA_ATTRIBUTEENUM_ToLeft:
      ptStart = CFX_PointF(rtFill.right(), rtFill.top);
      ptEnd = CFX_PointF(rtFill.left, rtFill.top);
      break;
    case XFA_ATTRIBUTEENUM_ToTop:
      ptStart = CFX_PointF(rtFill.left, rtFill.bottom());
      ptEnd = CFX_PointF(rtFill.left, rtFill.top);
      break;
    default:
      break;
  }
  CFX_Shading shading;
  shading.CreateAxial(ptStart, ptEnd, FALSE, FALSE, crStart, crEnd);
  CFX_Color cr(&shading);
  pGS->SetFillColor(&cr);
  pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
}
static void XFA_BOX_Fill(CXFA_Box box,
                         const CXFA_StrokeArray& strokes,
                         CFX_Graphics* pGS,
                         const CFX_RectF& rtWidget,
                         CFX_Matrix* pMatrix,
                         FX_DWORD dwFlags) {
  CXFA_Fill fill = box.GetFill();
  if (!fill || fill.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
    return;
  }
  pGS->SaveGraphState();
  CFX_Path fillPath;
  fillPath.Create();
  XFA_BOX_GetFillPath(box, strokes, rtWidget, fillPath,
                      (dwFlags & XFA_DRAWBOX_ForceRound) != 0);
  fillPath.Close();
  int32_t eType = fill.GetFillType();
  switch (eType) {
    case XFA_ELEMENT_Radial:
      XFA_BOX_Fill_Radial(box, pGS, fillPath, rtWidget, pMatrix);
      break;
    case XFA_ELEMENT_Pattern:
      XFA_BOX_Fill_Pattern(box, pGS, fillPath, rtWidget, pMatrix);
      break;
    case XFA_ELEMENT_Linear:
      XFA_BOX_Fill_Linear(box, pGS, fillPath, rtWidget, pMatrix);
      break;
    default: {
      FX_ARGB cr;
      if (eType == XFA_ELEMENT_Stipple) {
        int32_t iRate = fill.GetStipple(cr);
        if (iRate == 0) {
          iRate = 100;
        }
        int32_t a = 0;
        FX_COLORREF rgb;
        ArgbDecode(cr, a, rgb);
        cr = ArgbEncode(iRate * a / 100, rgb);
      } else {
        cr = fill.GetColor();
      }
      CFX_Color fillColor(cr);
      pGS->SetFillColor(&fillColor);
      pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
    } break;
  }
  pGS->RestoreGraphState();
}
static void XFA_BOX_StrokePath(CXFA_Stroke stroke,
                               CFX_Path* pPath,
                               CFX_Graphics* pGS,
                               CFX_Matrix* pMatrix) {
  if (!stroke || !stroke.IsVisible()) {
    return;
  }
  FX_FLOAT fThickness = stroke.GetThickness();
  if (fThickness < 0.001f) {
    return;
  }
  pGS->SaveGraphState();
  if (stroke.IsCorner() && fThickness > 2 * stroke.GetRadius()) {
    fThickness = 2 * stroke.GetRadius();
  }
  pGS->SetLineWidth(fThickness, TRUE);
  pGS->SetLineCap(CFX_GraphStateData::LineCapButt);
  XFA_StrokeTypeSetLineDash(pGS, stroke.GetStrokeType(),
                            XFA_ATTRIBUTEENUM_Butt);
  CFX_Color fxColor(stroke.GetColor());
  pGS->SetStrokeColor(&fxColor);
  pGS->StrokePath(pPath, pMatrix);
  pGS->RestoreGraphState();
}
static void XFA_BOX_StrokeArc(CXFA_Box box,
                              CFX_Graphics* pGS,
                              CFX_RectF rtWidget,
                              CFX_Matrix* pMatrix,
                              FX_DWORD dwFlags) {
  CXFA_Edge edge = box.GetEdge(0);
  if (!edge || !edge.IsVisible()) {
    return;
  }
  FX_BOOL bVisible = FALSE;
  FX_FLOAT fThickness = 0;
  int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
  if (i3DType) {
    if (bVisible && fThickness >= 0.001f) {
      dwFlags |= XFA_DRAWBOX_Lowered3D;
    }
  }
  FX_FLOAT fHalf = edge.GetThickness() / 2;
  if (fHalf < 0) {
    fHalf = 0;
  }
  int32_t iHand = box.GetHand();
  if (iHand == XFA_ATTRIBUTEENUM_Left) {
    rtWidget.Inflate(fHalf, fHalf);
  } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
    rtWidget.Deflate(fHalf, fHalf);
  }
  if ((dwFlags & XFA_DRAWBOX_ForceRound) == 0 ||
      (dwFlags & XFA_DRAWBOX_Lowered3D) == 0) {
    if (fHalf < 0.001f) {
      return;
    }
    CFX_Path arcPath;
    arcPath.Create();
    XFA_BOX_GetPath_Arc(box, rtWidget, arcPath, dwFlags);
    XFA_BOX_StrokePath(edge, &arcPath, pGS, pMatrix);
    return;
  }
  pGS->SaveGraphState();
  pGS->SetLineWidth(fHalf);
  FX_FLOAT a, b;
  a = rtWidget.width / 2.0f;
  b = rtWidget.height / 2.0f;
  if (dwFlags & XFA_DRAWBOX_ForceRound) {
    a = b = std::min(a, b);
  }
  CFX_PointF center = rtWidget.Center();
  rtWidget.left = center.x - a;
  rtWidget.top = center.y - b;
  rtWidget.width = a + a;
  rtWidget.height = b + b;
  FX_FLOAT startAngle = 0, sweepAngle = 360;
  startAngle = startAngle * FX_PI / 180.0f;
  sweepAngle = -sweepAngle * FX_PI / 180.0f;
  CFX_Path arcPath;
  arcPath.Create();
  arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
                 3.0f * FX_PI / 4.0f, FX_PI);
  CFX_Color cr(0xFF808080);
  pGS->SetStrokeColor(&cr);
  pGS->StrokePath(&arcPath, pMatrix);
  arcPath.Clear();
  arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
                 -1.0f * FX_PI / 4.0f, FX_PI);
  cr.Set(0xFFFFFFFF);
  pGS->SetStrokeColor(&cr);
  pGS->StrokePath(&arcPath, pMatrix);
  rtWidget.Deflate(fHalf, fHalf);
  arcPath.Clear();
  arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
                 3.0f * FX_PI / 4.0f, FX_PI);
  cr.Set(0xFF404040);
  pGS->SetStrokeColor(&cr);
  pGS->StrokePath(&arcPath, pMatrix);
  arcPath.Clear();
  arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
                 -1.0f * FX_PI / 4.0f, FX_PI);
  cr.Set(0xFFC0C0C0);
  pGS->SetStrokeColor(&cr);
  pGS->StrokePath(&arcPath, pMatrix);
  pGS->RestoreGraphState();
}
static void XFA_Draw3DRect(CFX_Graphics* pGraphic,
                           const CFX_RectF& rt,
                           FX_FLOAT fLineWidth,
                           CFX_Matrix* pMatrix,
                           FX_ARGB argbTopLeft,
                           FX_ARGB argbBottomRight) {
  CFX_Color crLT(argbTopLeft);
  pGraphic->SetFillColor(&crLT);
  FX_FLOAT fBottom = rt.bottom();
  FX_FLOAT fRight = rt.right();
  CFX_Path pathLT;
  pathLT.Create();
  pathLT.MoveTo(rt.left, fBottom);
  pathLT.LineTo(rt.left, rt.top);
  pathLT.LineTo(fRight, rt.top);
  pathLT.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
  pathLT.LineTo(rt.left + fLineWidth, rt.top + fLineWidth);
  pathLT.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
  pathLT.LineTo(rt.left, fBottom);
  pGraphic->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
  CFX_Color crRB(argbBottomRight);
  pGraphic->SetFillColor(&crRB);
  CFX_Path pathRB;
  pathRB.Create();
  pathRB.MoveTo(fRight, rt.top);
  pathRB.LineTo(fRight, fBottom);
  pathRB.LineTo(rt.left, fBottom);
  pathRB.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
  pathRB.LineTo(fRight - fLineWidth, fBottom - fLineWidth);
  pathRB.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
  pathRB.LineTo(fRight, rt.top);
  pGraphic->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
}
static void XFA_BOX_Stroke_3DRect_Lowered(CFX_Graphics* pGS,
                                          CFX_RectF rt,
                                          FX_FLOAT fThickness,
                                          CFX_Matrix* pMatrix) {
  FX_FLOAT fHalfWidth = fThickness / 2.0f;
  CFX_RectF rtInner(rt);
  rtInner.Deflate(fHalfWidth, fHalfWidth);
  CFX_Color cr(0xFF000000);
  pGS->SetFillColor(&cr);
  CFX_Path path;
  path.Create();
  path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
  path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
  pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
  XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF808080, 0xFFC0C0C0);
}
static void XFA_BOX_Stroke_3DRect_Raised(CFX_Graphics* pGS,
                                         CFX_RectF rt,
                                         FX_FLOAT fThickness,
                                         CFX_Matrix* pMatrix) {
  FX_FLOAT fHalfWidth = fThickness / 2.0f;
  CFX_RectF rtInner(rt);
  rtInner.Deflate(fHalfWidth, fHalfWidth);
  CFX_Color cr(0xFF000000);
  pGS->SetFillColor(&cr);
  CFX_Path path;
  path.Create();
  path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
  path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
  pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
  XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
}
static void XFA_BOX_Stroke_3DRect_Etched(CFX_Graphics* pGS,
                                         CFX_RectF rt,
                                         FX_FLOAT fThickness,
                                         CFX_Matrix* pMatrix) {
  FX_FLOAT fHalfWidth = fThickness / 2.0f;
  XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFFFFFFFF);
  CFX_RectF rtInner(rt);
  rtInner.Deflate(fHalfWidth, fHalfWidth);
  XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
}
static void XFA_BOX_Stroke_3DRect_Embossed(CFX_Graphics* pGS,
                                           CFX_RectF rt,
                                           FX_FLOAT fThickness,
                                           CFX_Matrix* pMatrix) {
  FX_FLOAT fHalfWidth = fThickness / 2.0f;
  XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFF000000);
  CFX_RectF rtInner(rt);
  rtInner.Deflate(fHalfWidth, fHalfWidth);
  XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF000000, 0xFF808080);
}
static void XFA_BOX_Stroke_Rect(CXFA_Box box,
                                const CXFA_StrokeArray& strokes,
                                CFX_Graphics* pGS,
                                CFX_RectF rtWidget,
                                CFX_Matrix* pMatrix) {
  FX_BOOL bVisible = FALSE;
  FX_FLOAT fThickness = 0;
  int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
  if (i3DType) {
    if (!bVisible || fThickness < 0.001f) {
      return;
    }
    switch (i3DType) {
      case XFA_ATTRIBUTEENUM_Lowered:
        XFA_BOX_Stroke_3DRect_Lowered(pGS, rtWidget, fThickness, pMatrix);
        break;
      case XFA_ATTRIBUTEENUM_Raised:
        XFA_BOX_Stroke_3DRect_Raised(pGS, rtWidget, fThickness, pMatrix);
        break;
      case XFA_ATTRIBUTEENUM_Etched:
        XFA_BOX_Stroke_3DRect_Etched(pGS, rtWidget, fThickness, pMatrix);
        break;
      case XFA_ATTRIBUTEENUM_Embossed:
        XFA_BOX_Stroke_3DRect_Embossed(pGS, rtWidget, fThickness, pMatrix);
        break;
    }
    return;
  }
  FX_BOOL bClose = FALSE;
  FX_BOOL bSameStyles = TRUE;
  int32_t i;
  CXFA_Stroke stroke1 = strokes[0];
  for (i = 1; i < 8; i++) {
    CXFA_Stroke stroke2 = strokes[i];
    if (!stroke1.SameStyles(stroke2)) {
      bSameStyles = FALSE;
      break;
    }
    stroke1 = stroke2;
  }
  if (bSameStyles) {
    stroke1 = strokes[0];
    bClose = TRUE;
    for (i = 2; i < 8; i += 2) {
      CXFA_Stroke stroke2 = strokes[i];
      if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
                                           XFA_STROKE_SAMESTYLE_Corner)) {
        bSameStyles = FALSE;
        break;
      }
      stroke1 = stroke2;
    }
    if (bSameStyles) {
      stroke1 = strokes[0];
      if (stroke1.IsInverted()) {
        bSameStyles = FALSE;
      }
      if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
        bSameStyles = FALSE;
      }
    }
  }
  FX_BOOL bStart = TRUE;
  CFX_Path path;
  path.Create();
  for (i = 0; i < 8; i++) {
    CXFA_Stroke stroke1 = strokes[i];
    if ((i % 1) == 0 && stroke1.GetRadius() < 0) {
      FX_BOOL bEmpty = path.IsEmpty();
      if (!bEmpty) {
        XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
        path.Clear();
      }
      bStart = TRUE;
      continue;
    }
    XFA_BOX_GetPath(box, strokes, rtWidget, path, i, bStart, !bSameStyles);
    CXFA_Stroke stroke2 = strokes[(i + 1) % 8];
    bStart = !stroke1.SameStyles(stroke2);
    if (bStart) {
      XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
      path.Clear();
    }
  }
  FX_BOOL bEmpty = path.IsEmpty();
  if (!bEmpty) {
    if (bClose) {
      path.Close();
    }
    XFA_BOX_StrokePath(strokes[7], &path, pGS, pMatrix);
  }
}
static void XFA_BOX_Stroke(CXFA_Box box,
                           const CXFA_StrokeArray& strokes,
                           CFX_Graphics* pGS,
                           CFX_RectF rtWidget,
                           CFX_Matrix* pMatrix,
                           FX_DWORD dwFlags) {
  if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
    XFA_BOX_StrokeArc(box, pGS, rtWidget, pMatrix, dwFlags);
    return;
  }
  bool bVisible = false;
  for (int32_t j = 0; j < 4; j++) {
    if (strokes[j * 2 + 1].IsVisible()) {
      bVisible = true;
      break;
    }
  }
  if (!bVisible) {
    return;
  }
  for (int32_t i = 1; i < 8; i += 2) {
    CXFA_Edge edge(strokes[i].GetNode());
    FX_FLOAT fThickness = edge.GetThickness();
    if (fThickness < 0) {
      fThickness = 0;
    }
    FX_FLOAT fHalf = fThickness / 2;
    int32_t iHand = box.GetHand();
    switch (i) {
      case 1:
        if (iHand == XFA_ATTRIBUTEENUM_Left) {
          rtWidget.top -= fHalf;
          rtWidget.height += fHalf;
        } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
          rtWidget.top += fHalf;
          rtWidget.height -= fHalf;
        }
        break;
      case 3:
        if (iHand == XFA_ATTRIBUTEENUM_Left) {
          rtWidget.width += fHalf;
        } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
          rtWidget.width -= fHalf;
        }
        break;
      case 5:
        if (iHand == XFA_ATTRIBUTEENUM_Left) {
          rtWidget.height += fHalf;
        } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
          rtWidget.height -= fHalf;
        }
        break;
      case 7:
        if (iHand == XFA_ATTRIBUTEENUM_Left) {
          rtWidget.left -= fHalf;
          rtWidget.width += fHalf;
        } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
          rtWidget.left += fHalf;
          rtWidget.width -= fHalf;
        }
        break;
    }
  }
  XFA_BOX_Stroke_Rect(box, strokes, pGS, rtWidget, pMatrix);
}
void XFA_DrawBox(CXFA_Box box,
                 CFX_Graphics* pGS,
                 const CFX_RectF& rtWidget,
                 CFX_Matrix* pMatrix,
                 FX_DWORD dwFlags) {
  if (!box || box.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
    return;
  }
  int32_t iType = box.GetClassID();
  if (iType != XFA_ELEMENT_Arc && iType != XFA_ELEMENT_Border &&
      iType != XFA_ELEMENT_Rectangle) {
    return;
  }
  CXFA_StrokeArray strokes;
  if (!(dwFlags & XFA_DRAWBOX_ForceRound) && iType != XFA_ELEMENT_Arc) {
    box.GetStrokes(strokes);
  }
  XFA_BOX_Fill(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
  XFA_BOX_Stroke(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
}
