// 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;
}
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_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)
{
    if (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;
    } else {
        *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;
    } else {
        *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;
    } else {
        *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
