diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp
new file mode 100644
index 0000000..cf83c05
--- /dev/null
+++ b/src/gui_dwrite.cpp
@@ -0,0 +1,901 @@
+/* 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:
+    unsigned 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, 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;
+}
