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.