Skip to content

Instantly share code, notes, and snippets.

@k-takata
Last active December 11, 2015 05:59
Show Gist options
  • Save k-takata/4556197 to your computer and use it in GitHub Desktop.
Save k-takata/4556197 to your computer and use it in GitHub Desktop.
additional patch No.6 for vim-kaoriya-vim-mq-ex / patch-direct_write.diff (Support for guifontwide.)
diff --git a/src/Make_cyg.mak b/src/Make_cyg.mak
--- a/src/Make_cyg.mak
+++ b/src/Make_cyg.mak
@@ -628,6 +628,9 @@
$(OUTDIR)/gui_dwrite.o: gui_dwrite.cpp $(INCL) gui_dwrite.h
$(CXX) -c $(CFLAGS) gui_dwrite.cpp -o $(OUTDIR)/gui_dwrite.o
+$(OUTDIR)/gui_w32.o: gui_w32.c gui_w48.c $(INCL)
+ $(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o
+
$(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h
$(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o
diff --git a/src/Make_ming.mak b/src/Make_ming.mak
--- a/src/Make_ming.mak
+++ b/src/Make_ming.mak
@@ -764,6 +764,9 @@
$(OUTDIR)/gui_dwrite.o: gui_dwrite.cpp $(INCL) gui_dwrite.h
$(CXX) -c $(CFLAGS) gui_dwrite.cpp -o $(OUTDIR)/gui_dwrite.o
+$(OUTDIR)/gui_w32.o: gui_w32.c gui_w48.c $(INCL)
+ $(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o
+
$(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h
$(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o
diff --git a/src/gui.c b/src/gui.c
--- a/src/gui.c
+++ b/src/gui.c
@@ -2397,6 +2397,9 @@
# ifdef FEAT_XFONTSET
&& fontset == NOFONTSET
# endif
+# ifdef USE_DIRECT_X
+ && !p_antialias
+# endif
&& gui.wide_font != NOFONT)
dowide = TRUE;
else
diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp
--- a/src/gui_dwrite.cpp
+++ b/src/gui_dwrite.cpp
@@ -16,6 +16,10 @@
#include "gui_dwrite.h"
+extern "C" {
+#include "vim.h"
+}
+
#ifdef __MINGW32__
# define __maybenull SAL__maybenull
# define __in SAL__in
@@ -260,6 +264,8 @@
IDWriteRenderingParams *mRenderingParams;
IDWriteTextFormat *mTextFormat;
+ LPWSTR mWideFontName;
+
// METHODS
DWriteContext();
@@ -272,6 +278,10 @@
void SetFont(const LOGFONTA &logFont);
+ void SetWideFontName(LPCSTR wideFontName);
+
+ void SetWideFontName(LPCWSTR wideFontName);
+
void convertLOGFONT(const LOGFONTA &src, LOGFONTW &dst);
void DrawText(HDC hdc, const WCHAR* text, int len,
@@ -298,7 +308,8 @@
mDWriteFactory(NULL),
mGdiInterop(NULL),
mRenderingParams(NULL),
- mTextFormat(NULL)
+ mTextFormat(NULL),
+ mWideFontName(NULL)
{
HRESULT hr;
@@ -358,6 +369,7 @@
DWriteContext::~DWriteContext()
{
+ delete [] mWideFontName;
SafeRelease(&mTextFormat);
SafeRelease(&mRenderingParams);
SafeRelease(&mGdiInterop);
@@ -370,7 +382,8 @@
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
+ // 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;
@@ -496,6 +509,34 @@
}
void
+DWriteContext::SetWideFontName(LPCSTR wideFontName)
+{
+ WCHAR lfFaceName[LF_FACESIZE];
+ if (wideFontName != NULL)
+ {
+ MultiByteToWideChar(GetACP(), MB_PRECOMPOSED,
+ wideFontName, -1,
+ lfFaceName, LF_FACESIZE);
+ SetWideFontName(lfFaceName);
+ }
+ else
+ SetWideFontName((LPCWSTR)NULL);
+}
+
+ void
+DWriteContext::SetWideFontName(LPCWSTR wideFontName)
+{
+ delete [] mWideFontName;
+ mWideFontName = NULL;
+
+ if (wideFontName != NULL)
+ {
+ mWideFontName = new WCHAR[wcslen(wideFontName) + 1];
+ wcscpy(mWideFontName, wideFontName);
+ }
+}
+
+ void
DWriteContext::convertLOGFONT(const LOGFONTA &src, LOGFONTW &dst)
{
dst.lfHeight = src.lfHeight;
@@ -551,6 +592,51 @@
textLayout->SetFontStyle(DWRITE_FONT_STYLE_ITALIC, textRange);
}
+ // set 'guifontwide'
+ if (SUCCEEDED(hr) && (mWideFontName != NULL))
+ {
+ DWRITE_TEXT_RANGE textRange = { 0, 0 };
+ bool isPrevWide = false;
+ for (int i = 0; i <= len; i++)
+ {
+ int skip = 0;
+ bool isWide;
+ if (i == len)
+ isWide = !isPrevWide;
+ else
+ {
+ int c = text[i];
+
+ if ((i + 1 < len) && IS_SURROGATE_PAIR(c, text[i + 1]))
+ {
+ c = (((c - 0xd800) << 10) | (text[i + 1] - 0xdc00))
+ + 0x10000;
+ skip = 1;
+ }
+ if (utf_iscomposing(c))
+ // Composing character should use the same font as the
+ // previous character.
+ isWide = isPrevWide;
+ else
+ isWide = utf_char2cells(c) > 1;
+ }
+
+ if (isWide != isPrevWide)
+ {
+ if (i > 0)
+ {
+ textRange.length = i - textRange.startPosition;
+ if (isPrevWide)
+ textLayout->SetFontFamilyName(mWideFontName,
+ textRange);
+ textRange.startPosition = i;
+ }
+ isPrevWide = isWide;
+ }
+ i += skip;
+ }
+ }
+
if (SUCCEEDED(hr))
{
GdiTextRenderer *renderer = new GdiTextRenderer(bmpRT,
@@ -677,6 +763,18 @@
}
void
+DWriteContext_SetFontWide(DWriteContext *ctx, const LOGFONT *logFontWide)
+{
+ if (ctx != NULL)
+ {
+ if (logFontWide != NULL)
+ ctx->SetWideFontName(logFontWide->lfFaceName);
+ else
+ ctx->SetWideFontName((LPCWSTR)NULL);
+ }
+}
+
+ void
DWriteContext_DrawText(
DWriteContext *ctx,
HDC hdc,
diff --git a/src/gui_dwrite.h b/src/gui_dwrite.h
--- a/src/gui_dwrite.h
+++ b/src/gui_dwrite.h
@@ -13,6 +13,7 @@
void DWriteContext_BeginDraw(DWriteContext *ctx);
void DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect);
void DWriteContext_SetFont(DWriteContext *ctx, const LOGFONT *logFont);
+void DWriteContext_SetFontWide(DWriteContext *ctx, const LOGFONT *logFontWide);
void DWriteContext_DrawText(
DWriteContext *ctx,
HDC hdc,
diff --git a/src/gui_w48.c b/src/gui_w48.c
--- a/src/gui_w48.c
+++ b/src/gui_w48.c
@@ -3144,6 +3144,16 @@
void
gui_mch_wide_font_changed()
{
+#ifdef USE_DIRECT_X
+ LOGFONT lf_wide;
+ if (gui.wide_font != NOFONT)
+ {
+ if (GetObject(gui.wide_font, sizeof(lf_wide), &lf_wide))
+ DWriteContext_SetFontWide(s_dwc, &lf_wide);
+ }
+ else
+ DWriteContext_SetFontWide(s_dwc, NULL);
+#endif
#ifdef FEAT_MBYTE_IME
update_im_font();
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment