/* vi:set ts=8 sts=4 sw=4 noet: */
/*
 * Author: MURAOKA Taro <koron.kaoriya@gmail.com>
 *
 * Contributors:
 *  - Ken Takata
 *
 * Copyright (C) 2013 MURAOKA Taro <koron.kaoriya@gmail.com>
 * THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
 */

#define WIN32_LEAN_AND_MEAN

#ifndef DYNAMIC_DIRECTX
# if WINVER < 0x0600
#  error WINVER must be 0x0600 or above to use DirectWrite(DirectX)
# endif
#endif

#include <windows.h>
#include <crtdbg.h>
#include <assert.h>
#include <math.h>
#include <d2d1.h>
#include <d2d1helper.h>
#include <dwrite.h>

#include "gui_dwrite.h"

#ifdef __MINGW32__
# define __maybenull	SAL__maybenull
# define __in		SAL__in
# define __out		SAL__out
#endif

#ifdef DYNAMIC_DIRECTX
extern "C" HINSTANCE vimLoadLib(char *name);

typedef int (WINAPI *PGETUSERDEFAULTLOCALENAME)(LPWSTR, int);
typedef HRESULT (WINAPI *PD2D1CREATEFACTORY)(D2D1_FACTORY_TYPE,
	REFIID, const D2D1_FACTORY_OPTIONS *, void **);
typedef HRESULT (WINAPI *PDWRITECREATEFACTORY)(DWRITE_FACTORY_TYPE,
	REFIID, IUnknown **);

static HINSTANCE hD2D1DLL = NULL;
static HINSTANCE hDWriteDLL = NULL;

static PGETUSERDEFAULTLOCALENAME pGetUserDefaultLocaleName = NULL;
static PD2D1CREATEFACTORY pD2D1CreateFactory = NULL;
static PDWRITECREATEFACTORY pDWriteCreateFactory = NULL;

#define GetUserDefaultLocaleName	(*pGetUserDefaultLocaleName)
#define D2D1CreateFactory		(*pD2D1CreateFactory)
#define DWriteCreateFactory		(*pDWriteCreateFactory)

    static void
unload(HINSTANCE &hinst)
{
    if (hinst != NULL)
    {
	FreeLibrary(hinst);
	hinst = NULL;
    }
}
#endif // DYNAMIC_DIRECTX

template <class T> inline void SafeRelease(T **ppT)
{
    if (*ppT)
    {
	(*ppT)->Release();
	*ppT = NULL;
    }
}

struct GdiTextRendererContext
{
    // const fields.
    COLORREF color;
    FLOAT cellWidth;

    // working fields.
    FLOAT offsetX;
};

    static DWRITE_PIXEL_GEOMETRY
ToPixelGeometry(int value)
{
    switch (value)
    {
	default:
	case 0:
	    return DWRITE_PIXEL_GEOMETRY_FLAT;
	case 1:
	    return DWRITE_PIXEL_GEOMETRY_RGB;
	case 2:
	    return DWRITE_PIXEL_GEOMETRY_BGR;
    }
}

    static int
ToInt(DWRITE_PIXEL_GEOMETRY value)
{
    switch (value)
    {
	case DWRITE_PIXEL_GEOMETRY_FLAT:
	    return 0;
	case DWRITE_PIXEL_GEOMETRY_RGB:
	    return 1;
	case DWRITE_PIXEL_GEOMETRY_BGR:
	    return 2;
	default:
	    return -1;
    }
}

    static DWRITE_RENDERING_MODE
ToRenderingMode(int value)
{
    switch (value)
    {
	default:
	case 0:
	    return DWRITE_RENDERING_MODE_DEFAULT;
	case 1:
	    return DWRITE_RENDERING_MODE_ALIASED;
	case 2:
	    return DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC;
	case 3:
	    return DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL;
	case 4:
	    return DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
	case 5:
	    return DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
	case 6:
	    return DWRITE_RENDERING_MODE_OUTLINE;
    }
}

    static D2D1_TEXT_ANTIALIAS_MODE
ToTextAntialiasMode(int value)
{
    switch (value)
    {
	default:
	case 0:
	    return D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
	case 1:
	    return D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
	case 2:
	    return D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
	case 3:
	    return D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
    }
}

    static int
ToInt(DWRITE_RENDERING_MODE value)
{
    switch (value)
    {
	case DWRITE_RENDERING_MODE_DEFAULT:
	    return 0;
	case DWRITE_RENDERING_MODE_ALIASED:
	    return 1;
	case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC:
	    return 2;
	case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL:
	    return 3;
	case DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL:
	    return 4;
	case DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC:
	    return 5;
	case DWRITE_RENDERING_MODE_OUTLINE:
	    return 6;
	default:
	    return -1;
    }
}

class AdjustedGlyphRun : public DWRITE_GLYPH_RUN
{
private:
    FLOAT mDelta;
    FLOAT *mAdjustedAdvances;

public:
    AdjustedGlyphRun(
	    const DWRITE_GLYPH_RUN *glyphRun,
	    FLOAT cellWidth) :
	DWRITE_GLYPH_RUN(*glyphRun),
	mDelta(0.0f),
	mAdjustedAdvances(new FLOAT[glyphRun->glyphCount])
    {
	assert(cellWidth != 0.0f);
	for (UINT32 i = 0; i < glyphRun->glyphCount; ++i)
	{
	    FLOAT orig = glyphRun->glyphAdvances[i];
	    FLOAT adjusted = adjustToCell(orig, cellWidth);
	    mAdjustedAdvances[i] = adjusted;
	    mDelta += adjusted - orig;
	}
	glyphAdvances = mAdjustedAdvances;
    }

    ~AdjustedGlyphRun(void)
    {
	delete[] mAdjustedAdvances;
    }

    FLOAT getDelta(void) const
    {
	return mDelta;
    }

    static FLOAT adjustToCell(FLOAT value, FLOAT cellWidth)
    {
	int cellCount = (int)floor(value / cellWidth + 0.5f);
	if (cellCount < 1)
	    cellCount = 1;
	return cellCount * cellWidth;
    }
};

class GdiTextRenderer : public IDWriteTextRenderer
{
public:
    GdiTextRenderer(
	    IDWriteBitmapRenderTarget* bitmapRenderTarget,
	    IDWriteRenderingParams* renderingParams) :
	cRefCount_(0),
	pRenderTarget_(bitmapRenderTarget),
	pRenderingParams_(renderingParams)
    {
	pRenderTarget_->AddRef();
	pRenderingParams_->AddRef();
	AddRef();
    }

    ~GdiTextRenderer()
    {
	SafeRelease(&pRenderTarget_);
	SafeRelease(&pRenderingParams_);
    }

    IFACEMETHOD(IsPixelSnappingDisabled)(
	__maybenull void* clientDrawingContext,
	__out BOOL* isDisabled)
    {
	*isDisabled = FALSE;
	return S_OK;
    }

    IFACEMETHOD(GetCurrentTransform)(
	__maybenull void* clientDrawingContext,
	__out DWRITE_MATRIX* transform)
    {
	//forward the render target's transform
	pRenderTarget_->GetCurrentTransform(transform);
	return S_OK;
    }

    IFACEMETHOD(GetPixelsPerDip)(
	__maybenull void* clientDrawingContext,
	__out FLOAT* pixelsPerDip)
    {
	*pixelsPerDip = pRenderTarget_->GetPixelsPerDip();
	return S_OK;
    }

    IFACEMETHOD(DrawGlyphRun)(
	__maybenull void* clientDrawingContext,
	FLOAT baselineOriginX,
	FLOAT baselineOriginY,
	DWRITE_MEASURING_MODE measuringMode,
	__in DWRITE_GLYPH_RUN const* glyphRun,
	__in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
	IUnknown* clientDrawingEffect)
    {
	HRESULT hr = S_OK;

	GdiTextRendererContext *context =
	    reinterpret_cast<GdiTextRendererContext*>(clientDrawingContext);

	AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth);

	// Pass on the drawing call to the render target to do the real work.
	RECT dirtyRect = {0};

	hr = pRenderTarget_->DrawGlyphRun(
		baselineOriginX + context->offsetX,
		baselineOriginY,
		measuringMode,
		&adjustedGlyphRun,
		pRenderingParams_,
		context->color,
		&dirtyRect);

	context->offsetX += adjustedGlyphRun.getDelta();

	return hr;
    }

    IFACEMETHOD(DrawUnderline)(
	__maybenull void* clientDrawingContext,
	FLOAT baselineOriginX,
	FLOAT baselineOriginY,
	__in DWRITE_UNDERLINE const* underline,
	IUnknown* clientDrawingEffect)
    {
	return E_NOTIMPL;
    }

    IFACEMETHOD(DrawStrikethrough)(
	__maybenull void* clientDrawingContext,
	FLOAT baselineOriginX,
	FLOAT baselineOriginY,
	__in DWRITE_STRIKETHROUGH const* strikethrough,
	IUnknown* clientDrawingEffect)
    {
	return E_NOTIMPL;
    }

    IFACEMETHOD(DrawInlineObject)(
	__maybenull void* clientDrawingContext,
	FLOAT originX,
	FLOAT originY,
	IDWriteInlineObject* inlineObject,
	BOOL isSideways,
	BOOL isRightToLeft,
	IUnknown* clientDrawingEffect)
    {
	return E_NOTIMPL;
    }

public:
    IFACEMETHOD_(unsigned long, AddRef) ()
    {
	return InterlockedIncrement(&cRefCount_);
    }

    IFACEMETHOD_(unsigned long, Release) ()
    {
	long newCount = InterlockedDecrement(&cRefCount_);

	if (newCount == 0)
	{
	    delete this;
	    return 0;
	}
	return newCount;
    }

    IFACEMETHOD(QueryInterface)(
	IID const& riid,
	void** ppvObject)
    {
	if (__uuidof(IDWriteTextRenderer) == riid)
	{
	    *ppvObject = this;
	}
	else if (__uuidof(IDWritePixelSnapping) == riid)
	{
	    *ppvObject = this;
	}
	else if (__uuidof(IUnknown) == riid)
	{
	    *ppvObject = this;
	}
	else
	{
	    *ppvObject = NULL;
	    return E_FAIL;
	}

	return S_OK;
    }

private:
    long cRefCount_;
    IDWriteBitmapRenderTarget* pRenderTarget_;
    IDWriteRenderingParams* pRenderingParams_;
};

struct DWriteContext {
    FLOAT mDpiScaleX;
    FLOAT mDpiScaleY;
    bool mDrawing;

    ID2D1Factory *mD2D1Factory;

    ID2D1DCRenderTarget *mRT;
    ID2D1SolidColorBrush *mBrush;

    IDWriteFactory *mDWriteFactory;
    IDWriteGdiInterop *mGdiInterop;
    IDWriteRenderingParams *mRenderingParams;
    IDWriteTextFormat *mTextFormat;

    HFONT mLastHFont;
    DWRITE_FONT_WEIGHT mFontWeight;
    DWRITE_FONT_STYLE mFontStyle;

    D2D1_TEXT_ANTIALIAS_MODE mTextAntialiasMode;

    // METHODS

    DWriteContext();

    virtual ~DWriteContext();

    HRESULT SetLOGFONT(const LOGFONTW &logFont, float fontSize);

    void SetFont(HFONT hFont);

    void SetFont(const LOGFONTW &logFont);

    void DrawText(HDC hdc, const WCHAR* text, int len,
	int x, int y, int w, int h, int cellWidth, COLORREF color);

    float PixelsToDipsX(int x);

    float PixelsToDipsY(int y);

    void SetRenderingParams(
	    const DWriteRenderingParams *params);

    DWriteRenderingParams *GetRenderingParams(
	    DWriteRenderingParams *params);
};

DWriteContext::DWriteContext() :
    mDpiScaleX(1.f),
    mDpiScaleY(1.f),
    mDrawing(false),
    mD2D1Factory(NULL),
    mRT(NULL),
    mBrush(NULL),
    mDWriteFactory(NULL),
    mGdiInterop(NULL),
    mRenderingParams(NULL),
    mTextFormat(NULL),
    mLastHFont(NULL),
    mFontWeight(DWRITE_FONT_WEIGHT_NORMAL),
    mFontStyle(DWRITE_FONT_STYLE_NORMAL),
    mTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_DEFAULT)
{
    HRESULT hr;

    HDC screen = ::GetDC(0);
    mDpiScaleX = ::GetDeviceCaps(screen, LOGPIXELSX) / 96.0f;
    mDpiScaleY = ::GetDeviceCaps(screen, LOGPIXELSY) / 96.0f;
    ::ReleaseDC(0, screen);

    hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
	    __uuidof(ID2D1Factory), NULL,
	    reinterpret_cast<void**>(&mD2D1Factory));
    _RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory);

    if (SUCCEEDED(hr))
    {
	D2D1_RENDER_TARGET_PROPERTIES props = {
	    D2D1_RENDER_TARGET_TYPE_DEFAULT,
	    { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
	    0, 0,
	    D2D1_RENDER_TARGET_USAGE_NONE,
	    D2D1_FEATURE_LEVEL_DEFAULT
	};
	hr = mD2D1Factory->CreateDCRenderTarget(&props, &mRT);
	_RPT2(_CRT_WARN, "CreateDCRenderTarget: hr=%p p=%p\n", hr, mRT);
    }

    if (SUCCEEDED(hr))
    {
	hr = mRT->CreateSolidColorBrush(
		D2D1::ColorF(D2D1::ColorF::Black),
		&mBrush);
	_RPT2(_CRT_WARN, "CreateSolidColorBrush: hr=%p p=%p\n", hr, mBrush);
    }

    if (SUCCEEDED(hr))
    {
	hr = DWriteCreateFactory(
		DWRITE_FACTORY_TYPE_SHARED,
		__uuidof(IDWriteFactory),
		reinterpret_cast<IUnknown**>(&mDWriteFactory));
	_RPT2(_CRT_WARN, "DWriteCreateFactory: hr=%p p=%p\n", hr,
		mDWriteFactory);
    }

    if (SUCCEEDED(hr))
    {
	hr = mDWriteFactory->GetGdiInterop(&mGdiInterop);
	_RPT2(_CRT_WARN, "GetGdiInterop: hr=%p p=%p\n", hr, mGdiInterop);
    }

    if (SUCCEEDED(hr))
    {
	hr = mDWriteFactory->CreateRenderingParams(&mRenderingParams);
	_RPT2(_CRT_WARN, "CreateRenderingParams: hr=%p p=%p\n", hr,
		mRenderingParams);
    }
}

DWriteContext::~DWriteContext()
{
    SafeRelease(&mTextFormat);
    SafeRelease(&mRenderingParams);
    SafeRelease(&mGdiInterop);
    SafeRelease(&mDWriteFactory);
    SafeRelease(&mBrush);
    SafeRelease(&mRT);
    SafeRelease(&mD2D1Factory);
}

    HRESULT
DWriteContext::SetLOGFONT(const LOGFONTW &logFont, float fontSize)
{
    // Most of this function is copy from: http://msdn.microsoft.com/en-us/library/windows/desktop/dd941783(v=vs.85).aspx
    HRESULT hr = S_OK;

    IDWriteFont *font = NULL;
    IDWriteFontFamily *fontFamily = NULL;
    IDWriteLocalizedStrings *localizedFamilyNames = NULL;

    if (SUCCEEDED(hr))
    {
	hr = mGdiInterop->CreateFontFromLOGFONT(&logFont, &font);
    }

    // Get the font family to which this font belongs.
    if (SUCCEEDED(hr))
    {
	hr = font->GetFontFamily(&fontFamily);
    }

    // Get the family names. This returns an object that encapsulates one or
    // more names with the same meaning but in different languages.
    if (SUCCEEDED(hr))
    {
	hr = fontFamily->GetFamilyNames(&localizedFamilyNames);
    }

    // Get the family name at index zero. If we were going to display the name
    // we'd want to try to find one that matched the use locale, but for
    // purposes of creating a text format object any language will do.

    wchar_t familyName[100];
    if (SUCCEEDED(hr))
    {
	hr = localizedFamilyNames->GetString(0, familyName,
		ARRAYSIZE(familyName));
    }

    if (SUCCEEDED(hr))
    {
	// If no font size was passed in use the lfHeight of the LOGFONT.
	if (fontSize == 0)
	{
	    // Convert from pixels to DIPs.
	    fontSize = PixelsToDipsY(logFont.lfHeight);
	    if (fontSize < 0)
	    {
		// Negative lfHeight represents the size of the em unit.
		fontSize = -fontSize;
	    }
	    else
	    {
		// Positive lfHeight represents the cell height (ascent +
		// descent).
		DWRITE_FONT_METRICS fontMetrics;
		font->GetMetrics(&fontMetrics);

		// Convert the cell height (ascent + descent) from design units
		// to ems.
		float cellHeight = static_cast<float>(
			fontMetrics.ascent + fontMetrics.descent)
					       / fontMetrics.designUnitsPerEm;

		// Divide the font size by the cell height to get the font em
		// size.
		fontSize /= cellHeight;
	    }
	}
    }

    // The text format includes a locale name. Ideally, this would be the
    // language of the text, which may or may not be the same as the primary
    // language of the user. However, for our purposes the user locale will do.
    wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
    if (SUCCEEDED(hr))
    {
	if (GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH) == 0)
	    hr = HRESULT_FROM_WIN32(GetLastError());
    }

    if (SUCCEEDED(hr))
    {
	// Create the text format object.
	hr = mDWriteFactory->CreateTextFormat(
		familyName,
		NULL, // no custom font collection
		font->GetWeight(),
		font->GetStyle(),
		font->GetStretch(),
		fontSize,
		localeName,
		&mTextFormat);
    }

    if (SUCCEEDED(hr))
    {
	mFontWeight = static_cast<DWRITE_FONT_WEIGHT>(logFont.lfWeight);
	mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC
	    : DWRITE_FONT_STYLE_NORMAL;
    }

    SafeRelease(&localizedFamilyNames);
    SafeRelease(&fontFamily);
    SafeRelease(&font);

    return hr;
}

    void
DWriteContext::SetFont(HFONT hFont)
{
    if (mLastHFont != hFont)
    {
	LOGFONTW lf;
	if (GetObjectW(hFont, sizeof(lf), &lf))
	{
	    SetFont(lf);
	    mLastHFont = hFont;
	}
    }
}

    void
DWriteContext::SetFont(const LOGFONTW &logFont)
{
    SafeRelease(&mTextFormat);
    mLastHFont = NULL;

    HRESULT hr = SetLOGFONT(logFont, 0.f);

    if (SUCCEEDED(hr))
	hr = mTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);

    if (SUCCEEDED(hr))
	hr = mTextFormat->SetParagraphAlignment(
		DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

    if (SUCCEEDED(hr))
	hr = mTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
}

    void
DWriteContext::DrawText(HDC hdc, const WCHAR* text, int len,
	int x, int y, int w, int h, int cellWidth, COLORREF color)
{
    HRESULT hr = S_OK;
    IDWriteBitmapRenderTarget *bmpRT = NULL;

    // Skip when any fonts are not set.
    if (mTextFormat == NULL)
	return;

    // Check possibility of zero divided error.
    if (cellWidth == 0 || mDpiScaleX == 0.0f || mDpiScaleY == 0.0f)
	return;

    if (SUCCEEDED(hr))
	hr = mGdiInterop->CreateBitmapRenderTarget(hdc, w, h, &bmpRT);

    if (SUCCEEDED(hr))
    {
	IDWriteTextLayout *textLayout = NULL;

	HDC memdc = bmpRT->GetMemoryDC();
	BitBlt(memdc, 0, 0, w, h, hdc, x, y, SRCCOPY);

	hr = mDWriteFactory->CreateGdiCompatibleTextLayout(
		text, len, mTextFormat, PixelsToDipsX(w),
		PixelsToDipsY(h), mDpiScaleX, NULL, TRUE, &textLayout);

	if (SUCCEEDED(hr))
	{
	    DWRITE_TEXT_RANGE textRange = { 0, (UINT32)len };
	    textLayout->SetFontWeight(mFontWeight, textRange);
	    textLayout->SetFontStyle(mFontStyle, textRange);
	}

	if (SUCCEEDED(hr))
	{
	    GdiTextRenderer *renderer = new GdiTextRenderer(bmpRT,
		    mRenderingParams);
	    GdiTextRendererContext data = {
		color,
		PixelsToDipsX(cellWidth),
		0.0f
	    };
	    textLayout->Draw(&data, renderer, 0, 0);
	    SafeRelease(&renderer);
	}

	BitBlt(hdc, x, y, w, h, memdc, 0, 0, SRCCOPY);

	SafeRelease(&textLayout);
    }

    SafeRelease(&bmpRT);
}

    float
DWriteContext::PixelsToDipsX(int x)
{
    return x / mDpiScaleX;
}

    float
DWriteContext::PixelsToDipsY(int y)
{
    return y / mDpiScaleY;
}

    void
DWriteContext::SetRenderingParams(
	const DWriteRenderingParams *params)
{
    if (mDWriteFactory == NULL)
	return;

    IDWriteRenderingParams *renderingParams = NULL;
    D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode =
	D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
    HRESULT hr;
    if (params != NULL)
    {
	hr = mDWriteFactory->CreateCustomRenderingParams(params->gamma,
		params->enhancedContrast, params->clearTypeLevel,
		ToPixelGeometry(params->pixelGeometry),
		ToRenderingMode(params->renderingMode), &renderingParams);
	textAntialiasMode = ToTextAntialiasMode(params->textAntialiasMode);
    }
    else
	hr = mDWriteFactory->CreateRenderingParams(&renderingParams);
    if (SUCCEEDED(hr) && renderingParams != NULL)
    {
	SafeRelease(&mRenderingParams);
	mRenderingParams = renderingParams;
	mTextAntialiasMode = textAntialiasMode;
    }
}

    DWriteRenderingParams *
DWriteContext::GetRenderingParams(
	DWriteRenderingParams *params)
{
    if (params != NULL && mRenderingParams != NULL)
    {
	params->gamma = mRenderingParams->GetGamma();
	params->enhancedContrast = mRenderingParams->GetEnhancedContrast();
	params->clearTypeLevel = mRenderingParams->GetClearTypeLevel();
	params->pixelGeometry = ToInt(mRenderingParams->GetPixelGeometry());
	params->renderingMode = ToInt(mRenderingParams->GetRenderingMode());
	params->textAntialiasMode = mTextAntialiasMode;
    }
    return params;
}

////////////////////////////////////////////////////////////////////////////
// PUBLIC C INTERFACES

    void
DWrite_Init(void)
{
#ifdef DYNAMIC_DIRECTX
    // Load libraries.
    hD2D1DLL = vimLoadLib(const_cast<char*>("d2d1.dll"));
    hDWriteDLL = vimLoadLib(const_cast<char*>("dwrite.dll"));
    if (hD2D1DLL == NULL || hDWriteDLL == NULL)
    {
	DWrite_Final();
	return;
    }
    // Get address of procedures.
    pGetUserDefaultLocaleName = (PGETUSERDEFAULTLOCALENAME)GetProcAddress(
	    GetModuleHandle("kernel32.dll"), "GetUserDefaultLocaleName");
    pD2D1CreateFactory = (PD2D1CREATEFACTORY)GetProcAddress(hD2D1DLL,
	    "D2D1CreateFactory");
    pDWriteCreateFactory = (PDWRITECREATEFACTORY)GetProcAddress(hDWriteDLL,
	    "DWriteCreateFactory");
#endif
}

    void
DWrite_Final(void)
{
#ifdef DYNAMIC_DIRECTX
    pGetUserDefaultLocaleName = NULL;
    pD2D1CreateFactory = NULL;
    pDWriteCreateFactory = NULL;
    unload(hDWriteDLL);
    unload(hD2D1DLL);
#endif
}

    DWriteContext *
DWriteContext_Open(void)
{
#ifdef DYNAMIC_DIRECTX
    if (pGetUserDefaultLocaleName == NULL || pD2D1CreateFactory == NULL
	    || pDWriteCreateFactory == NULL)
	return NULL;
#endif
    return new DWriteContext();
}

    void
DWriteContext_BeginDraw(DWriteContext *ctx)
{
    if (ctx != NULL && ctx->mRT != NULL)
    {
	ctx->mRT->BeginDraw();
	ctx->mRT->SetTransform(D2D1::IdentityMatrix());
	ctx->mDrawing = true;
    }
}

    void
DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect)
{
    if (ctx != NULL && ctx->mRT != NULL)
    {
	ctx->mRT->BindDC(hdc, rect);
	ctx->mRT->SetTextAntialiasMode(ctx->mTextAntialiasMode);
    }
}

    void
DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont)
{
    if (ctx != NULL)
    {
	ctx->SetFont(hFont);
    }
}

    void
DWriteContext_DrawText(
	DWriteContext *ctx,
	HDC hdc,
	const WCHAR* text,
	int len,
	int x,
	int y,
	int w,
	int h,
	int cellWidth,
	COLORREF color)
{
    if (ctx != NULL)
	ctx->DrawText(hdc, text, len, x, y, w, h, cellWidth, color);
}

    void
DWriteContext_EndDraw(DWriteContext *ctx)
{
    if (ctx != NULL && ctx->mRT != NULL)
    {
	ctx->mRT->EndDraw();
	ctx->mDrawing = false;
    }
}

    void
DWriteContext_Close(DWriteContext *ctx)
{
    delete ctx;
}

    void
DWriteContext_SetRenderingParams(
	DWriteContext *ctx,
	const DWriteRenderingParams *params)
{
    if (ctx != NULL)
	ctx->SetRenderingParams(params);
}

    DWriteRenderingParams *
DWriteContext_GetRenderingParams(
	DWriteContext *ctx,
	DWriteRenderingParams *params)
{
    if (ctx != NULL)
	return ctx->GetRenderingParams(params);
    else
	return NULL;
}
