diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp
index 9873c67..bd76383 100644
--- a/src/gui_dwrite.cpp
+++ b/src/gui_dwrite.cpp
@@ -4,6 +4,7 @@
  *
  * Contributors:
  *  - Ken Takata
+ *  - Yasuhiro Matsumoto
  *
  * Copyright (C) 2013 MURAOKA Taro <koron.kaoriya@gmail.com>
  * THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
@@ -23,7 +24,21 @@
 #include <math.h>
 #include <d2d1.h>
 #include <d2d1helper.h>
-#include <dwrite.h>
+
+// Disable these macros to compile with old VC and newer SDK (V8.1 or later).
+#if defined(_MSC_VER) && (_MSC_VER < 1700)
+# define _COM_Outptr_ __out
+# define _In_reads_(s)
+# define _In_reads_opt_(s)
+# define _Maybenull_
+# define _Out_writes_(s)
+# define _Out_writes_opt_(s)
+# define _Out_writes_to_(x, y)
+# define _Out_writes_to_opt_(x, y)
+# define _Outptr_
+#endif
+
+#include <dwrite_2.h>
 
 #include "gui_dwrite.h"
 
@@ -79,16 +94,6 @@
     }
 }
 
-struct GdiTextRendererContext
-{
-    // const fields.
-    COLORREF color;
-    FLOAT cellWidth;
-
-    // working fields.
-    FLOAT offsetX;
-};
-
     static DWRITE_PIXEL_GEOMETRY
 ToPixelGeometry(int value)
 {
@@ -184,17 +189,151 @@
     }
 }
 
+class FontCache {
+public:
+    struct Item {
+	HFONT              hFont;
+	IDWriteTextFormat* pTextFormat;
+	DWRITE_FONT_WEIGHT fontWeight;
+	DWRITE_FONT_STYLE  fontStyle;
+	Item() : hFont(NULL), pTextFormat(NULL) {}
+    };
+
+private:
+    int mSize;
+    Item *mItems;
+
+public:
+    FontCache(int size = 2) :
+	mSize(size),
+	mItems(new Item[size])
+    {
+    }
+
+    ~FontCache()
+    {
+	for (int i = 0; i < mSize; ++i)
+	    SafeRelease(&mItems[i].pTextFormat);
+	delete[] mItems;
+    }
+
+    bool get(HFONT hFont, Item &item)
+    {
+	int n = find(hFont);
+	if (n < 0)
+	    return false;
+	item = mItems[n];
+	slide(n);
+	return true;
+    }
+
+    void put(const Item& item)
+    {
+	int n = find(item.hFont);
+	if (n < 0)
+	    n = mSize - 1;
+	if (mItems[n].pTextFormat != item.pTextFormat)
+	{
+	    SafeRelease(&mItems[n].pTextFormat);
+	    item.pTextFormat->AddRef();
+	}
+	mItems[n] = item;
+	slide(n);
+    }
+
+private:
+    int find(HFONT hFont)
+    {
+	for (int i = 0; i < mSize; ++i)
+	{
+	    if (mItems[i].hFont == hFont)
+		return i;
+	}
+	return -1;
+    }
+
+    void slide(int nextTop)
+    {
+	if (nextTop == 0)
+	    return;
+	Item tmp = mItems[nextTop];
+	for (int i = nextTop - 1; i >= 0; --i)
+	    mItems[i + 1] = mItems[i];
+	mItems[0] = tmp;
+    }
+};
+
+struct DWriteContext {
+    HDC mHDC;
+    bool mDrawing;
+    bool mFallbackDC;
+
+    ID2D1Factory *mD2D1Factory;
+
+    ID2D1DCRenderTarget *mRT;
+    ID2D1SolidColorBrush *mBrush;
+
+    IDWriteFactory *mDWriteFactory;
+    IDWriteFactory2 *mDWriteFactory2;
+
+    IDWriteGdiInterop *mGdiInterop;
+    IDWriteRenderingParams *mRenderingParams;
+
+    FontCache mFontCache;
+    IDWriteTextFormat *mTextFormat;
+    DWRITE_FONT_WEIGHT mFontWeight;
+    DWRITE_FONT_STYLE mFontStyle;
+
+    D2D1_TEXT_ANTIALIAS_MODE mTextAntialiasMode;
+
+    // METHODS
+
+    DWriteContext();
+
+    virtual ~DWriteContext();
+
+    HRESULT CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
+	    IDWriteTextFormat **ppTextFormat);
+
+    HRESULT SetFontByLOGFONT(const LOGFONTW &logFont);
+
+    void SetFont(HFONT hFont);
+
+    void BindDC(HDC hdc, RECT *rect);
+
+    void AssureDrawing();
+
+    ID2D1Brush* SolidBrush(COLORREF color);
+
+    void DrawText(const WCHAR* text, int len,
+	int x, int y, int w, int h, int cellWidth, COLORREF color,
+	UINT fuOptions, CONST RECT *lprc, CONST INT * lpDx);
+
+    void FillRect(RECT *rc, COLORREF color);
+
+    void Flush();
+
+    void SetRenderingParams(
+	    const DWriteRenderingParams *params);
+
+    DWriteRenderingParams *GetRenderingParams(
+	    DWriteRenderingParams *params);
+};
+
 class AdjustedGlyphRun : public DWRITE_GLYPH_RUN
 {
 private:
+    FLOAT &mAccum;
     FLOAT mDelta;
     FLOAT *mAdjustedAdvances;
 
 public:
     AdjustedGlyphRun(
 	    const DWRITE_GLYPH_RUN *glyphRun,
-	    FLOAT cellWidth) :
+	    FLOAT cellWidth,
+	    FLOAT &accum) :
 	DWRITE_GLYPH_RUN(*glyphRun),
+	mAccum(accum),
 	mDelta(0.0f),
 	mAdjustedAdvances(new FLOAT[glyphRun->glyphCount])
     {
@@ -209,45 +348,44 @@
 	glyphAdvances = mAdjustedAdvances;
     }
 
-    ~AdjustedGlyphRun(void)
+    ~AdjustedGlyphRun()
     {
+	mAccum += mDelta;
 	delete[] mAdjustedAdvances;
     }
 
-    FLOAT getDelta(void) const
-    {
-	return mDelta;
-    }
-
     static FLOAT adjustToCell(FLOAT value, FLOAT cellWidth)
     {
-	int cellCount = (int)floor(value / cellWidth + 0.5f);
+	int cellCount = int(floor(value / cellWidth + 0.5f));
 	if (cellCount < 1)
 	    cellCount = 1;
 	return cellCount * cellWidth;
     }
 };
 
-class GdiTextRenderer FINAL : public IDWriteTextRenderer
+struct TextRendererContext {
+    // const fields.
+    COLORREF color;
+    FLOAT cellWidth;
+
+    // working fields.
+    FLOAT offsetX;
+};
+
+class TextRenderer FINAL : public IDWriteTextRenderer
 {
 public:
-    GdiTextRenderer(
-	    IDWriteBitmapRenderTarget* bitmapRenderTarget,
-	    IDWriteRenderingParams* renderingParams) :
+    TextRenderer(
+	    DWriteContext* pDWC) :
 	cRefCount_(0),
-	pRenderTarget_(bitmapRenderTarget),
-	pRenderingParams_(renderingParams)
+	pDWC_(pDWC)
     {
-	pRenderTarget_->AddRef();
-	pRenderingParams_->AddRef();
 	AddRef();
     }
 
     // add "virtual" to avoid a compiler warning
-    virtual ~GdiTextRenderer()
+    virtual ~TextRenderer()
     {
-	SafeRelease(&pRenderTarget_);
-	SafeRelease(&pRenderingParams_);
     }
 
     IFACEMETHOD(IsPixelSnappingDisabled)(
@@ -263,7 +401,8 @@
 	__out DWRITE_MATRIX* transform)
     {
 	// forward the render target's transform
-	pRenderTarget_->GetCurrentTransform(transform);
+	pDWC_->mRT->GetTransform(
+		reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform));
 	return S_OK;
     }
 
@@ -271,43 +410,12 @@
 	__maybenull void* clientDrawingContext,
 	__out FLOAT* pixelsPerDip)
     {
-	*pixelsPerDip = pRenderTarget_->GetPixelsPerDip();
+	float dpiX, unused;
+	pDWC_->mRT->GetDpi(&dpiX, &unused);
+	*pixelsPerDip = dpiX / 96.0f;
 	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,
@@ -340,6 +448,69 @@
 	return E_NOTIMPL;
     }
 
+    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)
+    {
+	TextRendererContext *context =
+	    reinterpret_cast<TextRendererContext*>(clientDrawingContext);
+
+	AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth,
+		context->offsetX);
+
+	if (pDWC_->mDWriteFactory2 != NULL)
+	{
+	    IDWriteColorGlyphRunEnumerator *enumerator = NULL;
+	    HRESULT hr = pDWC_->mDWriteFactory2->TranslateColorGlyphRun(
+		baselineOriginX + context->offsetX,
+		baselineOriginY,
+		&adjustedGlyphRun,
+		NULL,
+		DWRITE_MEASURING_MODE_GDI_NATURAL,
+		NULL,
+		0,
+		&enumerator);
+	    if (SUCCEEDED(hr))
+	    {
+		// Draw by IDWriteFactory2 for color emoji
+		BOOL hasRun = TRUE;
+		enumerator->MoveNext(&hasRun);
+		while (hasRun)
+		{
+		    const DWRITE_COLOR_GLYPH_RUN* colorGlyphRun;
+		    enumerator->GetCurrentRun(&colorGlyphRun);
+
+		    pDWC_->mBrush->SetColor(colorGlyphRun->runColor);
+		    pDWC_->mRT->DrawGlyphRun(
+			    D2D1::Point2F(
+				colorGlyphRun->baselineOriginX,
+				colorGlyphRun->baselineOriginY),
+			    &colorGlyphRun->glyphRun,
+			    pDWC_->mBrush,
+			    DWRITE_MEASURING_MODE_NATURAL);
+		    enumerator->MoveNext(&hasRun);
+		}
+		SafeRelease(&enumerator);
+		return S_OK;
+	    }
+	}
+
+	// Draw by IDWriteFactory (without color emoji)
+	pDWC_->mRT->DrawGlyphRun(
+		D2D1::Point2F(
+		    baselineOriginX + context->offsetX,
+		    baselineOriginY),
+		&adjustedGlyphRun,
+		pDWC_->SolidBrush(context->color),
+		DWRITE_MEASURING_MODE_NATURAL);
+	return S_OK;
+    }
+
 public:
     IFACEMETHOD_(unsigned long, AddRef) ()
     {
@@ -385,80 +556,28 @@
 
 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* pDWC_;
 };
 
 DWriteContext::DWriteContext() :
-    mDpiScaleX(1.f),
-    mDpiScaleY(1.f),
+    mHDC(NULL),
     mDrawing(false),
+    mFallbackDC(false),
     mD2D1Factory(NULL),
     mRT(NULL),
     mBrush(NULL),
     mDWriteFactory(NULL),
+    mDWriteFactory2(NULL),
     mGdiInterop(NULL),
     mRenderingParams(NULL),
+    mFontCache(8),
     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));
@@ -497,6 +616,15 @@
 
     if (SUCCEEDED(hr))
     {
+	DWriteCreateFactory(
+		DWRITE_FACTORY_TYPE_SHARED,
+		__uuidof(IDWriteFactory2),
+		reinterpret_cast<IUnknown**>(&mDWriteFactory2));
+	_RPT1(_CRT_WARN, "IDWriteFactory2: %s\n", SUCCEEDED(hr) ? "available" : "not available");
+    }
+
+    if (SUCCEEDED(hr))
+    {
 	hr = mDWriteFactory->GetGdiInterop(&mGdiInterop);
 	_RPT2(_CRT_WARN, "GetGdiInterop: hr=%p p=%p\n", hr, mGdiInterop);
     }
@@ -515,20 +643,24 @@
     SafeRelease(&mRenderingParams);
     SafeRelease(&mGdiInterop);
     SafeRelease(&mDWriteFactory);
+    SafeRelease(&mDWriteFactory2);
     SafeRelease(&mBrush);
     SafeRelease(&mRT);
     SafeRelease(&mD2D1Factory);
 }
 
     HRESULT
-DWriteContext::SetLOGFONT(const LOGFONTW &logFont, float fontSize)
+DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
+	IDWriteTextFormat **ppTextFormat)
 {
-    // Most of this function is copy from: http://msdn.microsoft.com/en-us/library/windows/desktop/dd941783(v=vs.85).aspx
+    // Most of this function is copied from: https://github.com/Microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/DirectWrite/RenderTest/TextHelpers.cpp
     HRESULT hr = S_OK;
+    IDWriteTextFormat *pTextFormat = NULL;
 
     IDWriteFont *font = NULL;
     IDWriteFontFamily *fontFamily = NULL;
     IDWriteLocalizedStrings *localizedFamilyNames = NULL;
+    float fontSize = 0;
 
     if (SUCCEEDED(hr))
     {
@@ -561,33 +693,30 @@
 
     if (SUCCEEDED(hr))
     {
-	// If no font size was passed in use the lfHeight of the LOGFONT.
-	if (fontSize == 0)
+	// Use lfHeight of the LOGFONT as font size.
+	fontSize = float(logFont.lfHeight);
+
+	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);
+	    // 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;
+	    // 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;
-	    }
+	    // Divide the font size by the cell height to get the font em
+	    // size.
+	    fontSize /= cellHeight;
 	}
     }
 
@@ -612,123 +741,165 @@
 		font->GetStretch(),
 		fontSize,
 		localeName,
-		&mTextFormat);
+		&pTextFormat);
     }
 
     if (SUCCEEDED(hr))
-    {
-	mFontWeight = static_cast<DWRITE_FONT_WEIGHT>(logFont.lfWeight);
-	mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC
-	    : DWRITE_FONT_STYLE_NORMAL;
-    }
+	hr = pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING);
+
+    if (SUCCEEDED(hr))
+	hr = pTextFormat->SetParagraphAlignment(
+		DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
+
+    if (SUCCEEDED(hr))
+	hr = pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
 
     SafeRelease(&localizedFamilyNames);
     SafeRelease(&fontFamily);
     SafeRelease(&font);
 
+    if (SUCCEEDED(hr))
+	*ppTextFormat = pTextFormat;
+    else
+	SafeRelease(&pTextFormat);
+
+    return hr;
+}
+
+    HRESULT
+DWriteContext::SetFontByLOGFONT(const LOGFONTW &logFont)
+{
+    HRESULT hr = S_OK;
+    IDWriteTextFormat *pTextFormat = NULL;
+
+    hr = CreateTextFormatFromLOGFONT(logFont, &pTextFormat);
+
+    if (SUCCEEDED(hr))
+    {
+	SafeRelease(&mTextFormat);
+	mTextFormat = pTextFormat;
+	mFontWeight = static_cast<DWRITE_FONT_WEIGHT>(logFont.lfWeight);
+	mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC
+	    : DWRITE_FONT_STYLE_NORMAL;
+    }
+
     return hr;
 }
 
     void
 DWriteContext::SetFont(HFONT hFont)
 {
-    if (mLastHFont != hFont)
+    FontCache::Item item;
+    if (mFontCache.get(hFont, item))
     {
-	LOGFONTW lf;
-	if (GetObjectW(hFont, sizeof(lf), &lf))
+	if (item.pTextFormat != NULL)
 	{
-	    SetFont(lf);
-	    mLastHFont = hFont;
+	    item.pTextFormat->AddRef();
+	    SafeRelease(&mTextFormat);
+	    mTextFormat = item.pTextFormat;
+	    mFontWeight = item.fontWeight;
+	    mFontStyle = item.fontStyle;
+	    mFallbackDC = false;
 	}
+	else
+	    mFallbackDC = true;
+	return;
     }
+
+    HRESULT hr = E_FAIL;
+    LOGFONTW lf;
+    if (GetObjectW(hFont, sizeof(lf), &lf))
+	hr = SetFontByLOGFONT(lf);
+
+    item.hFont = hFont;
+    if (SUCCEEDED(hr))
+    {
+	item.pTextFormat = mTextFormat;
+	item.fontWeight = mFontWeight;
+	item.fontStyle = mFontStyle;
+    }
+    mFontCache.put(item);
 }
 
     void
-DWriteContext::SetFont(const LOGFONTW &logFont)
+DWriteContext::BindDC(HDC hdc, RECT *rect)
 {
-    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);
+    Flush();
+    mRT->BindDC(hdc, rect);
+    mRT->SetTransform(D2D1::IdentityMatrix());
+    mHDC = hdc;
 }
 
     void
-DWriteContext::DrawText(HDC hdc, const WCHAR* text, int len,
-	int x, int y, int w, int h, int cellWidth, COLORREF color)
+DWriteContext::AssureDrawing()
 {
-    HRESULT hr = S_OK;
-    IDWriteBitmapRenderTarget *bmpRT = NULL;
+    if (mDrawing == false)
+    {
+	mRT->BeginDraw();
+	mDrawing = true;
+    }
+}
 
-    // Skip when any fonts are not set.
-    if (mTextFormat == NULL)
+    ID2D1Brush*
+DWriteContext::SolidBrush(COLORREF color)
+{
+    mBrush->SetColor(D2D1::ColorF(UINT32(GetRValue(color)) << 16 |
+		UINT32(GetGValue(color)) << 8 | UINT32(GetBValue(color))));
+    return mBrush;
+}
+
+    void
+DWriteContext::DrawText(const WCHAR* text, int len,
+	int x, int y, int w, int h, int cellWidth, COLORREF color,
+	UINT fuOptions, CONST RECT *lprc, CONST INT * lpDx)
+{
+    if (mFallbackDC)
+    {
+	Flush();
+	ExtTextOutW(mHDC, x, y, fuOptions, lprc, text, len, lpDx);
 	return;
+    }
 
-    // Check possibility of zero divided error.
-    if (cellWidth == 0 || mDpiScaleX == 0.0f || mDpiScaleY == 0.0f)
-	return;
+    AssureDrawing();
 
-    if (SUCCEEDED(hr))
-	hr = mGdiInterop->CreateBitmapRenderTarget(hdc, w, h, &bmpRT);
+    HRESULT hr;
+    IDWriteTextLayout *textLayout = NULL;
+
+    hr = mDWriteFactory->CreateTextLayout(text, len, mTextFormat,
+	    FLOAT(w), FLOAT(h), &textLayout);
 
     if (SUCCEEDED(hr))
     {
-	IDWriteTextLayout *textLayout = NULL;
+	DWRITE_TEXT_RANGE textRange = { 0, UINT32(len) };
+	textLayout->SetFontWeight(mFontWeight, textRange);
+	textLayout->SetFontStyle(mFontStyle, textRange);
 
-	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);
+	TextRenderer renderer(this);
+	TextRendererContext context = { color, FLOAT(cellWidth), 0.0f };
+	textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y));
     }
 
-    SafeRelease(&bmpRT);
+    SafeRelease(&textLayout);
 }
 
-    float
-DWriteContext::PixelsToDipsX(int x)
+    void
+DWriteContext::FillRect(RECT *rc, COLORREF color)
 {
-    return x / mDpiScaleX;
+    AssureDrawing();
+    mRT->FillRectangle(
+	    D2D1::RectF(FLOAT(rc->left), FLOAT(rc->top),
+		FLOAT(rc->right), FLOAT(rc->bottom)),
+	    SolidBrush(color));
 }
 
-    float
-DWriteContext::PixelsToDipsY(int y)
+    void
+DWriteContext::Flush()
 {
-    return y / mDpiScaleY;
+    if (mDrawing)
+    {
+	mRT->EndDraw();
+	mDrawing = false;
+    }
 }
 
     void
@@ -757,6 +928,10 @@
 	SafeRelease(&mRenderingParams);
 	mRenderingParams = renderingParams;
 	mTextAntialiasMode = textAntialiasMode;
+
+	Flush();
+	mRT->SetTextRenderingParams(mRenderingParams);
+	mRT->SetTextAntialiasMode(mTextAntialiasMode);
     }
 }
 
@@ -825,39 +1000,22 @@
 }
 
     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);
-    }
+    if (ctx != NULL)
+	ctx->BindDC(hdc, rect);
 }
 
     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,
@@ -865,20 +1023,28 @@
 	int w,
 	int h,
 	int cellWidth,
-	COLORREF color)
+	COLORREF color,
+	UINT fuOptions,
+	CONST RECT *lprc,
+	CONST INT * lpDx)
 {
     if (ctx != NULL)
-	ctx->DrawText(hdc, text, len, x, y, w, h, cellWidth, color);
+	ctx->DrawText(text, len, x, y, w, h, cellWidth, color,
+		fuOptions, lprc, lpDx);
 }
 
     void
-DWriteContext_EndDraw(DWriteContext *ctx)
+DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color)
 {
-    if (ctx != NULL && ctx->mRT != NULL)
-    {
-	ctx->mRT->EndDraw();
-	ctx->mDrawing = false;
-    }
+    if (ctx != NULL)
+	ctx->FillRect(rc, color);
+}
+
+    void
+DWriteContext_Flush(DWriteContext *ctx)
+{
+    if (ctx != NULL)
+	ctx->Flush();
 }
 
     void
