// 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/include/fxge/fx_ge.h"

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

#include "core/include/fxge/fx_ge_win32.h"
#include "core/src/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 = NULL;
  }
}
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);
  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
                                                   void** ppvObject);
  virtual ULONG STDMETHODCALLTYPE AddRef();
  virtual ULONG STDMETHODCALLTYPE Release();
  virtual HRESULT STDMETHODCALLTYPE
  ReadFileFragment(void const** fragmentStart,
                   UINT64 fileOffset,
                   UINT64 fragmentSize,
                   OUT void** fragmentContext);
  virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext);
  virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize);
  virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime);
  bool IsInitialized() { return resourcePtr_ != NULL; }

 private:
  ULONG refCount_;
  void const* resourcePtr_;
  DWORD resourceSize_;
};
class CDwFontFileLoader final : public IDWriteFontFileLoader {
 public:
  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,
                                                   void** ppvObject);
  virtual ULONG STDMETHODCALLTYPE AddRef();
  virtual ULONG STDMETHODCALLTYPE Release();
  virtual HRESULT STDMETHODCALLTYPE
  CreateStreamFromKey(void const* fontFileReferenceKey,
                      UINT32 fontFileReferenceKeySize,
                      OUT IDWriteFontFileStream** fontFileStream);

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

 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 = NULL;
  m_pDWriteFactory = NULL;
  m_pDwFontContext = NULL;
  m_pDwTextRenderer = NULL;
}
void CDWriteExt::Load() {}
void CDWriteExt::Unload() {
  if (m_pDwFontContext) {
    delete (CDwFontContext*)m_pDwFontContext;
    m_pDwFontContext = NULL;
  }
  SafeRelease((IDWriteFactory**)&m_pDWriteFactory);
}
CDWriteExt::~CDWriteExt() {
  Unload();
}
LPVOID CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData,
                                              FX_DWORD size,
                                              int simulation_style) {
  IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
  IDWriteFontFile* pDwFontFile = NULL;
  IDWriteFontFace* pDwFontFace = NULL;
  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 NULL;
}
FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap,
                                            void** renderTarget) {
  if (pBitmap->GetFormat() > FXDIB_Argb) {
    return FALSE;
  }
  IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
  IDWriteGdiInterop* pGdiInterop = NULL;
  IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL;
  IDWriteRenderingParams* pRenderingParams = NULL;
  HRESULT hr = S_OK;
  hr = pDwFactory->GetGdiInterop(&pGdiInterop);
  if (FAILED(hr)) {
    goto failed;
  }
  hr = pGdiInterop->CreateBitmapRenderTarget(
      NULL, 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 : NULL, 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 = NULL;
  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 = NULL;
    return S_OK;
  }
  *fragmentStart = NULL;
  *fragmentContext = NULL;
  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_ = NULL;
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 = NULL;
  return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() {
  return InterlockedIncrement((long*)(&refCount_));
}
ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() {
  ULONG newCount = InterlockedDecrement((long*)(&refCount_));
  if (newCount == 0) {
    instance_ = NULL;
    delete this;
  }
  return newCount;
}
HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey(
    void const* fontFileReferenceKey,
    UINT32 fontFileReferenceKeySize,
    OUT IDWriteFontFileStream** fontFileStream) {
  *fontFileStream = NULL;
  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, NULL);
  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
