Patch 8.0.1343
Problem:    MS-Windows: does not show colored emojis.
Solution:   Implement colored emojis. Improve drawing speed. Make 'taamode'
            work. (Taro Muraoka, Yasuhiro Matsumoto, Ken Takata, close #2375)
Files:      appveyor.yml, runtime/doc/options.txt, src/gui_dwrite.cpp,
            src/gui_dwrite.h, src/gui_w32.c, src/proto/gui_w32.pro


*** ../vim-8.0.1342/appveyor.yml        2016-09-25 20:21:58.333062395 +0200
--- appveyor.yml        2017-11-26 14:22:54.513534386 +0100
***************
*** 16,21 ****
--- 16,22 ----
  
  before_build:
    - '"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 
/release'
+   - 'set INCLUDE=%INCLUDE%C:\Program Files (x86)\Windows Kits\8.1\Include\um'
  
  build_script:
    - src/appveyor.bat
*** ../vim-8.0.1342/runtime/doc/options.txt     2017-11-25 17:58:23.622091808 
+0100
--- runtime/doc/options.txt     2017-11-26 14:22:54.517534364 +0100
***************
*** 6049,6059 ****
  
                Example: >
                  set encoding=utf-8
!                 set gfn=Ricty_Diminished:h12:cSHIFTJIS
                  set rop=type:directx
  <
!               If select a raster font (Courier, Terminal or FixedSys) to
!               'guifont', it fallbacks to be drawn by GDI automatically.
  
        Other render types are currently not supported.
  
--- 6154,6187 ----
  
                Example: >
                  set encoding=utf-8
!                 set gfn=Ricty_Diminished:h12
                  set rop=type:directx
  <
!               If select a raster font (Courier, Terminal or FixedSys which
!               have ".fon" extension in file name) to 'guifont', it will be
!               drawn by GDI as a fallback.  This fallback will cause
!               significant slow down on drawing.
! 
!               NOTE: It is known that some fonts and options combination
!               causes trouble on drawing glyphs.
! 
!                 - 'rendmode:5' and 'renmode:6' will not work with some
!                   special made fonts (True-Type fonts which includes only
!                   bitmap glyphs).
!                 - 'taamode:3' will not work with some vector fonts.
! 
!               NOTE: With this option, you can display colored emoji
!               (emoticon) in Windows 8.1 or later.  To display colored emoji,
!               there are some conditions which you should notice.
! 
!                 - If your font includes non-colored emoji already, it will
!                   be used.
!                 - If your font doesn't have emoji, the system chooses an
!                   alternative symbol font.  On Windows 10, "Segoe UI Emoji"
!                   will be used.
!                 - When this alternative font didn't have fixed width glyph,
!                   emoji might be rendered beyond the bounding box of drawing
!                   cell.
  
        Other render types are currently not supported.
  
*** ../vim-8.0.1342/src/gui_dwrite.cpp  2016-03-19 20:48:11.000000000 +0100
--- src/gui_dwrite.cpp  2017-11-26 14:22:54.517534364 +0100
***************
*** 4,9 ****
--- 4,10 ----
   *
   * Contributors:
   *  - Ken Takata
+  *  - Yasuhiro Matsumoto
   *
   * Copyright (C) 2013 MURAOKA Taro <[email protected]>
   * THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
***************
*** 23,29 ****
  #include <math.h>
  #include <d2d1.h>
  #include <d2d1helper.h>
! #include <dwrite.h>
  
  #include "gui_dwrite.h"
  
--- 24,44 ----
  #include <math.h>
  #include <d2d1.h>
  #include <d2d1helper.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,94 ****
      }
  }
  
- struct GdiTextRendererContext
- {
-     // const fields.
-     COLORREF color;
-     FLOAT cellWidth;
- 
-     // working fields.
-     FLOAT offsetX;
- };
- 
      static DWRITE_PIXEL_GEOMETRY
  ToPixelGeometry(int value)
  {
--- 94,99 ----
***************
*** 184,200 ****
      }
  }
  
  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])
      {
--- 189,339 ----
      }
  }
  
+ 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 &accum) :
        DWRITE_GLYPH_RUN(*glyphRun),
+       mAccum(accum),
        mDelta(0.0f),
        mAdjustedAdvances(new FLOAT[glyphRun->glyphCount])
      {
***************
*** 209,253 ****
        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 FINAL : public IDWriteTextRenderer
  {
  public:
!     GdiTextRenderer(
!           IDWriteBitmapRenderTarget* bitmapRenderTarget,
!           IDWriteRenderingParams* renderingParams) :
        cRefCount_(0),
!       pRenderTarget_(bitmapRenderTarget),
!       pRenderingParams_(renderingParams)
      {
-       pRenderTarget_->AddRef();
-       pRenderingParams_->AddRef();
        AddRef();
      }
  
      // add "virtual" to avoid a compiler warning
!     virtual ~GdiTextRenderer()
      {
-       SafeRelease(&pRenderTarget_);
-       SafeRelease(&pRenderingParams_);
      }
  
      IFACEMETHOD(IsPixelSnappingDisabled)(
--- 348,391 ----
        glyphAdvances = mAdjustedAdvances;
      }
  
!     ~AdjustedGlyphRun()
      {
+       mAccum += mDelta;
        delete[] mAdjustedAdvances;
      }
  
      static FLOAT adjustToCell(FLOAT value, FLOAT cellWidth)
      {
!       int cellCount = int(floor(value / cellWidth + 0.5f));
        if (cellCount < 1)
            cellCount = 1;
        return cellCount * cellWidth;
      }
  };
  
! struct TextRendererContext {
!     // const fields.
!     COLORREF color;
!     FLOAT cellWidth;
! 
!     // working fields.
!     FLOAT offsetX;
! };
! 
! class TextRenderer FINAL : public IDWriteTextRenderer
  {
  public:
!     TextRenderer(
!           DWriteContext* pDWC) :
        cRefCount_(0),
!       pDWC_(pDWC)
      {
        AddRef();
      }
  
      // add "virtual" to avoid a compiler warning
!     virtual ~TextRenderer()
      {
      }
  
      IFACEMETHOD(IsPixelSnappingDisabled)(
***************
*** 263,269 ****
        __out DWRITE_MATRIX* transform)
      {
        // forward the render target's transform
!       pRenderTarget_->GetCurrentTransform(transform);
        return S_OK;
      }
  
--- 401,408 ----
        __out DWRITE_MATRIX* transform)
      {
        // forward the render target's transform
!       pDWC_->mRT->GetTransform(
!               reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform));
        return S_OK;
      }
  
***************
*** 271,313 ****
        __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,
--- 410,421 ----
        __maybenull void* clientDrawingContext,
        __out FLOAT* pixelsPerDip)
      {
!       float dpiX, unused;
!       pDWC_->mRT->GetDpi(&dpiX, &unused);
!       *pixelsPerDip = dpiX / 96.0f;
        return S_OK;
      }
  
      IFACEMETHOD(DrawUnderline)(
        __maybenull void* clientDrawingContext,
        FLOAT baselineOriginX,
***************
*** 340,345 ****
--- 448,516 ----
        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,464 ****
  
  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));
--- 556,583 ----
  
  private:
      long cRefCount_;
!     DWriteContext* pDWC_;
  };
  
  DWriteContext::DWriteContext() :
!     mHDC(NULL),
      mDrawing(false),
+     mFallbackDC(false),
      mD2D1Factory(NULL),
      mRT(NULL),
      mBrush(NULL),
      mDWriteFactory(NULL),
+     mDWriteFactory2(NULL),
      mGdiInterop(NULL),
      mRenderingParams(NULL),
+     mFontCache(8),
      mTextFormat(NULL),
      mFontWeight(DWRITE_FONT_WEIGHT_NORMAL),
      mFontStyle(DWRITE_FONT_STYLE_NORMAL),
      mTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_DEFAULT)
  {
      HRESULT hr;
  
      hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
            __uuidof(ID2D1Factory), NULL,
            reinterpret_cast<void**>(&mD2D1Factory));
***************
*** 497,502 ****
--- 616,630 ----
  
      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,534 ****
      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))
      {
--- 643,666 ----
      SafeRelease(&mRenderingParams);
      SafeRelease(&mGdiInterop);
      SafeRelease(&mDWriteFactory);
+     SafeRelease(&mDWriteFactory2);
      SafeRelease(&mBrush);
      SafeRelease(&mRT);
      SafeRelease(&mD2D1Factory);
  }
  
      HRESULT
! DWriteContext::CreateTextFormatFromLOGFONT(const LOGFONTW &logFont,
!       IDWriteTextFormat **ppTextFormat)
  {
!     // 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,593 ****
  
      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;
!           }
        }
      }
  
--- 693,722 ----
  
      if (SUCCEEDED(hr))
      {
!       // Use lfHeight of the LOGFONT as font size.
!       fontSize = float(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;
        }
      }
  
***************
*** 612,734 ****
                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
--- 741,905 ----
                font->GetStretch(),
                fontSize,
                localeName,
!               &pTextFormat);
      }
  
      if (SUCCEEDED(hr))
+       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)
  {
!     FontCache::Item item;
!     if (mFontCache.get(hFont, item))
      {
!       if (item.pTextFormat != NULL)
        {
!           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::BindDC(HDC hdc, RECT *rect)
  {
!     Flush();
!     mRT->BindDC(hdc, rect);
!     mRT->SetTransform(D2D1::IdentityMatrix());
!     mHDC = hdc;
! }
  
!     void
! DWriteContext::AssureDrawing()
! {
!     if (mDrawing == false)
!     {
!       mRT->BeginDraw();
!       mDrawing = true;
!     }
! }
  
!     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;
+     }
  
!     AssureDrawing();
  
!     HRESULT hr;
!     IDWriteTextLayout *textLayout = NULL;
! 
!     hr = mDWriteFactory->CreateTextLayout(text, len, mTextFormat,
!           FLOAT(w), FLOAT(h), &textLayout);
  
      if (SUCCEEDED(hr))
      {
!       DWRITE_TEXT_RANGE textRange = { 0, UINT32(len) };
!       textLayout->SetFontWeight(mFontWeight, textRange);
!       textLayout->SetFontStyle(mFontStyle, textRange);
  
!       TextRenderer renderer(this);
!       TextRendererContext context = { color, FLOAT(cellWidth), 0.0f };
!       textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y));
      }
  
!     SafeRelease(&textLayout);
  }
  
!     void
! DWriteContext::FillRect(RECT *rc, COLORREF color)
  {
!     AssureDrawing();
!     mRT->FillRectangle(
!           D2D1::RectF(FLOAT(rc->left), FLOAT(rc->top),
!               FLOAT(rc->right), FLOAT(rc->bottom)),
!           SolidBrush(color));
  }
  
!     void
! DWriteContext::Flush()
  {
!     if (mDrawing)
!     {
!       mRT->EndDraw();
!       mDrawing = false;
!     }
  }
  
      void
***************
*** 757,762 ****
--- 928,937 ----
        SafeRelease(&mRenderingParams);
        mRenderingParams = renderingParams;
        mTextAntialiasMode = textAntialiasMode;
+ 
+       Flush();
+       mRT->SetTextRenderingParams(mRenderingParams);
+       mRT->SetTextAntialiasMode(mTextAntialiasMode);
      }
  }
  
***************
*** 825,863 ****
  }
  
      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,
--- 1000,1021 ----
  }
  
      void
  DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect)
  {
!     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,
        const WCHAR* text,
        int len,
        int x,
***************
*** 865,884 ****
        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
--- 1023,1050 ----
        int w,
        int h,
        int cellWidth,
!       COLORREF color,
!       UINT fuOptions,
!       CONST RECT *lprc,
!       CONST INT * lpDx)
  {
      if (ctx != NULL)
!       ctx->DrawText(text, len, x, y, w, h, cellWidth, color,
!               fuOptions, lprc, lpDx);
  }
  
      void
! DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color)
  {
!     if (ctx != NULL)
!       ctx->FillRect(rc, color);
! }
! 
!     void
! DWriteContext_Flush(DWriteContext *ctx)
! {
!     if (ctx != NULL)
!       ctx->Flush();
  }
  
      void
*** ../vim-8.0.1342/src/gui_dwrite.h    2014-08-06 14:21:57.000000000 +0200
--- src/gui_dwrite.h    2017-11-26 14:22:54.517534364 +0100
***************
*** 4,9 ****
--- 4,10 ----
   *
   * Contributors:
   *  - Ken Takata
+  *  - Yasuhiro Matsumoto
   *
   * Copyright (C) 2013 MURAOKA Taro <[email protected]>
   * THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
***************
*** 54,65 ****
  void DWrite_Final(void);
  
  DWriteContext *DWriteContext_Open(void);
- void DWriteContext_BeginDraw(DWriteContext *ctx);
  void DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect);
  void DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont);
  void DWriteContext_DrawText(
        DWriteContext *ctx,
-       HDC hdc,
        const WCHAR* text,
        int len,
        int x,
--- 55,64 ----
***************
*** 67,74 ****
        int w,
        int h,
        int cellWidth,
!       COLORREF color);
! void DWriteContext_EndDraw(DWriteContext *ctx);
  void DWriteContext_Close(DWriteContext *ctx);
  
  void DWriteContext_SetRenderingParams(
--- 66,77 ----
        int w,
        int h,
        int cellWidth,
!       COLORREF color,
!       UINT fuOptions,
!       CONST RECT *lprc,
!       CONST INT * lpDx);
! void DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color);
! void DWriteContext_Flush(DWriteContext *ctx);
  void DWriteContext_Close(DWriteContext *ctx);
  
  void DWriteContext_SetRenderingParams(
*** ../vim-8.0.1342/src/gui_w32.c       2017-11-25 17:14:29.604189538 +0100
--- src/gui_w32.c       2017-11-26 14:22:54.521534341 +0100
***************
*** 34,61 ****
  static int s_directx_enabled = 0;
  static int s_directx_load_attempted = 0;
  # define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL)
  #endif
  
  #ifdef FEAT_MENU
  static int gui_mswin_get_menu_height(int fix_window);
  #endif
  
- #if defined(FEAT_DIRECTX) || defined(PROTO)
-     int
- directx_enabled(void)
- {
-     if (s_dwc != NULL)
-       return 1;
-     else if (s_directx_load_attempted)
-       return 0;
-     /* load DirectX */
-     DWrite_Init();
-     s_directx_load_attempted = 1;
-     s_dwc = DWriteContext_Open();
-     return s_dwc != NULL ? 1 : 0;
- }
- #endif
- 
  #if defined(FEAT_RENDER_OPTIONS) || defined(PROTO)
      int
  gui_mch_set_rendering_options(char_u *s)
--- 34,47 ----
  static int s_directx_enabled = 0;
  static int s_directx_load_attempted = 0;
  # define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL)
+ static int directx_enabled(void);
+ static void directx_binddc(void);
  #endif
  
  #ifdef FEAT_MENU
  static int gui_mswin_get_menu_height(int fix_window);
  #endif
  
  #if defined(FEAT_RENDER_OPTIONS) || defined(PROTO)
      int
  gui_mch_set_rendering_options(char_u *s)
***************
*** 369,374 ****
--- 355,388 ----
  # define MyTranslateMessage(x) TranslateMessage(x)
  #endif
  
+ #if defined(FEAT_DIRECTX)
+     static int
+ directx_enabled(void)
+ {
+     if (s_dwc != NULL)
+       return 1;
+     else if (s_directx_load_attempted)
+       return 0;
+     /* load DirectX */
+     DWrite_Init();
+     s_directx_load_attempted = 1;
+     s_dwc = DWriteContext_Open();
+     directx_binddc();
+     return s_dwc != NULL ? 1 : 0;
+ }
+ 
+     static void
+ directx_binddc(void)
+ {
+     if (s_textArea != NULL)
+     {
+       RECT    rect;
+       GetClientRect(s_textArea, &rect);
+       DWriteContext_BindDC(s_dwc, s_hdc, &rect);
+     }
+ }
+ #endif
+ 
  #if defined(FEAT_MBYTE) || defined(GLOBAL_IME)
    /* use of WindowProc depends on wide_WindowProc */
  # define MyWindowProc vim_WindowProc
***************
*** 589,594 ****
--- 603,612 ----
        blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_ontime,
                                                    (TIMERPROC)_OnBlinkTimer);
      }
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
  }
  
      static void
***************
*** 1000,1005 ****
--- 1018,1036 ----
      _OnMouseEvent(button, x, y, FALSE, keyFlags);
  }
  
+     static void
+ _OnSizeTextArea(
+     HWND hwnd UNUSED,
+     UINT state UNUSED,
+     int cx UNUSED,
+     int cy UNUSED)
+ {
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       directx_binddc();
+ #endif
+ }
+ 
  #ifdef FEAT_MENU
  /*
   * Find the vimmenu_T with the given id
***************
*** 1234,1239 ****
--- 1265,1271 ----
        HANDLE_MSG(hwnd, WM_XBUTTONDBLCLK,_OnMouseButtonDown);
        HANDLE_MSG(hwnd, WM_XBUTTONDOWN,_OnMouseButtonDown);
        HANDLE_MSG(hwnd, WM_XBUTTONUP,  _OnMouseMoveOrRelease);
+       HANDLE_MSG(hwnd, WM_SIZE,       _OnSizeTextArea);
  
  #ifdef FEAT_BEVAL_GUI
        case WM_NOTIFY: Handle_WM_Notify(hwnd, (LPNMHDR)lParam);
***************
*** 1633,1638 ****
--- 1665,1675 ----
  {
      RECT    rc;
  
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      /*
       * Note: InvertRect() excludes right and bottom of rectangle.
       */
***************
*** 1661,1666 ****
--- 1698,1708 ----
      HBRUSH  hbr;
      RECT    rc;
  
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      /*
       * Note: FrameRect() excludes right and bottom of rectangle.
       */
***************
*** 1701,1706 ****
--- 1743,1754 ----
      rc.top = FILL_Y(gui.row) + gui.char_height - h;
      rc.right = rc.left + w;
      rc.bottom = rc.top + h;
+ 
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      hbr = CreateSolidBrush(color);
      FillRect(s_hdc, &rc, hbr);
      DeleteBrush(hbr);
***************
*** 2856,2865 ****
  
        out_flush();        /* make sure all output has been processed */
        (void)BeginPaint(hwnd, &ps);
- #if defined(FEAT_DIRECTX)
-       if (IS_ENABLE_DIRECTX())
-           DWriteContext_BeginDraw(s_dwc);
- #endif
  
  #ifdef FEAT_MBYTE
        /* prevent multi-byte characters from misprinting on an invalid
--- 2904,2909 ----
***************
*** 2876,2894 ****
  
        if (!IsRectEmpty(&ps.rcPaint))
        {
- #if defined(FEAT_DIRECTX)
-           if (IS_ENABLE_DIRECTX())
-               DWriteContext_BindDC(s_dwc, s_hdc, &ps.rcPaint);
- #endif
            gui_redraw(ps.rcPaint.left, ps.rcPaint.top,
                    ps.rcPaint.right - ps.rcPaint.left + 1,
                    ps.rcPaint.bottom - ps.rcPaint.top + 1);
        }
  
- #if defined(FEAT_DIRECTX)
-       if (IS_ENABLE_DIRECTX())
-           DWriteContext_EndDraw(s_dwc);
- #endif
        EndPaint(hwnd, &ps);
      }
  }
--- 2920,2930 ----
***************
*** 3010,3015 ****
--- 3046,3056 ----
  {
      RECT    rc;
  
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      /*
       * Note: InvertRect() excludes right and bottom of rectangle.
       */
***************
*** 3082,3087 ****
--- 3123,3134 ----
  
      intel_gpu_workaround();
  
+ #if defined(FEAT_DIRECTX)
+     // Commit drawing queue before ScrollWindowEx.
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      rc.left = FILL_X(gui.scroll_region_left);
      rc.right = FILL_X(gui.scroll_region_right + 1);
      rc.top = FILL_Y(row);
***************
*** 3115,3120 ****
--- 3162,3173 ----
  
      intel_gpu_workaround();
  
+ #if defined(FEAT_DIRECTX)
+     // Commit drawing queue before ScrollWindowEx.
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      rc.left = FILL_X(gui.scroll_region_left);
      rc.right = FILL_X(gui.scroll_region_right + 1);
      rc.top = FILL_Y(row);
***************
*** 6145,6153 ****
  #endif
      HPEN      hpen, old_pen;
      int               y;
- #ifdef FEAT_DIRECTX
-     int               font_is_ttf_or_vector = 0;
- #endif
  
      /*
       * Italic and bold text seems to have an extra row of pixels at the bottom
--- 6198,6203 ----
***************
*** 6208,6213 ****
--- 6258,6268 ----
            hbr = hbr_cache[brush_lru];
            brush_lru = !brush_lru;
        }
+ 
+ #if defined(FEAT_DIRECTX)
+       if (IS_ENABLE_DIRECTX())
+           DWriteContext_FillRect(s_dwc, &rc, gui.currBgColor);
+ #endif
        FillRect(s_hdc, &rc, hbr);
  
        SetBkMode(s_hdc, TRANSPARENT);
***************
*** 6227,6242 ****
  
  #ifdef FEAT_DIRECTX
      if (IS_ENABLE_DIRECTX())
!     {
!       TEXTMETRIC tm;
! 
!       GetTextMetrics(s_hdc, &tm);
!       if (tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR))
!       {
!           font_is_ttf_or_vector = 1;
!           DWriteContext_SetFont(s_dwc, (HFONT)gui.currFont);
!       }
!     }
  #endif
  
      if (pad_size != Columns || padding == NULL || padding[0] != 
gui.char_width)
--- 6282,6288 ----
  
  #ifdef FEAT_DIRECTX
      if (IS_ENABLE_DIRECTX())
!       DWriteContext_SetFont(s_dwc, (HFONT)gui.currFont);
  #endif
  
      if (pad_size != Columns || padding == NULL || padding[0] != 
gui.char_width)
***************
*** 6347,6358 ****
            ++clen;
        }
  #if defined(FEAT_DIRECTX)
!       if (IS_ENABLE_DIRECTX() && font_is_ttf_or_vector)
        {
            /* Add one to "cells" for italics. */
!           DWriteContext_DrawText(s_dwc, s_hdc, unicodebuf, wlen,
                    TEXT_X(col), TEXT_Y(row), FILL_X(cells + 1), FILL_Y(1),
!                   gui.char_width, gui.currFgColor);
        }
        else
  #endif
--- 6393,6405 ----
            ++clen;
        }
  #if defined(FEAT_DIRECTX)
!       if (IS_ENABLE_DIRECTX())
        {
            /* Add one to "cells" for italics. */
!           DWriteContext_DrawText(s_dwc, unicodebuf, wlen,
                    TEXT_X(col), TEXT_Y(row), FILL_X(cells + 1), FILL_Y(1),
!                   gui.char_width, gui.currFgColor,
!                   foptions, pcliprect, unicodepdy);
        }
        else
  #endif
***************
*** 6411,6416 ****
--- 6458,6469 ----
                         foptions, pcliprect, (char *)text, len, padding);
      }
  
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX() &&
+           (flags & (DRAW_UNDERL | DRAW_STRIKE | DRAW_UNDERC | DRAW_CURSOR)))
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      /* Underline */
      if (flags & DRAW_UNDERL)
      {
***************
*** 6473,6478 ****
--- 6526,6536 ----
      BOOL  __stdcall GdiFlush(void);
  #   endif
  
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      GdiFlush();
  }
  
***************
*** 6481,6486 ****
--- 6539,6552 ----
  {
      HBRUSH  hbr;
  
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+     {
+       DWriteContext_FillRect(s_dwc, rcp, gui.back_pixel);
+       return;
+     }
+ #endif
+ 
      hbr = CreateSolidBrush(gui.back_pixel);
      FillRect(s_hdc, rcp, hbr);
      DeleteBrush(hbr);
***************
*** 8386,8391 ****
--- 8452,8462 ----
      if (!gui.in_use || (sign = (signicon_t *)sign_get_image(typenr)) == NULL)
        return;
  
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      x = TEXT_X(col);
      y = TEXT_Y(row);
      w = gui.char_width * 2;
***************
*** 8865,8870 ****
--- 8936,8946 ----
      x = 0;
      y = TEXT_Y(row);
  
+ #if defined(FEAT_DIRECTX)
+     if (IS_ENABLE_DIRECTX())
+       DWriteContext_Flush(s_dwc);
+ #endif
+ 
      for (i = 0; i < gui.char_height - 3; i++)
        SetPixel(s_hdc, x+2, y++, gui.currFgColor);
  
*** ../vim-8.0.1342/src/proto/gui_w32.pro       2017-07-23 16:45:05.673761155 
+0200
--- src/proto/gui_w32.pro       2017-11-26 14:22:54.521534341 +0100
***************
*** 1,5 ****
  /* gui_w32.c */
- int directx_enabled(void);
  int gui_mch_set_rendering_options(char_u *s);
  int gui_mch_is_blinking(void);
  int gui_mch_is_blink_off(void);
--- 1,4 ----
*** ../vim-8.0.1342/src/version.c       2017-11-25 21:07:25.337679963 +0100
--- src/version.c       2017-11-26 14:25:22.756828762 +0100
***************
*** 773,774 ****
--- 773,776 ----
  {   /* Add new patch number below this line */
+ /**/
+     1343,
  /**/

-- 
Everyone has a photographic memory. Some don't have film.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui