// 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 "../../../include/fxge/fx_ge.h"
#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
#include "../../../include/fxge/fx_ge_win32.h"
#include "dwrite_int.h"
#include <dwrite.h>
typedef HRESULT  (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_TYPE, __in REFIID, __out IUnknown **);
template <typename InterfaceType>
inline void SafeRelease(InterfaceType** currentObject)
{
    if (*currentObject != NULL) {
        (*currentObject)->Release();
        *currentObject = NULL;
    }
}
template <typename InterfaceType>
inline InterfaceType* SafeAcquire(InterfaceType* newObject)
{
    if (newObject != NULL) {
        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_ == NULL) {
            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;
}
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;
}
bool	CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* 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 == NULL) {
        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) ? true : false;
}
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
