// 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 "core/fxge/ge/cfx_cliprgn.h"
#include "core/fxge/include/fx_ge.h"

#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
#include <dwrite.h>

#include "core/fxge/win32/dwrite_int.h"

typedef HRESULT(__stdcall* FuncType_DWriteCreateFactory)(
    __in DWRITE_FACTORY_TYPE,
    __in REFIID,
    __out IUnknown**);
template <typename InterfaceType>
inline void SafeRelease(InterfaceType** currentObject) {
  if (*currentObject) {
    (*currentObject)->Release();
    *currentObject = nullptr;
  }
}
template <typename InterfaceType>
inline InterfaceType* SafeAcquire(InterfaceType* newObject) {
  if (newObject) {
    newObject->AddRef();
  }
  return newObject;
}

class CDwFontFileStream final : public IDWriteFontFileStream {
 public:
  explicit CDwFontFileStream(void const* fontFileReferenceKey,
                             UINT32 fontFileReferenceKeySize);

  // IUnknown.
  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
                                           void** ppvObject) override;
  ULONG STDMETHODCALLTYPE AddRef() override;
  ULONG STDMETHODCALLTYPE Release() override;

  // IDWriteFontFileStream.
  HRESULT STDMETHODCALLTYPE
  ReadFileFragment(void const** fragmentStart,
                   UINT64 fileOffset,
                   UINT64 fragmentSize,
                   OUT void** fragmentContext) override;
  void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext) override;
  HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize) override;
  HRESULT STDMETHODCALLTYPE
  GetLastWriteTime(OUT UINT64* lastWriteTime) override;

  bool IsInitialized() { return !!resourcePtr_; }

 private:
  ULONG refCount_;
  void const* resourcePtr_;
  DWORD resourceSize_;
};

class CDwFontFileLoader final : public IDWriteFontFileLoader {
 public:
  // IUnknown.
  HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
                                           void** ppvObject) override;
  ULONG STDMETHODCALLTYPE AddRef() override;
  ULONG STDMETHODCALLTYPE Release() override;

  // IDWriteFontFileLoader.
  HRESULT STDMETHODCALLTYPE
  CreateStreamFromKey(void const* fontFileReferenceKey,
                      UINT32 fontFileReferenceKeySize,
                      OUT IDWriteFontFileStream** fontFileStream) override;

  static IDWriteFontFileLoader* GetLoader() {
    if (!instance_) {
      instance_ = new CDwFontFileLoader();
    }
    return instance_;
  }
  static bool IsLoaderInitialized() { return !!instance_; }

 private:
  CDwFontFileLoader();
  ULONG refCount_;
  static IDWriteFontFileLoader* instance_;
};

class CDwFontContext {
 public:
  CDwFontContext(IDWriteFactory* dwriteFactory);
  ~CDwFontContext();

  HRESULT Initialize();

 private:
  CDwFontContext(CDwFontContext const&);
  void operator=(CDwFontContext const&);
  HRESULT hr_;
  IDWriteFactory* dwriteFactory_;
};

class CDwGdiTextRenderer {
 public:
  CDwGdiTextRenderer(CFX_DIBitmap* pBitmap,
                     IDWriteBitmapRenderTarget* bitmapRenderTarget,
                     IDWriteRenderingParams* renderingParams);
  ~CDwGdiTextRenderer();

  HRESULT STDMETHODCALLTYPE DrawGlyphRun(const FX_RECT& text_bbox,
                                         __in_opt CFX_ClipRgn* pClipRgn,
                                         __in_opt DWRITE_MATRIX const* pMatrix,
                                         FLOAT baselineOriginX,
                                         FLOAT baselineOriginY,
                                         DWRITE_MEASURING_MODE measuringMode,
                                         __in DWRITE_GLYPH_RUN const* glyphRun,
                                         const COLORREF& textColor);

 private:
  CFX_DIBitmap* pBitmap_;
  IDWriteBitmapRenderTarget* pRenderTarget_;
  IDWriteRenderingParams* pRenderingParams_;
};

CDWriteExt::CDWriteExt()
    : m_hModule(nullptr),
      m_pDWriteFactory(nullptr),
      m_pDwFontContext(nullptr),
      m_pDwTextRenderer(nullptr) {}

void CDWriteExt::Load() {}

void CDWriteExt::Unload() {
  if (m_pDwFontContext) {
    delete (CDwFontContext*)m_pDwFontContext;
    m_pDwFontContext = nullptr;
  }
  SafeRelease((IDWriteFactory**)&m_pDWriteFactory);
}

CDWriteExt::~CDWriteExt() {
  Unload();
}

LPVOID CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData,
                                              uint32_t size,
                                              int simulation_style) {
  IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
  IDWriteFontFile* pDwFontFile = nullptr;
  IDWriteFontFace* pDwFontFace = nullptr;
  BOOL isSupportedFontType = FALSE;
  DWRITE_FONT_FILE_TYPE fontFileType;
  DWRITE_FONT_FACE_TYPE fontFaceType;
  UINT32 numberOfFaces;
  DWRITE_FONT_SIMULATIONS fontStyle =
      (DWRITE_FONT_SIMULATIONS)(simulation_style & 3);
  HRESULT hr = S_OK;
  hr = pDwFactory->CreateCustomFontFileReference(
      (void const*)pData, (UINT32)size, CDwFontFileLoader::GetLoader(),
      &pDwFontFile);
  if (FAILED(hr)) {
    goto failed;
  }
  hr = pDwFontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType,
                            &numberOfFaces);
  if (FAILED(hr) || !isSupportedFontType ||
      fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) {
    goto failed;
  }
  hr = pDwFactory->CreateFontFace(fontFaceType, 1, &pDwFontFile, 0, fontStyle,
                                  &pDwFontFace);
  if (FAILED(hr)) {
    goto failed;
  }
  SafeRelease(&pDwFontFile);
  return pDwFontFace;
failed:
  SafeRelease(&pDwFontFile);
  return nullptr;
}

FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap,
                                            void** renderTarget) {
  if (pBitmap->GetFormat() > FXDIB_Argb) {
    return FALSE;
  }
  IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
  IDWriteGdiInterop* pGdiInterop = nullptr;
  IDWriteBitmapRenderTarget* pBitmapRenderTarget = nullptr;
  IDWriteRenderingParams* pRenderingParams = nullptr;
  HRESULT hr = S_OK;
  hr = pDwFactory->GetGdiInterop(&pGdiInterop);
  if (FAILED(hr)) {
    goto failed;
  }
  hr = pGdiInterop->CreateBitmapRenderTarget(
      nullptr, pBitmap->GetWidth(), pBitmap->GetHeight(), &pBitmapRenderTarget);
  if (FAILED(hr)) {
    goto failed;
  }
  hr = pDwFactory->CreateCustomRenderingParams(
      1.0f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_RGB,
      DWRITE_RENDERING_MODE_DEFAULT, &pRenderingParams);
  if (FAILED(hr)) {
    goto failed;
  }
  hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f);
  if (FAILED(hr)) {
    goto failed;
  }
  *(CDwGdiTextRenderer**)renderTarget =
      new CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams);
  SafeRelease(&pGdiInterop);
  SafeRelease(&pBitmapRenderTarget);
  SafeRelease(&pRenderingParams);
  return TRUE;
failed:
  SafeRelease(&pGdiInterop);
  SafeRelease(&pBitmapRenderTarget);
  SafeRelease(&pRenderingParams);
  return FALSE;
}

FX_BOOL CDWriteExt::DwRendingString(void* renderTarget,
                                    CFX_ClipRgn* pClipRgn,
                                    FX_RECT& stringRect,
                                    CFX_Matrix* pMatrix,
                                    void* font,
                                    FX_FLOAT font_size,
                                    FX_ARGB text_color,
                                    int glyph_count,
                                    unsigned short* glyph_indices,
                                    FX_FLOAT baselineOriginX,
                                    FX_FLOAT baselineOriginY,
                                    void* glyph_offsets,
                                    FX_FLOAT* glyph_advances) {
  if (!renderTarget) {
    return TRUE;
  }
  CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget;
  DWRITE_MATRIX transform;
  DWRITE_GLYPH_RUN glyphRun;
  HRESULT hr = S_OK;
  if (pMatrix) {
    transform.m11 = pMatrix->a;
    transform.m12 = pMatrix->b;
    transform.m21 = pMatrix->c;
    transform.m22 = pMatrix->d;
    transform.dx = pMatrix->e;
    transform.dy = pMatrix->f;
  }
  glyphRun.fontFace = (IDWriteFontFace*)font;
  glyphRun.fontEmSize = font_size;
  glyphRun.glyphCount = glyph_count;
  glyphRun.glyphIndices = glyph_indices;
  glyphRun.glyphAdvances = glyph_advances;
  glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets;
  glyphRun.isSideways = FALSE;
  glyphRun.bidiLevel = 0;
  hr = pTextRenderer->DrawGlyphRun(
      stringRect, pClipRgn, pMatrix ? &transform : nullptr, baselineOriginX,
      baselineOriginY, DWRITE_MEASURING_MODE_NATURAL, &glyphRun,
      RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color)));
  return SUCCEEDED(hr);
}

void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget) {
  delete (CDwGdiTextRenderer*)renderTarget;
}

void CDWriteExt::DwDeleteFont(void* pFont) {
  if (pFont) {
    SafeRelease((IDWriteFontFace**)&pFont);
  }
}

CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey,
                                     UINT32 fontFileReferenceKeySize) {
  refCount_ = 0;
  resourcePtr_ = fontFileReferenceKey;
  resourceSize_ = fontFileReferenceKeySize;
}

HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid,
                                                            void** ppvObject) {
  if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
    *ppvObject = this;
    AddRef();
    return S_OK;
  }
  *ppvObject = nullptr;
  return E_NOINTERFACE;
}

ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef() {
  return InterlockedIncrement((long*)(&refCount_));
}

ULONG STDMETHODCALLTYPE CDwFontFileStream::Release() {
  ULONG newCount = InterlockedDecrement((long*)(&refCount_));
  if (newCount == 0) {
    delete this;
  }
  return newCount;
}

HRESULT STDMETHODCALLTYPE
CDwFontFileStream::ReadFileFragment(void const** fragmentStart,
                                    UINT64 fileOffset,
                                    UINT64 fragmentSize,
                                    OUT void** fragmentContext) {
  if (fileOffset <= resourceSize_ &&
      fragmentSize <= resourceSize_ - fileOffset) {
    *fragmentStart = static_cast<uint8_t const*>(resourcePtr_) +
                     static_cast<size_t>(fileOffset);
    *fragmentContext = nullptr;
    return S_OK;
  }
  *fragmentStart = nullptr;
  *fragmentContext = nullptr;
  return E_FAIL;
}

void STDMETHODCALLTYPE
CDwFontFileStream::ReleaseFileFragment(void* fragmentContext) {}
HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize) {
  *fileSize = resourceSize_;
  return S_OK;
}

HRESULT STDMETHODCALLTYPE
CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime) {
  *lastWriteTime = 0;
  return E_NOTIMPL;
}

IDWriteFontFileLoader* CDwFontFileLoader::instance_ = nullptr;
CDwFontFileLoader::CDwFontFileLoader() : refCount_(0) {}
HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid,
                                                            void** ppvObject) {
  if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
    *ppvObject = this;
    AddRef();
    return S_OK;
  }
  *ppvObject = nullptr;
  return E_NOINTERFACE;
}

ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() {
  return InterlockedIncrement((long*)(&refCount_));
}

ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() {
  ULONG newCount = InterlockedDecrement((long*)(&refCount_));
  if (newCount == 0) {
    instance_ = nullptr;
    delete this;
  }
  return newCount;
}

HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey(
    void const* fontFileReferenceKey,
    UINT32 fontFileReferenceKeySize,
    OUT IDWriteFontFileStream** fontFileStream) {
  *fontFileStream = nullptr;
  CDwFontFileStream* stream =
      new CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize);
  if (!stream->IsInitialized()) {
    delete stream;
    return E_FAIL;
  }
  *fontFileStream = SafeAcquire(stream);
  return S_OK;
}

CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory)
    : hr_(S_FALSE), dwriteFactory_(SafeAcquire(dwriteFactory)) {}

CDwFontContext::~CDwFontContext() {
  if (dwriteFactory_ && hr_ == S_OK) {
    dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader());
  }
  SafeRelease(&dwriteFactory_);
}

HRESULT CDwFontContext::Initialize() {
  if (hr_ == S_FALSE) {
    return hr_ = dwriteFactory_->RegisterFontFileLoader(
               CDwFontFileLoader::GetLoader());
  }
  return hr_;
}

CDwGdiTextRenderer::CDwGdiTextRenderer(
    CFX_DIBitmap* pBitmap,
    IDWriteBitmapRenderTarget* bitmapRenderTarget,
    IDWriteRenderingParams* renderingParams)
    : pBitmap_(pBitmap),
      pRenderTarget_(SafeAcquire(bitmapRenderTarget)),
      pRenderingParams_(SafeAcquire(renderingParams)) {}
CDwGdiTextRenderer::~CDwGdiTextRenderer() {
  SafeRelease(&pRenderTarget_);
  SafeRelease(&pRenderingParams_);
}

STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun(
    const FX_RECT& text_bbox,
    __in_opt CFX_ClipRgn* pClipRgn,
    __in_opt DWRITE_MATRIX const* pMatrix,
    FLOAT baselineOriginX,
    FLOAT baselineOriginY,
    DWRITE_MEASURING_MODE measuringMode,
    __in DWRITE_GLYPH_RUN const* glyphRun,
    const COLORREF& textColor) {
  HRESULT hr = S_OK;
  if (pMatrix) {
    hr = pRenderTarget_->SetCurrentTransform(pMatrix);
    if (FAILED(hr)) {
      return hr;
    }
  }
  HDC hDC = pRenderTarget_->GetMemoryDC();
  HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP);
  BITMAP bitmap;
  GetObject(hBitmap, sizeof bitmap, &bitmap);
  CFX_DIBitmap dib;
  dib.Create(bitmap.bmWidth, bitmap.bmHeight,
             bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32,
             (uint8_t*)bitmap.bmBits);
  dib.CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(),
                      text_bbox.Height(), pBitmap_, text_bbox.left,
                      text_bbox.top, FXDIB_BLEND_NORMAL, nullptr);
  hr = pRenderTarget_->DrawGlyphRun(baselineOriginX, baselineOriginY,
                                    measuringMode, glyphRun, pRenderingParams_,
                                    textColor);
  if (FAILED(hr)) {
    return hr;
  }
  pBitmap_->CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(),
                            text_bbox.Height(), &dib, text_bbox.left,
                            text_bbox.top, FXDIB_BLEND_NORMAL, pClipRgn);
  return hr;
}
#endif
