// 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 <dwrite.h>

#include "core/fxcrt/fx_system.h"
#include "core/fxge/cfx_cliprgn.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:
  explicit CDwFontContext(IDWriteFactory* dwriteFactory);
  ~CDwFontContext();

  HRESULT Initialize();

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

class CDwGdiTextRenderer {
 public:
  CDwGdiTextRenderer(const RetainPtr<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:
  RetainPtr<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;
}

bool CDWriteExt::DwCreateRenderingTarget(const RetainPtr<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;
}

bool CDWriteExt::DwRendingString(void* renderTarget,
                                 CFX_ClipRgn* pClipRgn,
                                 FX_RECT& stringRect,
                                 CFX_Matrix* pMatrix,
                                 void* font,
                                 float font_size,
                                 FX_ARGB text_color,
                                 int glyph_count,
                                 unsigned short* glyph_indices,
                                 float baselineOriginX,
                                 float baselineOriginY,
                                 void* glyph_offsets,
                                 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(
    const RetainPtr<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);
  auto dib = pdfium::MakeRetain<CFX_DIBitmap>();
  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;
}
