// 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 <memory>

#include "xfa/src/fxgraphics/src/fx_path_generator.h"
#include "xfa/src/fxgraphics/src/pre.h"

class CAGG_Graphics {
 public:
  CAGG_Graphics();
  FX_ERR Create(CFX_Graphics* owner,
                int32_t width,
                int32_t height,
                FXDIB_Format format);
  virtual ~CAGG_Graphics();

 private:
  CFX_Graphics* _owner;
};
CFX_Graphics::CFX_Graphics() {
  _type = FX_CONTEXT_None;
  _info._graphState.SetDashCount(0);
  _info._isAntialiasing = TRUE;
  _info._strokeAlignment = FX_STROKEALIGNMENT_Center;
  _info._CTM.SetIdentity();
  _info._isActOnDash = FALSE;
  _info._strokeColor = NULL;
  _info._fillColor = NULL;
  _info._font = NULL;
  _info._fontSize = 40.0;
  _info._fontHScale = 1.0;
  _info._fontSpacing = 0.0;
  _renderDevice = NULL;
  _aggGraphics = NULL;
}
FX_ERR CFX_Graphics::Create(CFX_RenderDevice* renderDevice,
                            FX_BOOL isAntialiasing) {
  if (!renderDevice)
    return FX_ERR_Parameter_Invalid;
  if (_type != FX_CONTEXT_None) {
    return FX_ERR_Property_Invalid;
  }
  _type = FX_CONTEXT_Device;
  _info._isAntialiasing = isAntialiasing;
  _renderDevice = renderDevice;
  if (_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP) {
    return FX_ERR_Succeeded;
  }
  return FX_ERR_Indefinite;
}
FX_ERR CFX_Graphics::Create(int32_t width,
                            int32_t height,
                            FXDIB_Format format,
                            FX_BOOL isNative,
                            FX_BOOL isAntialiasing) {
  if (_type != FX_CONTEXT_None) {
    return FX_ERR_Property_Invalid;
  }
  _type = FX_CONTEXT_Device;
  _info._isAntialiasing = isAntialiasing;
  {
    _aggGraphics = new CAGG_Graphics;
    return _aggGraphics->Create(this, width, height, format);
  }
}
CFX_Graphics::~CFX_Graphics() {
  if (_aggGraphics) {
    delete _aggGraphics;
    _aggGraphics = NULL;
  }
  _renderDevice = NULL;
  _info._graphState.SetDashCount(0);
  _type = FX_CONTEXT_None;
}
FX_ERR CFX_Graphics::GetDeviceCap(const int32_t capID, FX_DeviceCap& capVal) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      capVal = _renderDevice->GetDeviceCaps(capID);
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::IsPrinterDevice(FX_BOOL& isPrinter) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      int32_t deviceClass = _renderDevice->GetDeviceClass();
      if (deviceClass == FXDC_PRINTER) {
        isPrinter = TRUE;
      } else {
        isPrinter = FALSE;
      }
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::EnableAntialiasing(FX_BOOL isAntialiasing) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._isAntialiasing = isAntialiasing;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SaveGraphState() {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _renderDevice->SaveState();
      TInfo* info = new TInfo;
      info->_graphState.Copy(_info._graphState);
      info->_isAntialiasing = _info._isAntialiasing;
      info->_strokeAlignment = _info._strokeAlignment;
      info->_CTM = _info._CTM;
      info->_isActOnDash = _info._isActOnDash;
      info->_strokeColor = _info._strokeColor;
      info->_fillColor = _info._fillColor;
      info->_font = _info._font;
      info->_fontSize = _info._fontSize;
      info->_fontHScale = _info._fontHScale;
      info->_fontSpacing = _info._fontSpacing;
      _infoStack.Add(info);
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::RestoreGraphState() {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _renderDevice->RestoreState();
      int32_t size = _infoStack.GetSize();
      if (size <= 0) {
        return FX_ERR_Intermediate_Value_Invalid;
      }
      int32_t topIndex = size - 1;
      TInfo* info = (TInfo*)_infoStack.GetAt(topIndex);
      if (!info)
        return FX_ERR_Intermediate_Value_Invalid;
      _info._graphState.Copy(info->_graphState);
      _info._isAntialiasing = info->_isAntialiasing;
      _info._strokeAlignment = info->_strokeAlignment;
      _info._CTM = info->_CTM;
      _info._isActOnDash = info->_isActOnDash;
      _info._strokeColor = info->_strokeColor;
      _info._fillColor = info->_fillColor;
      _info._font = info->_font;
      _info._fontSize = info->_fontSize;
      _info._fontHScale = info->_fontHScale;
      _info._fontSpacing = info->_fontSpacing;
      delete info;
      info = NULL;
      _infoStack.RemoveAt(topIndex);
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap& lineCap) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      lineCap = _info._graphState.m_LineCap;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._graphState.m_LineCap = lineCap;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::GetDashCount(int32_t& dashCount) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      dashCount = _info._graphState.m_DashCount;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::GetLineDash(FX_FLOAT& dashPhase, FX_FLOAT* dashArray) {
  if (!dashArray)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      dashPhase = _info._graphState.m_DashPhase;
      FXSYS_memcpy(dashArray, _info._graphState.m_DashArray,
                   _info._graphState.m_DashCount * sizeof(FX_FLOAT));
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetLineDash(FX_FLOAT dashPhase,
                                 FX_FLOAT* dashArray,
                                 int32_t dashCount) {
  if (dashCount > 0 && !dashArray) {
    return FX_ERR_Parameter_Invalid;
  }
  dashCount = dashCount < 0 ? 0 : dashCount;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      FX_FLOAT scale = 1.0;
      if (_info._isActOnDash) {
        scale = _info._graphState.m_LineWidth;
      }
      _info._graphState.m_DashPhase = dashPhase;
      _info._graphState.SetDashCount(dashCount);
      for (int32_t i = 0; i < dashCount; i++) {
        _info._graphState.m_DashArray[i] = dashArray[i] * scale;
      }
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      return RenderDeviceSetLineDash(dashStyle);
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::GetLineJoin(CFX_GraphStateData::LineJoin& lineJoin) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      lineJoin = _info._graphState.m_LineJoin;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._graphState.m_LineJoin = lineJoin;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::GetMiterLimit(FX_FLOAT& miterLimit) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      miterLimit = _info._graphState.m_MiterLimit;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._graphState.m_MiterLimit = miterLimit;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::GetLineWidth(FX_FLOAT& lineWidth) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      lineWidth = _info._graphState.m_LineWidth;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._graphState.m_LineWidth = lineWidth;
      _info._isActOnDash = isActOnDash;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::GetStrokeAlignment(FX_StrokeAlignment& strokeAlignment) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      strokeAlignment = _info._strokeAlignment;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._strokeAlignment = strokeAlignment;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetStrokeColor(CFX_Color* color) {
  if (!color)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._strokeColor = color;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetFillColor(CFX_Color* color) {
  if (!color)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._fillColor = color;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) {
  if (!path)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      return RenderDeviceStrokePath(path, matrix);
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::FillPath(CFX_Path* path,
                              FX_FillMode fillMode,
                              CFX_Matrix* matrix) {
  if (!path)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      return RenderDeviceFillPath(path, fillMode, matrix);
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::ClipPath(CFX_Path* path,
                              FX_FillMode fillMode,
                              CFX_Matrix* matrix) {
  if (!path)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      FX_BOOL result = _renderDevice->SetClip_PathFill(
          path->GetPathData(), (CFX_Matrix*)matrix, fillMode);
      if (!result)
        return FX_ERR_Indefinite;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::DrawImage(CFX_DIBSource* source,
                               const CFX_PointF& point,
                               CFX_Matrix* matrix) {
  if (!source)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      return RenderDeviceDrawImage(source, point, matrix);
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::StretchImage(CFX_DIBSource* source,
                                  const CFX_RectF& rect,
                                  CFX_Matrix* matrix) {
  if (!source)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      return RenderDeviceStretchImage(source, rect, matrix);
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) {
  if (!matrix)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._CTM.Concat(*matrix);
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
CFX_Matrix* CFX_Graphics::GetMatrix() {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return NULL;
      return &_info._CTM;
    }
    default: { return NULL; }
  }
}
FX_ERR CFX_Graphics::GetClipRect(CFX_RectF& rect) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      FX_RECT r = _renderDevice->GetClipBox();
      rect.left = (FX_FLOAT)r.left;
      rect.top = (FX_FLOAT)r.top;
      rect.width = (FX_FLOAT)r.Width();
      rect.height = (FX_FLOAT)r.Height();
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetClipRect(const CFX_RectF& rect) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      FX_RECT r(FXSYS_round(rect.left), FXSYS_round(rect.top),
                FXSYS_round(rect.right()), FXSYS_round(rect.bottom()));
      FX_BOOL result = _renderDevice->SetClip_Rect(&r);
      if (!result)
        return FX_ERR_Method_Not_Supported;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::ClearClip() {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetFont(CFX_Font* font) {
  if (!font)
    return FX_ERR_Parameter_Invalid;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._font = font;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetFontSize(const FX_FLOAT size) {
  FX_FLOAT fontSize = size <= 0 ? 1.0f : size;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._fontSize = fontSize;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetFontHScale(const FX_FLOAT scale) {
  FX_FLOAT fontHScale = scale <= 0 ? 1.0f : scale;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._fontHScale = fontHScale;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing) {
  FX_FLOAT fontSpacing = spacing < 0 ? 0 : spacing;
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      _info._fontSpacing = fontSpacing;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::SetTextDrawingMode(const int32_t mode) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::ShowText(const CFX_PointF& point,
                              const CFX_WideString& text,
                              CFX_Matrix* matrix) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      return RenderDeviceShowText(point, text, matrix);
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::CalcTextRect(CFX_RectF& rect,
                                  const CFX_WideString& text,
                                  FX_BOOL isMultiline,
                                  CFX_Matrix* matrix) {
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      int32_t length = text.GetLength();
      FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length);
      FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
      CalcTextInfo(text, charCodes, charPos, rect);
      FX_Free(charPos);
      FX_Free(charCodes);
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics,
                              const CFX_Matrix* matrix) {
  if (!graphics)
    return FX_ERR_Parameter_Invalid;
  CFX_Matrix m;
  m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
        _info._CTM.f);
  if (matrix) {
    m.Concat(*matrix);
  }
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      {
        if (!graphics->_renderDevice)
          return FX_ERR_Parameter_Invalid;
        CFX_DIBitmap* bitmap = graphics->_renderDevice->GetBitmap();
        FX_BOOL result = _renderDevice->SetDIBits(bitmap, 0, 0);
        if (!result)
          return FX_ERR_Method_Not_Supported;
      }
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics,
                              FX_FLOAT srcLeft,
                              FX_FLOAT srcTop,
                              const CFX_RectF& dstRect,
                              const CFX_Matrix* matrix) {
  if (!graphics)
    return FX_ERR_Parameter_Invalid;
  CFX_Matrix m;
  m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
        _info._CTM.f);
  if (matrix) {
    m.Concat(*matrix);
  }
  switch (_type) {
    case FX_CONTEXT_Device: {
      if (!_renderDevice)
        return FX_ERR_Property_Invalid;
      {
        if (!graphics->_renderDevice)
          return FX_ERR_Parameter_Invalid;
        CFX_DIBitmap* bitmap = graphics->_renderDevice->GetBitmap();
        CFX_DIBitmap bmp;
        FX_BOOL result =
            bmp.Create((int32_t)dstRect.width, (int32_t)dstRect.height,
                       bitmap->GetFormat());
        if (!result)
          return FX_ERR_Intermediate_Value_Invalid;
        result = graphics->_renderDevice->GetDIBits(&bmp, (int32_t)srcLeft,
                                                    (int32_t)srcTop);
        if (!result)
          return FX_ERR_Method_Not_Supported;
        result = _renderDevice->SetDIBits(&bmp, (int32_t)dstRect.left,
                                          (int32_t)dstRect.top);
        if (!result)
          return FX_ERR_Method_Not_Supported;
        return FX_ERR_Succeeded;
      }
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
CFX_RenderDevice* CFX_Graphics::GetRenderDevice() {
  return _renderDevice;
}
FX_ERR CFX_Graphics::InverseRect(const CFX_RectF& rect) {
  if (!_renderDevice)
    return FX_ERR_Property_Invalid;
  CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
  if (!bitmap)
    return FX_ERR_Property_Invalid;
  CFX_RectF temp(rect);
  _info._CTM.TransformRect(temp);
  CFX_RectF r;
  r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth());
  r.Intersect(temp);
  if (r.IsEmpty()) {
    return FX_ERR_Parameter_Invalid;
  }
  FX_ARGB* pBuf =
      (FX_ARGB*)(bitmap->GetBuffer() + int32_t(r.top) * bitmap->GetPitch());
  int32_t bottom = (int32_t)r.bottom();
  int32_t right = (int32_t)r.right();
  for (int32_t i = (int32_t)r.top; i < bottom; i++) {
    FX_ARGB* pLine = pBuf + (int32_t)r.left;
    for (int32_t j = (int32_t)r.left; j < right; j++) {
      FX_ARGB c = *pLine;
      *pLine++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF));
    }
    pBuf = (FX_ARGB*)((uint8_t*)pBuf + bitmap->GetPitch());
  }
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Graphics::XorDIBitmap(const CFX_DIBitmap* srcBitmap,
                                 const CFX_RectF& rect) {
  if (!_renderDevice)
    return FX_ERR_Property_Invalid;
  CFX_DIBitmap* dst = _renderDevice->GetBitmap();
  if (!dst)
    return FX_ERR_Property_Invalid;
  CFX_RectF temp(rect);
  _info._CTM.TransformRect(temp);
  CFX_RectF r;
  r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
  r.Intersect(temp);
  if (r.IsEmpty()) {
    return FX_ERR_Parameter_Invalid;
  }
  FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
                                int32_t(r.top) * srcBitmap->GetPitch());
  FX_ARGB* pDstBuf =
      (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
  int32_t bottom = (int32_t)r.bottom();
  int32_t right = (int32_t)r.right();
  for (int32_t i = (int32_t)r.top; i < bottom; i++) {
    FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
    FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
    for (int32_t j = (int32_t)r.left; j < right; j++) {
      FX_ARGB c = *pDstLine;
      *pDstLine++ =
          ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF));
      pSrcLine++;
    }
    pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
    pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
  }
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap* srcBitmap,
                                 const CFX_RectF& rect) {
  if (!_renderDevice)
    return FX_ERR_Property_Invalid;
  CFX_DIBitmap* dst = _renderDevice->GetBitmap();
  if (!dst)
    return FX_ERR_Property_Invalid;
  CFX_RectF temp(rect);
  _info._CTM.TransformRect(temp);
  CFX_RectF r;
  r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
  r.Intersect(temp);
  if (r.IsEmpty()) {
    return FX_ERR_Parameter_Invalid;
  }
  FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() +
                                int32_t(r.top) * srcBitmap->GetPitch());
  FX_ARGB* pDstBuf =
      (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch());
  int32_t bottom = (int32_t)r.bottom();
  int32_t right = (int32_t)r.right();
  for (int32_t i = (int32_t)r.top; i < bottom; i++) {
    FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left;
    FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left;
    for (int32_t j = (int32_t)r.left; j < right; j++) {
      FX_ARGB c = *pDstLine;
      *pDstLine++ =
          ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)));
      pSrcLine++;
    }
    pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch());
    pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch());
  }
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) {
  switch (dashStyle) {
    case FX_DASHSTYLE_Solid: {
      _info._graphState.SetDashCount(0);
      return FX_ERR_Succeeded;
    }
    case FX_DASHSTYLE_Dash: {
      FX_FLOAT dashArray[] = {3, 1};
      SetLineDash(0, dashArray, 2);
      return FX_ERR_Succeeded;
    }
    case FX_DASHSTYLE_Dot: {
      FX_FLOAT dashArray[] = {1, 1};
      SetLineDash(0, dashArray, 2);
      return FX_ERR_Succeeded;
    }
    case FX_DASHSTYLE_DashDot: {
      FX_FLOAT dashArray[] = {3, 1, 1, 1};
      SetLineDash(0, dashArray, 4);
      return FX_ERR_Succeeded;
    }
    case FX_DASHSTYLE_DashDotDot: {
      FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
      SetLineDash(0, dashArray, 6);
      return FX_ERR_Succeeded;
    }
    default: { return FX_ERR_Parameter_Invalid; }
  }
}
FX_ERR CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path,
                                            CFX_Matrix* matrix) {
  if (!_info._strokeColor)
    return FX_ERR_Property_Invalid;
  CFX_Matrix m;
  m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
        _info._CTM.f);
  if (matrix) {
    m.Concat(*matrix);
  }
  switch (_info._strokeColor->_type) {
    case FX_COLOR_Solid: {
      FX_BOOL result = _renderDevice->DrawPath(
          path->GetPathData(), (CFX_Matrix*)&m, &_info._graphState, 0x0,
          _info._strokeColor->_argb, 0);
      if (!result)
        return FX_ERR_Indefinite;
      return FX_ERR_Succeeded;
    }
    case FX_COLOR_Pattern: {
      return StrokePathWithPattern(path, &m);
    }
    case FX_COLOR_Shading: {
      return StrokePathWithShading(path, &m);
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::RenderDeviceFillPath(CFX_Path* path,
                                          FX_FillMode fillMode,
                                          CFX_Matrix* matrix) {
  if (!_info._fillColor)
    return FX_ERR_Property_Invalid;
  CFX_Matrix m;
  m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
        _info._CTM.f);
  if (matrix) {
    m.Concat(*matrix);
  }
  switch (_info._fillColor->_type) {
    case FX_COLOR_Solid: {
      FX_BOOL result = _renderDevice->DrawPath(
          path->GetPathData(), (CFX_Matrix*)&m, &_info._graphState,
          _info._fillColor->_argb, 0x0, fillMode);
      if (!result)
        return FX_ERR_Indefinite;
      return FX_ERR_Succeeded;
    }
    case FX_COLOR_Pattern: {
      { return FillPathWithPattern(path, fillMode, &m); }
    }
    case FX_COLOR_Shading: {
      { return FillPathWithShading(path, fillMode, &m); }
    }
    default: { return FX_ERR_Property_Invalid; }
  }
}
FX_ERR CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource* source,
                                           const CFX_PointF& point,
                                           CFX_Matrix* matrix) {
  CFX_Matrix m1;
  m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
         _info._CTM.f);
  if (matrix) {
    m1.Concat(*matrix);
  }
  CFX_Matrix m2;
  m2.Set((FX_FLOAT)source->GetWidth(), 0.0, 0.0, (FX_FLOAT)source->GetHeight(),
         point.x, point.y);
  m2.Concat(m1);
  int32_t left, top;
  CFX_DIBitmap* bmp1 = source->FlipImage(FALSE, TRUE);
  CFX_DIBitmap* bmp2 = bmp1->TransformTo((CFX_Matrix*)&m2, left, top);
  CFX_RectF r;
  GetClipRect(r);
  FX_ERR result = FX_ERR_Indefinite;
  {
    CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
    CFX_DIBitmap bmp;
    bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb);
    _renderDevice->GetDIBits(&bmp, 0, 0);
    bmp.TransferBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
                       FXSYS_round(r.Width()), FXSYS_round(r.Height()), bmp2,
                       FXSYS_round(r.left - left), FXSYS_round(r.top - top));
    _renderDevice->SetDIBits(&bmp, 0, 0);
    result = FX_ERR_Succeeded;
  }
  if (bmp2) {
    delete bmp2;
    bmp2 = NULL;
  }
  if (bmp1) {
    delete bmp1;
    bmp1 = NULL;
  }
  return result;
}
FX_ERR CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource* source,
                                              const CFX_RectF& rect,
                                              CFX_Matrix* matrix) {
  CFX_Matrix m1;
  m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
         _info._CTM.f);
  if (matrix) {
    m1.Concat(*matrix);
  }
  CFX_DIBitmap* bmp1 =
      source->StretchTo((int32_t)rect.Width(), (int32_t)rect.Height());
  CFX_Matrix m2;
  m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top);
  m2.Concat(m1);
  int32_t left, top;
  CFX_DIBitmap* bmp2 = bmp1->FlipImage(FALSE, TRUE);
  CFX_DIBitmap* bmp3 = bmp2->TransformTo((CFX_Matrix*)&m2, left, top);
  CFX_RectF r;
  GetClipRect(r);
  FX_ERR result = FX_ERR_Indefinite;
  {
    CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
    bitmap->CompositeBitmap(FXSYS_round(r.left), FXSYS_round(r.top),
                            FXSYS_round(r.Width()), FXSYS_round(r.Height()),
                            bmp3, FXSYS_round(r.left - left),
                            FXSYS_round(r.top - top));
    result = FX_ERR_Succeeded;
  }
  if (bmp3) {
    delete bmp3;
    bmp3 = NULL;
  }
  if (bmp2) {
    delete bmp2;
    bmp2 = NULL;
  }
  if (bmp1) {
    delete bmp1;
    bmp1 = NULL;
  }
  return result;
}
FX_ERR CFX_Graphics::RenderDeviceShowText(const CFX_PointF& point,
                                          const CFX_WideString& text,
                                          CFX_Matrix* matrix) {
  int32_t length = text.GetLength();
  FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length);
  FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length);
  CFX_RectF rect;
  rect.Set(point.x, point.y, 0, 0);
  CalcTextInfo(text, charCodes, charPos, rect);
  CFX_Matrix m;
  m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e,
        _info._CTM.f);
  m.Translate(0, _info._fontSize * _info._fontHScale);
  if (matrix) {
    m.Concat(*matrix);
  }
  FX_BOOL result = _renderDevice->DrawNormalText(
      length, charPos, _info._font, CFX_GEModule::Get()->GetFontCache(),
      -_info._fontSize * _info._fontHScale, (CFX_Matrix*)&m,
      _info._fillColor->_argb, FXTEXT_CLEARTYPE);
  if (!result)
    return FX_ERR_Indefinite;
  FX_Free(charPos);
  FX_Free(charCodes);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Graphics::StrokePathWithPattern(CFX_Path* path, CFX_Matrix* matrix) {
  return FX_ERR_Method_Not_Supported;
}
FX_ERR CFX_Graphics::StrokePathWithShading(CFX_Path* path, CFX_Matrix* matrix) {
  return FX_ERR_Method_Not_Supported;
}
FX_ERR CFX_Graphics::FillPathWithPattern(CFX_Path* path,
                                         FX_FillMode fillMode,
                                         CFX_Matrix* matrix) {
  CFX_Pattern* pattern = _info._fillColor->_pattern;
  CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
  int32_t width = bitmap->GetWidth();
  int32_t height = bitmap->GetHeight();
  CFX_DIBitmap bmp;
  bmp.Create(width, height, FXDIB_Argb);
  _renderDevice->GetDIBits(&bmp, 0, 0);
  switch (pattern->_type) {
    case FX_PATTERN_Bitmap: {
      int32_t xStep = FXSYS_round(pattern->_x1Step);
      int32_t yStep = FXSYS_round(pattern->_y1Step);
      int32_t xCount = width / xStep + 1;
      int32_t yCount = height / yStep + 1;
      for (int32_t i = 0; i <= yCount; i++) {
        for (int32_t j = 0; j <= xCount; j++) {
          bmp.TransferBitmap(j * xStep, i * yStep, xStep, yStep,
                             pattern->_bitmap, 0, 0);
        }
      }
      break;
    }
    case FX_PATTERN_Hatch: {
      FX_HatchStyle hatchStyle = _info._fillColor->_pattern->_hatchStyle;
      if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
          hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
        return FX_ERR_Intermediate_Value_Invalid;
      }
      const FX_HATCHDATA& data = hatchBitmapData[hatchStyle];
      CFX_DIBitmap mask;
      mask.Create(data.width, data.height, FXDIB_1bppMask);
      FXSYS_memcpy(mask.GetBuffer(), data.maskBits,
                   mask.GetPitch() * data.height);
      CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox();
      if (matrix) {
        rectf.Transform((const CFX_Matrix*)matrix);
      }
      FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
                   FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
      CFX_FxgeDevice device;
      device.Attach(&bmp);
      device.FillRect(&rect, _info._fillColor->_pattern->_backArgb);
      for (int32_t j = rect.bottom; j < rect.top; j += mask.GetHeight()) {
        for (int32_t i = rect.left; i < rect.right; i += mask.GetWidth()) {
          device.SetBitMask(&mask, i, j, _info._fillColor->_pattern->_foreArgb);
        }
      }
      break;
    }
  }
  _renderDevice->SaveState();
  _renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix,
                                  fillMode);
  SetDIBitsWithMatrix(&bmp, &pattern->_matrix);
  _renderDevice->RestoreState();
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Graphics::FillPathWithShading(CFX_Path* path,
                                         FX_FillMode fillMode,
                                         CFX_Matrix* matrix) {
  CFX_DIBitmap* bitmap = _renderDevice->GetBitmap();
  int32_t width = bitmap->GetWidth();
  int32_t height = bitmap->GetHeight();
  FX_FLOAT start_x = _info._fillColor->_shading->_beginPoint.x;
  FX_FLOAT start_y = _info._fillColor->_shading->_beginPoint.y;
  FX_FLOAT end_x = _info._fillColor->_shading->_endPoint.x;
  FX_FLOAT end_y = _info._fillColor->_shading->_endPoint.y;
  CFX_DIBitmap bmp;
  bmp.Create(width, height, FXDIB_Argb);
  _renderDevice->GetDIBits(&bmp, 0, 0);
  int32_t pitch = bmp.GetPitch();
  FX_BOOL result = FALSE;
  switch (_info._fillColor->_shading->_type) {
    case FX_SHADING_Axial: {
      FX_FLOAT x_span = end_x - start_x;
      FX_FLOAT y_span = end_y - start_y;
      FX_FLOAT axis_len_square = (x_span * x_span) + (y_span * y_span);
      for (int32_t row = 0; row < height; row++) {
        FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch);
        for (int32_t column = 0; column < width; column++) {
          FX_FLOAT x = (FX_FLOAT)(column);
          FX_FLOAT y = (FX_FLOAT)(row);
          FX_FLOAT scale =
              (((x - start_x) * x_span) + ((y - start_y) * y_span)) /
              axis_len_square;
          if (scale < 0) {
            if (!_info._fillColor->_shading->_isExtendedBegin) {
              continue;
            }
            scale = 0;
          } else if (scale > 1.0f) {
            if (!_info._fillColor->_shading->_isExtendedEnd) {
              continue;
            }
            scale = 1.0f;
          }
          int32_t index = (int32_t)(scale * (FX_SHADING_Steps - 1));
          dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
        }
      }
      result = TRUE;
      break;
    }
    case FX_SHADING_Radial: {
      FX_FLOAT start_r = _info._fillColor->_shading->_beginRadius;
      FX_FLOAT end_r = _info._fillColor->_shading->_endRadius;
      FX_FLOAT a = ((start_x - end_x) * (start_x - end_x)) +
                   ((start_y - end_y) * (start_y - end_y)) -
                   ((start_r - end_r) * (start_r - end_r));
      for (int32_t row = 0; row < height; row++) {
        FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch);
        for (int32_t column = 0; column < width; column++) {
          FX_FLOAT x = (FX_FLOAT)(column);
          FX_FLOAT y = (FX_FLOAT)(row);
          FX_FLOAT b = -2 * (((x - start_x) * (end_x - start_x)) +
                             ((y - start_y) * (end_y - start_y)) +
                             (start_r * (end_r - start_r)));
          FX_FLOAT c = ((x - start_x) * (x - start_x)) +
                       ((y - start_y) * (y - start_y)) - (start_r * start_r);
          FX_FLOAT s;
          if (a == 0) {
            s = -c / b;
          } else {
            FX_FLOAT b2_4ac = (b * b) - 4 * (a * c);
            if (b2_4ac < 0) {
              continue;
            }
            FX_FLOAT root = (FXSYS_sqrt(b2_4ac));
            FX_FLOAT s1, s2;
            if (a > 0) {
              s1 = (-b - root) / (2 * a);
              s2 = (-b + root) / (2 * a);
            } else {
              s2 = (-b - root) / (2 * a);
              s1 = (-b + root) / (2 * a);
            }
            if (s2 <= 1.0f || _info._fillColor->_shading->_isExtendedEnd) {
              s = (s2);
            } else {
              s = (s1);
            }
            if ((start_r) + s * (end_r - start_r) < 0) {
              continue;
            }
          }
          if (s < 0) {
            if (!_info._fillColor->_shading->_isExtendedBegin) {
              continue;
            }
            s = 0;
          }
          if (s > 1.0f) {
            if (!_info._fillColor->_shading->_isExtendedEnd) {
              continue;
            }
            s = 1.0f;
          }
          int index = (int32_t)(s * (FX_SHADING_Steps - 1));
          dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
        }
      }
      result = TRUE;
      break;
    }
    default: { result = FALSE; }
  }
  if (result) {
    _renderDevice->SaveState();
    _renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix,
                                    fillMode);
    SetDIBitsWithMatrix(&bmp, matrix);
    _renderDevice->RestoreState();
  }
  return result;
}
FX_ERR CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource* source,
                                         CFX_Matrix* matrix) {
  if (matrix->IsIdentity()) {
    _renderDevice->SetDIBits(source, 0, 0);
  } else {
    CFX_Matrix m;
    m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0,
          0);
    m.Concat(*matrix);
    int32_t left, top;
    CFX_DIBitmap* bmp1 = source->FlipImage(FALSE, TRUE);
    CFX_DIBitmap* bmp2 = bmp1->TransformTo((CFX_Matrix*)&m, left, top);
    _renderDevice->SetDIBits(bmp2, left, top);
    if (bmp2) {
      delete bmp2;
      bmp2 = NULL;
    }
    if (bmp1) {
      delete bmp1;
      bmp1 = NULL;
    }
  }
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Graphics::CalcTextInfo(const CFX_WideString& text,
                                  FX_DWORD* charCodes,
                                  FXTEXT_CHARPOS* charPos,
                                  CFX_RectF& rect) {
  std::unique_ptr<CFX_UnicodeEncoding> encoding(
      new CFX_UnicodeEncoding(_info._font));
  int32_t length = text.GetLength();
  FX_FLOAT penX = (FX_FLOAT)rect.left;
  FX_FLOAT penY = (FX_FLOAT)rect.top;
  FX_FLOAT left = (FX_FLOAT)(0);
  FX_FLOAT top = (FX_FLOAT)(0);
  charCodes[0] = text.GetAt(0);
  charPos[0].m_OriginX = penX + left;
  charPos[0].m_OriginY = penY + top;
  charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]);
  charPos[0].m_FontCharWidth = FXSYS_round(
      _info._font->GetGlyphWidth(charPos[0].m_GlyphIndex) * _info._fontHScale);
  charPos[0].m_bGlyphAdjust = TRUE;
  charPos[0].m_AdjustMatrix[0] = -1;
  charPos[0].m_AdjustMatrix[1] = 0;
  charPos[0].m_AdjustMatrix[2] = 0;
  charPos[0].m_AdjustMatrix[3] = 1;
  penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * _info._fontSize / 1000 +
          _info._fontSpacing;
  for (int32_t i = 1; i < length; i++) {
    charCodes[i] = text.GetAt(i);
    charPos[i].m_OriginX = penX + left;
    charPos[i].m_OriginY = penY + top;
    charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]);
    charPos[i].m_FontCharWidth =
        FXSYS_round(_info._font->GetGlyphWidth(charPos[i].m_GlyphIndex) *
                    _info._fontHScale);
    charPos[i].m_bGlyphAdjust = TRUE;
    charPos[i].m_AdjustMatrix[0] = -1;
    charPos[i].m_AdjustMatrix[1] = 0;
    charPos[i].m_AdjustMatrix[2] = 0;
    charPos[i].m_AdjustMatrix[3] = 1;
    penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * _info._fontSize / 1000 +
            _info._fontSpacing;
  }
  rect.width = (FX_FLOAT)penX - rect.left;
  rect.height = rect.top + _info._fontSize * _info._fontHScale - rect.top;
  return FX_ERR_Succeeded;
}
CAGG_Graphics::CAGG_Graphics() {
  _owner = NULL;
}
FX_ERR CAGG_Graphics::Create(CFX_Graphics* owner,
                             int32_t width,
                             int32_t height,
                             FXDIB_Format format) {
  if (owner->_renderDevice) {
    return FX_ERR_Parameter_Invalid;
  }
  if (_owner) {
    return FX_ERR_Property_Invalid;
  }
  CFX_FxgeDevice* device = new CFX_FxgeDevice;
  device->Create(width, height, format);
  _owner = owner;
  _owner->_renderDevice = device;
  _owner->_renderDevice->GetBitmap()->Clear(0xFFFFFFFF);
  return FX_ERR_Succeeded;
}
CAGG_Graphics::~CAGG_Graphics() {
  if (_owner->_renderDevice) {
    delete (CFX_FxgeDevice*)_owner->_renderDevice;
  }
  _owner = NULL;
}
CFX_Path::CFX_Path() {
  _generator = NULL;
}
FX_ERR CFX_Path::Create() {
  if (_generator) {
    return FX_ERR_Property_Invalid;
  }
  _generator = new CFX_PathGenerator;
  _generator->Create();
  return FX_ERR_Succeeded;
}
CFX_Path::~CFX_Path() {
  if (_generator) {
    delete _generator;
    _generator = NULL;
  }
}
FX_ERR CFX_Path::MoveTo(FX_FLOAT x, FX_FLOAT y) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->MoveTo(x, y);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::LineTo(FX_FLOAT x, FX_FLOAT y) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->LineTo(x, y);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::BezierTo(FX_FLOAT ctrlX1,
                          FX_FLOAT ctrlY1,
                          FX_FLOAT ctrlX2,
                          FX_FLOAT ctrlY2,
                          FX_FLOAT toX,
                          FX_FLOAT toY) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->BezierTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, toX, toY);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::ArcTo(FX_FLOAT left,
                       FX_FLOAT top,
                       FX_FLOAT width,
                       FX_FLOAT height,
                       FX_FLOAT startAngle,
                       FX_FLOAT sweepAngle) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->ArcTo(left + width / 2, top + height / 2, width / 2, height / 2,
                    startAngle, sweepAngle);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::Close() {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->Close();
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->AddLine(x1, y1, x2, y2);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::AddBezier(FX_FLOAT startX,
                           FX_FLOAT startY,
                           FX_FLOAT ctrlX1,
                           FX_FLOAT ctrlY1,
                           FX_FLOAT ctrlX2,
                           FX_FLOAT ctrlY2,
                           FX_FLOAT endX,
                           FX_FLOAT endY) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->AddBezier(startX, startY, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX,
                        endY);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::AddRectangle(FX_FLOAT left,
                              FX_FLOAT top,
                              FX_FLOAT width,
                              FX_FLOAT height) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->AddRectangle(left, top, left + width, top + height);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::AddEllipse(FX_FLOAT left,
                            FX_FLOAT top,
                            FX_FLOAT width,
                            FX_FLOAT height) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->AddEllipse(left + width / 2, top + height / 2, width / 2,
                         height / 2);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::AddEllipse(const CFX_RectF& rect) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->AddEllipse(rect.left + rect.Width() / 2,
                         rect.top + rect.Height() / 2, rect.Width() / 2,
                         rect.Height() / 2);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::AddArc(FX_FLOAT left,
                        FX_FLOAT top,
                        FX_FLOAT width,
                        FX_FLOAT height,
                        FX_FLOAT startAngle,
                        FX_FLOAT sweepAngle) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->AddArc(left + width / 2, top + height / 2, width / 2, height / 2,
                     startAngle, sweepAngle);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::AddPie(FX_FLOAT left,
                        FX_FLOAT top,
                        FX_FLOAT width,
                        FX_FLOAT height,
                        FX_FLOAT startAngle,
                        FX_FLOAT sweepAngle) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->AddPie(left + width / 2, top + height / 2, width / 2, height / 2,
                     startAngle, sweepAngle);
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::AddSubpath(CFX_Path* path) {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->AddPathData(path->GetPathData());
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Path::Clear() {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  _generator->GetPathData()->SetPointCount(0);
  return FX_ERR_Succeeded;
}
FX_BOOL CFX_Path::IsEmpty() {
  if (!_generator)
    return FX_ERR_Property_Invalid;
  if (_generator->GetPathData()->GetPointCount() == 0) {
    return TRUE;
  }
  return FALSE;
}
CFX_PathData* CFX_Path::GetPathData() {
  if (!_generator)
    return NULL;
  return _generator->GetPathData();
}
CFX_Color::CFX_Color() {
  _type = FX_COLOR_None;
}
CFX_Color::CFX_Color(const FX_ARGB argb) {
  _type = FX_COLOR_None;
  Set(argb);
}
CFX_Color::CFX_Color(CFX_Pattern* pattern, const FX_ARGB argb) {
  _type = FX_COLOR_None;
  Set(pattern, argb);
}
CFX_Color::CFX_Color(CFX_Shading* shading) {
  _type = FX_COLOR_None;
  Set(shading);
}
CFX_Color::~CFX_Color() {
  _type = FX_COLOR_None;
}
FX_ERR CFX_Color::Set(const FX_ARGB argb) {
  _type = FX_COLOR_Solid;
  _argb = argb;
  _pattern = NULL;
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) {
  if (!pattern)
    return FX_ERR_Parameter_Invalid;
  _type = FX_COLOR_Pattern;
  _argb = argb;
  _pattern = pattern;
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Color::Set(CFX_Shading* shading) {
  if (!shading)
    return FX_ERR_Parameter_Invalid;
  _type = FX_COLOR_Shading;
  _shading = shading;
  return FX_ERR_Succeeded;
}
CFX_Pattern::CFX_Pattern() {
  _type = FX_PATTERN_None;
  _matrix.SetIdentity();
}
FX_ERR CFX_Pattern::Create(CFX_DIBitmap* bitmap,
                           const FX_FLOAT xStep,
                           const FX_FLOAT yStep,
                           CFX_Matrix* matrix) {
  if (!bitmap)
    return FX_ERR_Parameter_Invalid;
  if (_type != FX_PATTERN_None) {
    return FX_ERR_Property_Invalid;
  }
  _type = FX_PATTERN_Bitmap;
  _bitmap = bitmap;
  _x1Step = xStep;
  _y1Step = yStep;
  if (matrix) {
    _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e,
                matrix->f);
  }
  return FX_ERR_Succeeded;
}
FX_ERR CFX_Pattern::Create(FX_HatchStyle hatchStyle,
                           const FX_ARGB foreArgb,
                           const FX_ARGB backArgb,
                           CFX_Matrix* matrix) {
  if (hatchStyle < FX_HATCHSTYLE_Horizontal ||
      hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
    return FX_ERR_Parameter_Invalid;
  }
  if (_type != FX_PATTERN_None) {
    return FX_ERR_Property_Invalid;
  }
  _type = FX_PATTERN_Hatch;
  _hatchStyle = hatchStyle;
  _foreArgb = foreArgb;
  _backArgb = backArgb;
  if (matrix) {
    _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e,
                matrix->f);
  }
  return FX_ERR_Succeeded;
}
CFX_Pattern::~CFX_Pattern() {
  _type = FX_PATTERN_None;
}
CFX_Shading::CFX_Shading() {
  _type = FX_SHADING_None;
}
FX_ERR CFX_Shading::CreateAxial(const CFX_PointF& beginPoint,
                                const CFX_PointF& endPoint,
                                FX_BOOL isExtendedBegin,
                                FX_BOOL isExtendedEnd,
                                const FX_ARGB beginArgb,
                                const FX_ARGB endArgb) {
  if (_type != FX_SHADING_None) {
    return FX_ERR_Property_Invalid;
  }
  _type = FX_SHADING_Axial;
  _beginPoint = beginPoint;
  _endPoint = endPoint;
  _isExtendedBegin = isExtendedBegin;
  _isExtendedEnd = isExtendedEnd;
  _beginArgb = beginArgb;
  _endArgb = endArgb;
  return InitArgbArray();
}
FX_ERR CFX_Shading::CreateRadial(const CFX_PointF& beginPoint,
                                 const CFX_PointF& endPoint,
                                 const FX_FLOAT beginRadius,
                                 const FX_FLOAT endRadius,
                                 FX_BOOL isExtendedBegin,
                                 FX_BOOL isExtendedEnd,
                                 const FX_ARGB beginArgb,
                                 const FX_ARGB endArgb) {
  if (_type != FX_SHADING_None) {
    return FX_ERR_Property_Invalid;
  }
  _type = FX_SHADING_Radial;
  _beginPoint = beginPoint;
  _endPoint = endPoint;
  _beginRadius = beginRadius;
  _endRadius = endRadius;
  _isExtendedBegin = isExtendedBegin;
  _isExtendedEnd = isExtendedEnd;
  _beginArgb = beginArgb;
  _endArgb = endArgb;
  return InitArgbArray();
}
CFX_Shading::~CFX_Shading() {
  _type = FX_SHADING_None;
}
FX_ERR CFX_Shading::InitArgbArray() {
  int32_t a1, r1, g1, b1;
  ArgbDecode(_beginArgb, a1, r1, g1, b1);
  int32_t a2, r2, g2, b2;
  ArgbDecode(_endArgb, a2, r2, g2, b2);
  FX_FLOAT f = (FX_FLOAT)(FX_SHADING_Steps - 1);
  FX_FLOAT aScale = (FX_FLOAT)(1.0 * (a2 - a1) / f);
  FX_FLOAT rScale = (FX_FLOAT)(1.0 * (r2 - r1) / f);
  FX_FLOAT gScale = (FX_FLOAT)(1.0 * (g2 - g1) / f);
  FX_FLOAT bScale = (FX_FLOAT)(1.0 * (b2 - b1) / f);
  int32_t a3, r3, g3, b3;
  for (int32_t i = 0; i < FX_SHADING_Steps; i++) {
    a3 = (int32_t)(i * aScale);
    r3 = (int32_t)(i * rScale);
    g3 = (int32_t)(i * gScale);
    b3 = (int32_t)(i * bScale);
    _argbArray[i] =
        FXARGB_TODIB(FXARGB_MAKE((a1 + a3), (r1 + r3), (g1 + g3), (b1 + b3)));
  }
  return FX_ERR_Succeeded;
}
class CFX_Pause : public IFX_Pause {
 public:
  virtual FX_BOOL NeedToPauseNow() { return TRUE; }
};
