From 4c462a4364ebafb9859dd5af3c46a7964de44e68 Mon Sep 17 00:00:00 2001 From: Karsten Hopp Date: Aug 12 2014 08:46:21 +0000 Subject: - patchlevel 393 --- diff --git a/7.4.393 b/7.4.393 new file mode 100644 index 0000000..957ce24 --- /dev/null +++ b/7.4.393 @@ -0,0 +1,1946 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.4.393 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.4.393 +Problem: Text drawing on newer MS-Windows systems is suboptimal. Some + multi-byte characters are not displayed, even though the same font + in Notepad can display them. (Srinath Avadhanula) +Solution: Add the 'renderoptions' option to enable Direct-X drawing. (Taro + Muraoka) +Files: runtime/doc/eval.txt, runtime/doc/options.txt, + runtime/doc/various.txt, src/Make_cyg.mak, src/Make_ming.mak, + src/Make_mvc.mak, src/eval.c, src/gui_dwrite.cpp, + src/gui_dwrite.h, src/gui_w32.c, src/gui_w48.c, src/option.c, + src/option.h, src/version.c, src/vim.h, src/proto/gui_w32.pro + + +*** ../vim-7.4.392/runtime/doc/eval.txt 2014-06-25 18:15:18.442838249 +0200 +--- runtime/doc/eval.txt 2014-08-06 14:35:24.871243363 +0200 +*************** +*** 6606,6611 **** +--- 6622,6628 ---- + dialog_gui Compiled with GUI dialog support. + diff Compiled with |vimdiff| and 'diff' support. + digraphs Compiled with support for digraphs. ++ directx Compiled with support for Direct-X and 'renderoptions'. + dnd Compiled with support for the "~ register |quote_~|. + dos16 16 bits DOS version of Vim. + dos32 32 bits DOS (DJGPP) version of Vim. +*************** +*** 6744,6750 **** + writebackup Compiled with 'writebackup' default on. + xfontset Compiled with X fontset support |xfontset|. + xim Compiled with X input method support |xim|. +! xpm_w32 Compiled with pixmap support for Win32. + xsmp Compiled with X session management support. + xsmp_interact Compiled with interactive X session management support. + xterm_clipboard Compiled with support for xterm clipboard. +--- 6761,6769 ---- + writebackup Compiled with 'writebackup' default on. + xfontset Compiled with X fontset support |xfontset|. + xim Compiled with X input method support |xim|. +! xpm Compiled with pixmap support. +! xpm_w32 Compiled with pixmap support for Win32. (Only for +! backward compatibility. Use "xpm" instead.) + xsmp Compiled with X session management support. + xsmp_interact Compiled with interactive X session management support. + xterm_clipboard Compiled with support for xterm clipboard. +*** ../vim-7.4.392/runtime/doc/options.txt 2014-07-02 19:59:35.446375136 +0200 +--- runtime/doc/options.txt 2014-08-06 14:36:59.591242682 +0200 +*************** +*** 5647,5652 **** +--- 5650,5726 ---- + this option at the default "on". Only switch it off when working with + old Vi scripts. + ++ *'renderoptions'* *'rop'* ++ 'renderoptions' 'rop' string (default: empty) ++ global ++ {not in Vi} ++ {only available when compiled with GUI and DIRECTX on ++ MS-Windows} ++ Select a text renderer and set its options. The options depend on the ++ renderer. ++ ++ Syntax: > ++ set rop=type:{renderer}(,{name}:{value})* ++ < ++ Currently, only one optional renderer is available. ++ ++ render behavior ~ ++ directx Vim will draw text using DirectX (DirectWrite). It makes ++ drawn glyphs more beautiful than default GDI. ++ It requires 'encoding' is "utf-8", and only works on ++ MS-Windows Vista or newer version. ++ ++ Options: ++ name meaning type value ~ ++ gamma gamma float 1.0 - 2.2 (maybe) ++ contrast enhancedContrast float (unknown) ++ level clearTypeLevel float (unknown) ++ geom pixelGeometry int 0 - 2 (see below) ++ renmode renderingMode int 0 - 6 (see below) ++ taamode textAntialiasMode int 0 - 3 (see below) ++ ++ See this URL for detail: ++ http://msdn.microsoft.com/en-us/library/dd368190.aspx ++ ++ For geom: structure of a device pixel. ++ 0 - DWRITE_PIXEL_GEOMETRY_FLAT ++ 1 - DWRITE_PIXEL_GEOMETRY_RGB ++ 2 - DWRITE_PIXEL_GEOMETRY_BGR ++ ++ See this URL for detail: ++ http://msdn.microsoft.com/en-us/library/dd368114.aspx ++ ++ For renmode: method of rendering glyphs. ++ 0 - DWRITE_RENDERING_MODE_DEFAULT ++ 1 - DWRITE_RENDERING_MODE_ALIASED ++ 2 - DWRITE_RENDERING_MODE_GDI_CLASSIC ++ 3 - DWRITE_RENDERING_MODE_GDI_NATURAL ++ 4 - DWRITE_RENDERING_MODE_NATURAL ++ 5 - DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC ++ 6 - DWRITE_RENDERING_MODE_OUTLINE ++ ++ See this URL for detail: ++ http://msdn.microsoft.com/en-us/library/dd368118.aspx ++ ++ For taamode: antialiasing mode used for drawing text. ++ 0 - D2D1_TEXT_ANTIALIAS_MODE_DEFAULT ++ 1 - D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE ++ 2 - D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE ++ 3 - D2D1_TEXT_ANTIALIAS_MODE_ALIASED ++ ++ See this URL for detail: ++ http://msdn.microsoft.com/en-us/library/dd368170.aspx ++ ++ 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. ++ + *'report'* + 'report' number (default 2) + global +*** ../vim-7.4.392/runtime/doc/various.txt 2013-08-10 13:25:06.000000000 +0200 +--- runtime/doc/various.txt 2014-08-06 14:37:28.843242472 +0200 +*************** +*** 320,325 **** +--- 337,343 ---- + N *+dialog_con_gui* Support for |:confirm| with GUI and console dialog. + N *+diff* |vimdiff| and 'diff' + N *+digraphs* |digraphs| *E196* ++ m *+directx* Win32 GUI only: DirectX and |'renderoptions'| + *+dnd* Support for DnD into the "~ register |quote_~|. + B *+emacs_tags* |emacs-tags| files + N *+eval* expression evaluation |eval.txt| +*************** +*** 426,431 **** +--- 445,451 ---- + m *+writebackup* |'writebackup'| is default on + m *+xim* X input method |xim| + *+xfontset* X fontset support |xfontset| ++ *+xpm* pixmap support + m *+xpm_w32* Win32 GUI only: pixmap support |w32-xpm-support| + *+xsmp* XSMP (X session management) support + *+xsmp_interact* interactive XSMP (X session management) support +*** ../vim-7.4.392/src/Make_cyg.mak 2013-12-11 15:06:36.000000000 +0100 +--- src/Make_cyg.mak 2014-08-06 14:21:57.455249166 +0200 +*************** +*** 8,13 **** +--- 8,14 ---- + # Cygwin application use the Makefile (just like on Unix). + # + # GUI no or yes: set to yes if you want the GUI version (yes) ++ # DIRECTX no or yes: set to yes if you want use DirectWrite (no) + # PERL define to path to Perl dir to get Perl support (not defined) + # PERL_VER define to version of Perl being used (56) + # DYNAMIC_PERL no or yes: set to yes to load the Perl DLL dynamically (yes) +*************** +*** 88,93 **** +--- 89,98 ---- + ARCH = i386 + endif + ++ ifndef DIRECTX ++ DIRECTX = no ++ endif ++ + ifndef WINVER + WINVER = 0x0500 + endif +*************** +*** 470,475 **** +--- 475,489 ---- + endif + + ############################## ++ ifeq (yes, $(DIRECTX)) ++ # Only allow DIRECTX for a GUI build. ++ DEFINES += -DFEAT_DIRECTX -DDYNAMIC_DIRECTX ++ EXTRA_OBJS += $(OUTDIR)/gui_dwrite.o ++ EXTRA_LIBS += -ld2d1 -ldwrite ++ USE_STDCPLUS = yes ++ endif ++ ++ ############################## + ifdef XPM + # Only allow XPM for a GUI build. + DEFINES += -DFEAT_XPM_W32 +*************** +*** 495,505 **** + DEFINES += -DFEAT_OLE + EXTRA_OBJS += $(OUTDIR)/if_ole.o + EXTRA_LIBS += -loleaut32 +! ifeq (yes, $(STATIC_STDCPLUS)) +! EXTRA_LIBS += -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic +! else +! EXTRA_LIBS += -lstdc++ +! endif + endif + + ############################## +--- 509,515 ---- + DEFINES += -DFEAT_OLE + EXTRA_OBJS += $(OUTDIR)/if_ole.o + EXTRA_LIBS += -loleaut32 +! USE_STDCPLUS = yes + endif + + ############################## +*************** +*** 513,518 **** +--- 523,537 ---- + DIRSLASH = \\ + endif + ++ ############################## ++ ifeq (yes, $(USE_STDCPLUS)) ++ ifeq (yes, $(STATIC_STDCPLUS)) ++ EXTRA_LIBS += -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic ++ else ++ EXTRA_LIBS += -lstdc++ ++ endif ++ endif ++ + #>>>>> end of choices + ########################################################################### + +*************** +*** 643,648 **** +--- 662,670 ---- + $(OUTDIR)/gui_w32.o: gui_w32.c gui_w48.c $(INCL) + $(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o + ++ $(OUTDIR)/gui_dwrite.o: gui_dwrite.cpp $(INCL) gui_dwrite.h ++ $(CC) -c $(CFLAGS) gui_dwrite.cpp -o $(OUTDIR)/gui_dwrite.o ++ + $(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h + $(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o + +*** ../vim-7.4.392/src/Make_ming.mak 2014-01-06 15:44:59.000000000 +0100 +--- src/Make_ming.mak 2014-08-06 14:21:57.455249166 +0200 +*************** +*** 31,36 **** +--- 31,38 ---- + OPTIMIZE=MAXSPEED + # set to yes to make gvim, no for vim + GUI=yes ++ # set to yes if you want to use DirectWrite (DirectX) ++ DIRECTX=no + # FEATURES=[TINY | SMALL | NORMAL | BIG | HUGE] + # Set to TINY to make minimal version (few features). + FEATURES=BIG +*************** +*** 456,461 **** +--- 458,471 ---- + endif + endif + ++ # DirectWrite (DirectX) ++ ifeq ($(DIRECTX),yes) ++ # Only allow DirectWrite for a GUI build. ++ ifeq (yes, $(GUI)) ++ DEFINES += -DFEAT_DIRECTX -DDYNAMIC_DIRECTX ++ endif ++ endif ++ + # Only allow XPM for a GUI build. + ifeq (yes, $(GUI)) + +*************** +*** 593,598 **** +--- 603,616 ---- + LIB += -lwsock32 + endif + endif ++ ifeq ($(DIRECTX),yes) ++ # Only allow DIRECTX for a GUI build. ++ ifeq (yes, $(GUI)) ++ OBJ += $(OUTDIR)/gui_dwrite.o ++ LIB += -ld2d1 -ldwrite ++ USE_STDCPLUS = yes ++ endif ++ endif + ifdef XPM + # Only allow XPM for a GUI build. + ifeq (yes, $(GUI)) +*************** +*** 650,660 **** + ifeq (yes, $(OLE)) + LIB += -loleaut32 + OBJ += $(OUTDIR)/if_ole.o +! ifeq (yes, $(STATIC_STDCPLUS)) +! LIB += -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic +! else +! LIB += -lstdc++ +! endif + endif + + ifeq (yes, $(MBYTE)) +--- 668,674 ---- + ifeq (yes, $(OLE)) + LIB += -loleaut32 + OBJ += $(OUTDIR)/if_ole.o +! USE_STDCPLUS = yes + endif + + ifeq (yes, $(MBYTE)) +*************** +*** 678,683 **** +--- 692,705 ---- + DEFINES+=-DDYNAMIC_ICONV + endif + ++ ifeq (yes, $(USE_STDCPLUS)) ++ ifeq (yes, $(STATIC_STDCPLUS)) ++ LIB += -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic ++ else ++ LIB += -lstdc++ ++ endif ++ endif ++ + all: $(TARGET) vimrun.exe xxd/xxd.exe install.exe uninstal.exe GvimExt/gvimext.dll + + vimrun.exe: vimrun.c +*************** +*** 751,756 **** +--- 773,781 ---- + $(OUTDIR)/gui_w32.o: gui_w32.c gui_w48.c $(INCL) + $(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o + ++ $(OUTDIR)/gui_dwrite.o: gui_dwrite.cpp $(INCL) gui_dwrite.h ++ $(CC) -c $(CFLAGS) gui_dwrite.cpp -o $(OUTDIR)/gui_dwrite.o ++ + $(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h + $(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o + +*** ../vim-7.4.392/src/Make_mvc.mak 2014-05-22 16:29:03.374353200 +0200 +--- src/Make_mvc.mak 2014-08-06 14:21:57.455249166 +0200 +*************** +*** 24,29 **** +--- 24,32 ---- + # + # GUI interface: GUI=yes (default is no) + # ++ # GUI with DirectWrite(DirectX): DIRECTX=yes ++ # (default is no, requires GUI=yes) ++ # + # OLE interface: OLE=yes (usually with GUI=yes) + # + # Multibyte support: MBYTE=yes (default is no) +*************** +*** 168,173 **** +--- 171,179 ---- + !else + OBJDIR = .\ObjC + !endif ++ !if "$(DIRECTX)" == "yes" ++ OBJDIR = $(OBJDIR)X ++ !endif + !if "$(OLE)" == "yes" + OBJDIR = $(OBJDIR)O + !endif +*************** +*** 292,297 **** +--- 298,310 ---- + NETBEANS_LIB = WSock32.lib + !endif + ++ # DirectWrite(DirectX) ++ !if "$(DIRECTX)" == "yes" ++ DIRECTX_DEFS = -DFEAT_DIRECTX -DDYNAMIC_DIRECTX ++ DIRECTX_INCL = gui_dwrite.h ++ DIRECTX_OBJ = $(OUTDIR)\gui_dwrite.obj ++ !endif ++ + !ifndef XPM + # XPM is not set, use the included xpm files, depending on the architecture. + !if "$(CPU)" == "AMD64" +*************** +*** 642,647 **** +--- 655,666 ---- + SUBSYSTEM = console + !endif + ++ !if "$(GUI)" == "yes" && "$(DIRECTX)" == "yes" ++ CFLAGS = $(CFLAGS) $(DIRECTX_DEFS) ++ GUI_INCL = $(GUI_INCL) $(DIRECTX_INCL) ++ GUI_OBJ = $(GUI_OBJ) $(DIRECTX_OBJ) ++ !endif ++ + # iconv.dll library (dynamically loaded) + !ifndef ICONV + ICONV = yes +*************** +*** 1107,1112 **** +--- 1126,1133 ---- + + $(OUTDIR)/gui_w32.obj: $(OUTDIR) gui_w32.c gui_w48.c $(INCL) $(GUI_INCL) + ++ $(OUTDIR)/gui_dwrite.obj: $(OUTDIR) gui_dwrite.cpp $(INCL) $(GUI_INCL) ++ + $(OUTDIR)/if_cscope.obj: $(OUTDIR) if_cscope.c $(INCL) + + $(OUTDIR)/if_lua.obj: $(OUTDIR) if_lua.c $(INCL) +*** ../vim-7.4.392/src/eval.c 2014-08-06 13:36:56.091268582 +0200 +--- src/eval.c 2014-08-06 14:21:57.459249166 +0200 +*************** +*** 12464,12469 **** +--- 12464,12472 ---- + #ifdef FEAT_DIGRAPHS + "digraphs", + #endif ++ #ifdef FEAT_DIRECTX ++ "directx", ++ #endif + #ifdef FEAT_DND + "dnd", + #endif +*** ../vim-7.4.392/src/gui_dwrite.cpp 2014-08-06 14:49:19.663237363 +0200 +--- src/gui_dwrite.cpp 2014-08-06 14:39:48.775241466 +0200 +*************** +*** 0 **** +--- 1,901 ---- ++ /* vi:set ts=8 sts=4 sw=4 noet: */ ++ /* ++ * Author: MURAOKA Taro ++ * ++ * Contributors: ++ * - Ken Takata ++ * ++ * Copyright (C) 2013 MURAOKA Taro ++ * THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE. ++ */ ++ ++ #define WIN32_LEAN_AND_MEAN ++ ++ #ifndef DYNAMIC_DIRECTX ++ # if WINVER < 0x0600 ++ # error WINVER must be 0x0600 or above to use DirectWrite(DirectX) ++ # endif ++ #endif ++ ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ #include "gui_dwrite.h" ++ ++ #ifdef __MINGW32__ ++ # define __maybenull SAL__maybenull ++ # define __in SAL__in ++ # define __out SAL__out ++ #endif ++ ++ #ifdef DYNAMIC_DIRECTX ++ extern "C" HINSTANCE vimLoadLib(char *name); ++ ++ typedef int (WINAPI *PGETUSERDEFAULTLOCALENAME)(LPWSTR, int); ++ typedef HRESULT (WINAPI *PD2D1CREATEFACTORY)(D2D1_FACTORY_TYPE, ++ REFIID, const D2D1_FACTORY_OPTIONS *, void **); ++ typedef HRESULT (WINAPI *PDWRITECREATEFACTORY)(DWRITE_FACTORY_TYPE, ++ REFIID, IUnknown **); ++ ++ static HINSTANCE hD2D1DLL = NULL; ++ static HINSTANCE hDWriteDLL = NULL; ++ ++ static PGETUSERDEFAULTLOCALENAME pGetUserDefaultLocaleName = NULL; ++ static PD2D1CREATEFACTORY pD2D1CreateFactory = NULL; ++ static PDWRITECREATEFACTORY pDWriteCreateFactory = NULL; ++ ++ #define GetUserDefaultLocaleName (*pGetUserDefaultLocaleName) ++ #define D2D1CreateFactory (*pD2D1CreateFactory) ++ #define DWriteCreateFactory (*pDWriteCreateFactory) ++ ++ static void ++ unload(HINSTANCE &hinst) ++ { ++ if (hinst != NULL) ++ { ++ FreeLibrary(hinst); ++ hinst = NULL; ++ } ++ } ++ #endif // DYNAMIC_DIRECTX ++ ++ template inline void SafeRelease(T **ppT) ++ { ++ if (*ppT) ++ { ++ (*ppT)->Release(); ++ *ppT = NULL; ++ } ++ } ++ ++ struct GdiTextRendererContext ++ { ++ // const fields. ++ COLORREF color; ++ FLOAT cellWidth; ++ ++ // working fields. ++ FLOAT offsetX; ++ }; ++ ++ static DWRITE_PIXEL_GEOMETRY ++ ToPixelGeometry(int value) ++ { ++ switch (value) ++ { ++ default: ++ case 0: ++ return DWRITE_PIXEL_GEOMETRY_FLAT; ++ case 1: ++ return DWRITE_PIXEL_GEOMETRY_RGB; ++ case 2: ++ return DWRITE_PIXEL_GEOMETRY_BGR; ++ } ++ } ++ ++ static int ++ ToInt(DWRITE_PIXEL_GEOMETRY value) ++ { ++ switch (value) ++ { ++ case DWRITE_PIXEL_GEOMETRY_FLAT: ++ return 0; ++ case DWRITE_PIXEL_GEOMETRY_RGB: ++ return 1; ++ case DWRITE_PIXEL_GEOMETRY_BGR: ++ return 2; ++ default: ++ return -1; ++ } ++ } ++ ++ static DWRITE_RENDERING_MODE ++ ToRenderingMode(int value) ++ { ++ switch (value) ++ { ++ default: ++ case 0: ++ return DWRITE_RENDERING_MODE_DEFAULT; ++ case 1: ++ return DWRITE_RENDERING_MODE_ALIASED; ++ case 2: ++ return DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC; ++ case 3: ++ return DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL; ++ case 4: ++ return DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL; ++ case 5: ++ return DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; ++ case 6: ++ return DWRITE_RENDERING_MODE_OUTLINE; ++ } ++ } ++ ++ static D2D1_TEXT_ANTIALIAS_MODE ++ ToTextAntialiasMode(int value) ++ { ++ switch (value) ++ { ++ default: ++ case 0: ++ return D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; ++ case 1: ++ return D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; ++ case 2: ++ return D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE; ++ case 3: ++ return D2D1_TEXT_ANTIALIAS_MODE_ALIASED; ++ } ++ } ++ ++ static int ++ ToInt(DWRITE_RENDERING_MODE value) ++ { ++ switch (value) ++ { ++ case DWRITE_RENDERING_MODE_DEFAULT: ++ return 0; ++ case DWRITE_RENDERING_MODE_ALIASED: ++ return 1; ++ case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC: ++ return 2; ++ case DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL: ++ return 3; ++ case DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL: ++ return 4; ++ case DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC: ++ return 5; ++ case DWRITE_RENDERING_MODE_OUTLINE: ++ return 6; ++ default: ++ return -1; ++ } ++ } ++ ++ class AdjustedGlyphRun : public DWRITE_GLYPH_RUN ++ { ++ private: ++ FLOAT mDelta; ++ FLOAT *mAdjustedAdvances; ++ ++ public: ++ AdjustedGlyphRun( ++ const DWRITE_GLYPH_RUN *glyphRun, ++ FLOAT cellWidth) : ++ DWRITE_GLYPH_RUN(*glyphRun), ++ mDelta(0.0f), ++ mAdjustedAdvances(new FLOAT[glyphRun->glyphCount]) ++ { ++ assert(cellWidth != 0.0f); ++ for (UINT32 i = 0; i < glyphRun->glyphCount; ++i) ++ { ++ FLOAT orig = glyphRun->glyphAdvances[i]; ++ FLOAT adjusted = adjustToCell(orig, cellWidth); ++ mAdjustedAdvances[i] = adjusted; ++ mDelta += adjusted - orig; ++ } ++ glyphAdvances = mAdjustedAdvances; ++ } ++ ++ ~AdjustedGlyphRun(void) ++ { ++ delete[] mAdjustedAdvances; ++ } ++ ++ FLOAT getDelta(void) const ++ { ++ return mDelta; ++ } ++ ++ static FLOAT adjustToCell(FLOAT value, FLOAT cellWidth) ++ { ++ int cellCount = (int)floor(value / cellWidth + 0.5f); ++ if (cellCount < 1) ++ cellCount = 1; ++ return cellCount * cellWidth; ++ } ++ }; ++ ++ class GdiTextRenderer : public IDWriteTextRenderer ++ { ++ public: ++ GdiTextRenderer( ++ IDWriteBitmapRenderTarget* bitmapRenderTarget, ++ IDWriteRenderingParams* renderingParams) : ++ cRefCount_(0), ++ pRenderTarget_(bitmapRenderTarget), ++ pRenderingParams_(renderingParams) ++ { ++ pRenderTarget_->AddRef(); ++ pRenderingParams_->AddRef(); ++ AddRef(); ++ } ++ ++ ~GdiTextRenderer() ++ { ++ SafeRelease(&pRenderTarget_); ++ SafeRelease(&pRenderingParams_); ++ } ++ ++ IFACEMETHOD(IsPixelSnappingDisabled)( ++ __maybenull void* clientDrawingContext, ++ __out BOOL* isDisabled) ++ { ++ *isDisabled = FALSE; ++ return S_OK; ++ } ++ ++ IFACEMETHOD(GetCurrentTransform)( ++ __maybenull void* clientDrawingContext, ++ __out DWRITE_MATRIX* transform) ++ { ++ //forward the render target's transform ++ pRenderTarget_->GetCurrentTransform(transform); ++ return S_OK; ++ } ++ ++ IFACEMETHOD(GetPixelsPerDip)( ++ __maybenull void* clientDrawingContext, ++ __out FLOAT* pixelsPerDip) ++ { ++ *pixelsPerDip = pRenderTarget_->GetPixelsPerDip(); ++ return S_OK; ++ } ++ ++ IFACEMETHOD(DrawGlyphRun)( ++ __maybenull void* clientDrawingContext, ++ FLOAT baselineOriginX, ++ FLOAT baselineOriginY, ++ DWRITE_MEASURING_MODE measuringMode, ++ __in DWRITE_GLYPH_RUN const* glyphRun, ++ __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, ++ IUnknown* clientDrawingEffect) ++ { ++ HRESULT hr = S_OK; ++ ++ GdiTextRendererContext *context = ++ reinterpret_cast(clientDrawingContext); ++ ++ AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth); ++ ++ // Pass on the drawing call to the render target to do the real work. ++ RECT dirtyRect = {0}; ++ ++ hr = pRenderTarget_->DrawGlyphRun( ++ baselineOriginX + context->offsetX, ++ baselineOriginY, ++ measuringMode, ++ &adjustedGlyphRun, ++ pRenderingParams_, ++ context->color, ++ &dirtyRect); ++ ++ context->offsetX += adjustedGlyphRun.getDelta(); ++ ++ return hr; ++ } ++ ++ IFACEMETHOD(DrawUnderline)( ++ __maybenull void* clientDrawingContext, ++ FLOAT baselineOriginX, ++ FLOAT baselineOriginY, ++ __in DWRITE_UNDERLINE const* underline, ++ IUnknown* clientDrawingEffect) ++ { ++ return E_NOTIMPL; ++ } ++ ++ IFACEMETHOD(DrawStrikethrough)( ++ __maybenull void* clientDrawingContext, ++ FLOAT baselineOriginX, ++ FLOAT baselineOriginY, ++ __in DWRITE_STRIKETHROUGH const* strikethrough, ++ IUnknown* clientDrawingEffect) ++ { ++ return E_NOTIMPL; ++ } ++ ++ IFACEMETHOD(DrawInlineObject)( ++ __maybenull void* clientDrawingContext, ++ FLOAT originX, ++ FLOAT originY, ++ IDWriteInlineObject* inlineObject, ++ BOOL isSideways, ++ BOOL isRightToLeft, ++ IUnknown* clientDrawingEffect) ++ { ++ return E_NOTIMPL; ++ } ++ ++ public: ++ IFACEMETHOD_(unsigned long, AddRef) () ++ { ++ return InterlockedIncrement(&cRefCount_); ++ } ++ ++ IFACEMETHOD_(unsigned long, Release) () ++ { ++ long newCount = InterlockedDecrement(&cRefCount_); ++ ++ if (newCount == 0) ++ { ++ delete this; ++ return 0; ++ } ++ return newCount; ++ } ++ ++ IFACEMETHOD(QueryInterface)( ++ IID const& riid, ++ void** ppvObject) ++ { ++ if (__uuidof(IDWriteTextRenderer) == riid) ++ { ++ *ppvObject = this; ++ } ++ else if (__uuidof(IDWritePixelSnapping) == riid) ++ { ++ *ppvObject = this; ++ } ++ else if (__uuidof(IUnknown) == riid) ++ { ++ *ppvObject = this; ++ } ++ else ++ { ++ *ppvObject = NULL; ++ return E_FAIL; ++ } ++ ++ return S_OK; ++ } ++ ++ private: ++ unsigned long cRefCount_; ++ IDWriteBitmapRenderTarget* pRenderTarget_; ++ IDWriteRenderingParams* pRenderingParams_; ++ }; ++ ++ struct DWriteContext { ++ FLOAT mDpiScaleX; ++ FLOAT mDpiScaleY; ++ bool mDrawing; ++ ++ ID2D1Factory *mD2D1Factory; ++ ++ ID2D1DCRenderTarget *mRT; ++ ID2D1SolidColorBrush *mBrush; ++ ++ IDWriteFactory *mDWriteFactory; ++ IDWriteGdiInterop *mGdiInterop; ++ IDWriteRenderingParams *mRenderingParams; ++ IDWriteTextFormat *mTextFormat; ++ ++ HFONT mLastHFont; ++ DWRITE_FONT_WEIGHT mFontWeight; ++ DWRITE_FONT_STYLE mFontStyle; ++ ++ D2D1_TEXT_ANTIALIAS_MODE mTextAntialiasMode; ++ ++ // METHODS ++ ++ DWriteContext(); ++ ++ virtual ~DWriteContext(); ++ ++ HRESULT SetLOGFONT(const LOGFONTW &logFont, float fontSize); ++ ++ void SetFont(HFONT hFont); ++ ++ void SetFont(const LOGFONTW &logFont); ++ ++ void DrawText(HDC hdc, const WCHAR* text, int len, ++ int x, int y, int w, int h, int cellWidth, COLORREF color); ++ ++ float PixelsToDipsX(int x); ++ ++ float PixelsToDipsY(int y); ++ ++ void SetRenderingParams( ++ const DWriteRenderingParams *params); ++ ++ DWriteRenderingParams *GetRenderingParams( ++ DWriteRenderingParams *params); ++ }; ++ ++ DWriteContext::DWriteContext() : ++ mDpiScaleX(1.f), ++ mDpiScaleY(1.f), ++ mDrawing(false), ++ mD2D1Factory(NULL), ++ mRT(NULL), ++ mBrush(NULL), ++ mDWriteFactory(NULL), ++ mGdiInterop(NULL), ++ mRenderingParams(NULL), ++ mTextFormat(NULL), ++ mLastHFont(NULL), ++ mFontWeight(DWRITE_FONT_WEIGHT_NORMAL), ++ mFontStyle(DWRITE_FONT_STYLE_NORMAL), ++ mTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_DEFAULT) ++ { ++ HRESULT hr; ++ ++ HDC screen = ::GetDC(0); ++ mDpiScaleX = ::GetDeviceCaps(screen, LOGPIXELSX) / 96.0f; ++ mDpiScaleY = ::GetDeviceCaps(screen, LOGPIXELSY) / 96.0f; ++ ::ReleaseDC(0, screen); ++ ++ hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, ++ __uuidof(ID2D1Factory), NULL, ++ reinterpret_cast(&mD2D1Factory)); ++ _RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory); ++ ++ if (SUCCEEDED(hr)) ++ { ++ D2D1_RENDER_TARGET_PROPERTIES props = { ++ D2D1_RENDER_TARGET_TYPE_DEFAULT, ++ { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE }, ++ 0, 0, ++ D2D1_RENDER_TARGET_USAGE_NONE, ++ D2D1_FEATURE_LEVEL_DEFAULT ++ }; ++ hr = mD2D1Factory->CreateDCRenderTarget(&props, &mRT); ++ _RPT2(_CRT_WARN, "CreateDCRenderTarget: hr=%p p=%p\n", hr, mRT); ++ } ++ ++ if (SUCCEEDED(hr)) ++ { ++ hr = mRT->CreateSolidColorBrush( ++ D2D1::ColorF(D2D1::ColorF::Black), ++ &mBrush); ++ _RPT2(_CRT_WARN, "CreateSolidColorBrush: hr=%p p=%p\n", hr, mBrush); ++ } ++ ++ if (SUCCEEDED(hr)) ++ { ++ hr = DWriteCreateFactory( ++ DWRITE_FACTORY_TYPE_SHARED, ++ __uuidof(IDWriteFactory), ++ reinterpret_cast(&mDWriteFactory)); ++ _RPT2(_CRT_WARN, "DWriteCreateFactory: hr=%p p=%p\n", hr, ++ mDWriteFactory); ++ } ++ ++ if (SUCCEEDED(hr)) ++ { ++ hr = mDWriteFactory->GetGdiInterop(&mGdiInterop); ++ _RPT2(_CRT_WARN, "GetGdiInterop: hr=%p p=%p\n", hr, mGdiInterop); ++ } ++ ++ if (SUCCEEDED(hr)) ++ { ++ hr = mDWriteFactory->CreateRenderingParams(&mRenderingParams); ++ _RPT2(_CRT_WARN, "CreateRenderingParams: hr=%p p=%p\n", hr, ++ mRenderingParams); ++ } ++ } ++ ++ DWriteContext::~DWriteContext() ++ { ++ SafeRelease(&mTextFormat); ++ SafeRelease(&mRenderingParams); ++ SafeRelease(&mGdiInterop); ++ SafeRelease(&mDWriteFactory); ++ SafeRelease(&mBrush); ++ SafeRelease(&mRT); ++ SafeRelease(&mD2D1Factory); ++ } ++ ++ HRESULT ++ DWriteContext::SetLOGFONT(const LOGFONTW &logFont, float fontSize) ++ { ++ // Most of this function is copy from: http://msdn.microsoft.com/en-us/library/windows/desktop/dd941783(v=vs.85).aspx ++ HRESULT hr = S_OK; ++ ++ IDWriteFont *font = NULL; ++ IDWriteFontFamily *fontFamily = NULL; ++ IDWriteLocalizedStrings *localizedFamilyNames = NULL; ++ ++ if (SUCCEEDED(hr)) ++ { ++ hr = mGdiInterop->CreateFontFromLOGFONT(&logFont, &font); ++ } ++ ++ // Get the font family to which this font belongs. ++ if (SUCCEEDED(hr)) ++ { ++ hr = font->GetFontFamily(&fontFamily); ++ } ++ ++ // Get the family names. This returns an object that encapsulates one or ++ // more names with the same meaning but in different languages. ++ if (SUCCEEDED(hr)) ++ { ++ hr = fontFamily->GetFamilyNames(&localizedFamilyNames); ++ } ++ ++ // Get the family name at index zero. If we were going to display the name ++ // we'd want to try to find one that matched the use locale, but for ++ // purposes of creating a text format object any language will do. ++ ++ wchar_t familyName[100]; ++ if (SUCCEEDED(hr)) ++ { ++ hr = localizedFamilyNames->GetString(0, familyName, ++ ARRAYSIZE(familyName)); ++ } ++ ++ if (SUCCEEDED(hr)) ++ { ++ // If no font size was passed in use the lfHeight of the LOGFONT. ++ if (fontSize == 0) ++ { ++ // Convert from pixels to DIPs. ++ fontSize = PixelsToDipsY(logFont.lfHeight); ++ if (fontSize < 0) ++ { ++ // Negative lfHeight represents the size of the em unit. ++ fontSize = -fontSize; ++ } ++ else ++ { ++ // Positive lfHeight represents the cell height (ascent + ++ // descent). ++ DWRITE_FONT_METRICS fontMetrics; ++ font->GetMetrics(&fontMetrics); ++ ++ // Convert the cell height (ascent + descent) from design units ++ // to ems. ++ float cellHeight = static_cast( ++ fontMetrics.ascent + fontMetrics.descent) ++ / fontMetrics.designUnitsPerEm; ++ ++ // Divide the font size by the cell height to get the font em ++ // size. ++ fontSize /= cellHeight; ++ } ++ } ++ } ++ ++ // The text format includes a locale name. Ideally, this would be the ++ // language of the text, which may or may not be the same as the primary ++ // language of the user. However, for our purposes the user locale will do. ++ wchar_t localeName[LOCALE_NAME_MAX_LENGTH]; ++ if (SUCCEEDED(hr)) ++ { ++ if (GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH) == 0) ++ hr = HRESULT_FROM_WIN32(GetLastError()); ++ } ++ ++ if (SUCCEEDED(hr)) ++ { ++ // Create the text format object. ++ hr = mDWriteFactory->CreateTextFormat( ++ familyName, ++ NULL, // no custom font collection ++ font->GetWeight(), ++ font->GetStyle(), ++ font->GetStretch(), ++ fontSize, ++ localeName, ++ &mTextFormat); ++ } ++ ++ if (SUCCEEDED(hr)) ++ { ++ mFontWeight = static_cast(logFont.lfWeight); ++ mFontStyle = logFont.lfItalic ? DWRITE_FONT_STYLE_ITALIC ++ : DWRITE_FONT_STYLE_NORMAL; ++ } ++ ++ SafeRelease(&localizedFamilyNames); ++ SafeRelease(&fontFamily); ++ SafeRelease(&font); ++ ++ return hr; ++ } ++ ++ void ++ DWriteContext::SetFont(HFONT hFont) ++ { ++ if (mLastHFont != hFont) ++ { ++ LOGFONTW lf; ++ if (GetObjectW(hFont, sizeof(lf), &lf)) ++ { ++ SetFont(lf); ++ mLastHFont = hFont; ++ } ++ } ++ } ++ ++ void ++ DWriteContext::SetFont(const LOGFONTW &logFont) ++ { ++ SafeRelease(&mTextFormat); ++ mLastHFont = NULL; ++ ++ HRESULT hr = SetLOGFONT(logFont, 0.f); ++ ++ if (SUCCEEDED(hr)) ++ hr = mTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_LEADING); ++ ++ if (SUCCEEDED(hr)) ++ hr = mTextFormat->SetParagraphAlignment( ++ DWRITE_PARAGRAPH_ALIGNMENT_CENTER); ++ ++ if (SUCCEEDED(hr)) ++ hr = mTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); ++ } ++ ++ void ++ DWriteContext::DrawText(HDC hdc, const WCHAR* text, int len, ++ int x, int y, int w, int h, int cellWidth, COLORREF color) ++ { ++ HRESULT hr = S_OK; ++ IDWriteBitmapRenderTarget *bmpRT = NULL; ++ ++ // Skip when any fonts are not set. ++ if (mTextFormat == NULL) ++ return; ++ ++ // Check possibility of zero divided error. ++ if (cellWidth == 0 || mDpiScaleX == 0.0f || mDpiScaleY == 0.0f) ++ return; ++ ++ if (SUCCEEDED(hr)) ++ hr = mGdiInterop->CreateBitmapRenderTarget(hdc, w, h, &bmpRT); ++ ++ if (SUCCEEDED(hr)) ++ { ++ IDWriteTextLayout *textLayout = NULL; ++ ++ HDC memdc = bmpRT->GetMemoryDC(); ++ BitBlt(memdc, 0, 0, w, h, hdc, x, y, SRCCOPY); ++ ++ hr = mDWriteFactory->CreateGdiCompatibleTextLayout( ++ text, len, mTextFormat, PixelsToDipsX(w), ++ PixelsToDipsY(h), mDpiScaleX, NULL, TRUE, &textLayout); ++ ++ if (SUCCEEDED(hr)) ++ { ++ DWRITE_TEXT_RANGE textRange = { 0, len }; ++ textLayout->SetFontWeight(mFontWeight, textRange); ++ textLayout->SetFontStyle(mFontStyle, textRange); ++ } ++ ++ if (SUCCEEDED(hr)) ++ { ++ GdiTextRenderer *renderer = new GdiTextRenderer(bmpRT, ++ mRenderingParams); ++ GdiTextRendererContext data = { ++ color, ++ PixelsToDipsX(cellWidth), ++ 0.0f ++ }; ++ textLayout->Draw(&data, renderer, 0, 0); ++ SafeRelease(&renderer); ++ } ++ ++ BitBlt(hdc, x, y, w, h, memdc, 0, 0, SRCCOPY); ++ ++ SafeRelease(&textLayout); ++ } ++ ++ SafeRelease(&bmpRT); ++ } ++ ++ float ++ DWriteContext::PixelsToDipsX(int x) ++ { ++ return x / mDpiScaleX; ++ } ++ ++ float ++ DWriteContext::PixelsToDipsY(int y) ++ { ++ return y / mDpiScaleY; ++ } ++ ++ void ++ DWriteContext::SetRenderingParams( ++ const DWriteRenderingParams *params) ++ { ++ if (mDWriteFactory == NULL) ++ return; ++ ++ IDWriteRenderingParams *renderingParams = NULL; ++ D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode = ++ D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; ++ HRESULT hr; ++ if (params != NULL) ++ { ++ hr = mDWriteFactory->CreateCustomRenderingParams(params->gamma, ++ params->enhancedContrast, params->clearTypeLevel, ++ ToPixelGeometry(params->pixelGeometry), ++ ToRenderingMode(params->renderingMode), &renderingParams); ++ textAntialiasMode = ToTextAntialiasMode(params->textAntialiasMode); ++ } ++ else ++ hr = mDWriteFactory->CreateRenderingParams(&renderingParams); ++ if (SUCCEEDED(hr) && renderingParams != NULL) ++ { ++ SafeRelease(&mRenderingParams); ++ mRenderingParams = renderingParams; ++ mTextAntialiasMode = textAntialiasMode; ++ } ++ } ++ ++ DWriteRenderingParams * ++ DWriteContext::GetRenderingParams( ++ DWriteRenderingParams *params) ++ { ++ if (params != NULL && mRenderingParams != NULL) ++ { ++ params->gamma = mRenderingParams->GetGamma(); ++ params->enhancedContrast = mRenderingParams->GetEnhancedContrast(); ++ params->clearTypeLevel = mRenderingParams->GetClearTypeLevel(); ++ params->pixelGeometry = ToInt(mRenderingParams->GetPixelGeometry()); ++ params->renderingMode = ToInt(mRenderingParams->GetRenderingMode()); ++ params->textAntialiasMode = mTextAntialiasMode; ++ } ++ return params; ++ } ++ ++ //////////////////////////////////////////////////////////////////////////// ++ // PUBLIC C INTERFACES ++ ++ void ++ DWrite_Init(void) ++ { ++ #ifdef DYNAMIC_DIRECTX ++ // Load libraries. ++ hD2D1DLL = vimLoadLib(const_cast("d2d1.dll")); ++ hDWriteDLL = vimLoadLib(const_cast("dwrite.dll")); ++ if (hD2D1DLL == NULL || hDWriteDLL == NULL) ++ { ++ DWrite_Final(); ++ return; ++ } ++ // Get address of procedures. ++ pGetUserDefaultLocaleName = (PGETUSERDEFAULTLOCALENAME)GetProcAddress( ++ GetModuleHandle("kernel32.dll"), "GetUserDefaultLocaleName"); ++ pD2D1CreateFactory = (PD2D1CREATEFACTORY)GetProcAddress(hD2D1DLL, ++ "D2D1CreateFactory"); ++ pDWriteCreateFactory = (PDWRITECREATEFACTORY)GetProcAddress(hDWriteDLL, ++ "DWriteCreateFactory"); ++ #endif ++ } ++ ++ void ++ DWrite_Final(void) ++ { ++ #ifdef DYNAMIC_DIRECTX ++ pGetUserDefaultLocaleName = NULL; ++ pD2D1CreateFactory = NULL; ++ pDWriteCreateFactory = NULL; ++ unload(hDWriteDLL); ++ unload(hD2D1DLL); ++ #endif ++ } ++ ++ DWriteContext * ++ DWriteContext_Open(void) ++ { ++ #ifdef DYNAMIC_DIRECTX ++ if (pGetUserDefaultLocaleName == NULL || pD2D1CreateFactory == NULL ++ || pDWriteCreateFactory == NULL) ++ return NULL; ++ #endif ++ return new DWriteContext(); ++ } ++ ++ void ++ DWriteContext_BeginDraw(DWriteContext *ctx) ++ { ++ if (ctx != NULL && ctx->mRT != NULL) ++ { ++ ctx->mRT->BeginDraw(); ++ ctx->mRT->SetTransform(D2D1::IdentityMatrix()); ++ ctx->mDrawing = true; ++ } ++ } ++ ++ void ++ DWriteContext_BindDC(DWriteContext *ctx, HDC hdc, RECT *rect) ++ { ++ if (ctx != NULL && ctx->mRT != NULL) ++ { ++ ctx->mRT->BindDC(hdc, rect); ++ ctx->mRT->SetTextAntialiasMode(ctx->mTextAntialiasMode); ++ } ++ } ++ ++ void ++ DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont) ++ { ++ if (ctx != NULL) ++ { ++ ctx->SetFont(hFont); ++ } ++ } ++ ++ void ++ DWriteContext_DrawText( ++ DWriteContext *ctx, ++ HDC hdc, ++ const WCHAR* text, ++ int len, ++ int x, ++ int y, ++ int w, ++ int h, ++ int cellWidth, ++ COLORREF color) ++ { ++ if (ctx != NULL) ++ ctx->DrawText(hdc, text, len, x, y, w, h, cellWidth, color); ++ } ++ ++ void ++ DWriteContext_EndDraw(DWriteContext *ctx) ++ { ++ if (ctx != NULL && ctx->mRT != NULL) ++ { ++ ctx->mRT->EndDraw(); ++ ctx->mDrawing = false; ++ } ++ } ++ ++ void ++ DWriteContext_Close(DWriteContext *ctx) ++ { ++ delete ctx; ++ } ++ ++ void ++ DWriteContext_SetRenderingParams( ++ DWriteContext *ctx, ++ const DWriteRenderingParams *params) ++ { ++ if (ctx != NULL) ++ ctx->SetRenderingParams(params); ++ } ++ ++ DWriteRenderingParams * ++ DWriteContext_GetRenderingParams( ++ DWriteContext *ctx, ++ DWriteRenderingParams *params) ++ { ++ if (ctx != NULL) ++ return ctx->GetRenderingParams(params); ++ else ++ return NULL; ++ } +*** ../vim-7.4.392/src/gui_dwrite.h 2014-08-06 14:49:19.667237363 +0200 +--- src/gui_dwrite.h 2014-08-06 14:21:57.459249166 +0200 +*************** +*** 0 **** +--- 1,85 ---- ++ /* vi:set ts=8 sts=4 sw=4 noet: */ ++ /* ++ * Author: MURAOKA Taro ++ * ++ * Contributors: ++ * - Ken Takata ++ * ++ * Copyright (C) 2013 MURAOKA Taro ++ * THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE. ++ */ ++ ++ #ifndef GUI_DWRITE_H ++ #define GUI_DWRITE_H ++ ++ #ifdef __cplusplus ++ extern "C" { ++ #endif ++ ++ typedef struct DWriteContext DWriteContext; ++ ++ typedef struct DWriteRenderingParams { ++ float gamma; ++ float enhancedContrast; ++ float clearTypeLevel; ++ /* ++ * pixelGeometry: ++ * 0 - DWRITE_PIXEL_GEOMETRY_FLAT ++ * 1 - DWRITE_PIXEL_GEOMETRY_RGB ++ * 2 - DWRITE_PIXEL_GEOMETRY_BGR ++ */ ++ int pixelGeometry; ++ /* ++ * renderingMode: ++ * 0 - DWRITE_RENDERING_MODE_DEFAULT ++ * 1 - DWRITE_RENDERING_MODE_ALIASED ++ * 2 - DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC ++ * 3 - DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL ++ * 4 - DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL ++ * 5 - DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC ++ * 6 - DWRITE_RENDERING_MODE_OUTLINE ++ */ ++ int renderingMode; ++ /* ++ * antialiasMode: ++ * 0 - D2D1_TEXT_ANTIALIAS_MODE_DEFAULT ++ * 1 - D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE ++ * 2 - D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE ++ * 3 - D2D1_TEXT_ANTIALIAS_MODE_ALIASED ++ */ ++ int textAntialiasMode; ++ } DWriteRenderingParams; ++ ++ void DWrite_Init(void); ++ 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, ++ int y, ++ int w, ++ int h, ++ int cellWidth, ++ COLORREF color); ++ void DWriteContext_EndDraw(DWriteContext *ctx); ++ void DWriteContext_Close(DWriteContext *ctx); ++ ++ void DWriteContext_SetRenderingParams( ++ DWriteContext *ctx, ++ const DWriteRenderingParams *params); ++ ++ DWriteRenderingParams *DWriteContext_GetRenderingParams( ++ DWriteContext *ctx, ++ DWriteRenderingParams *params); ++ ++ #ifdef __cplusplus ++ } ++ #endif ++ #endif/*GUI_DWRITE_H*/ +*** ../vim-7.4.392/src/gui_w32.c 2013-08-04 16:15:37.000000000 +0200 +--- src/gui_w32.c 2014-08-06 14:45:43.495238916 +0200 +*************** +*** 25,30 **** +--- 25,169 ---- + + #include "vim.h" + ++ #if defined(FEAT_DIRECTX) ++ # include "gui_dwrite.h" ++ #endif ++ ++ #if defined(FEAT_DIRECTX) || defined(PROTO) ++ static DWriteContext *s_dwc = NULL; ++ static int s_directx_enabled = 0; ++ static int s_directx_load_attempted = 0; ++ # define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL) ++ ++ 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) ++ { ++ #ifdef FEAT_DIRECTX ++ int retval = FAIL; ++ char_u *p, *q; ++ ++ int dx_enable = 0; ++ int dx_flags = 0; ++ float dx_gamma = 0.0f; ++ float dx_contrast = 0.0f; ++ float dx_level = 0.0f; ++ int dx_geom = 0; ++ int dx_renmode = 0; ++ int dx_taamode = 0; ++ ++ /* parse string as rendering options. */ ++ for (p = s; p != NULL && *p != NUL; ) ++ { ++ char_u item[256]; ++ char_u name[128]; ++ char_u value[128]; ++ ++ copy_option_part(&p, item, sizeof(item), ","); ++ if (p == NULL) ++ break; ++ q = &item[0]; ++ copy_option_part(&q, name, sizeof(name), ":"); ++ if (q == NULL) ++ return FAIL; ++ copy_option_part(&q, value, sizeof(value), ":"); ++ ++ if (STRCMP(name, "type") == 0) ++ { ++ if (STRCMP(value, "directx") == 0) ++ dx_enable = 1; ++ else ++ return FAIL; ++ } ++ else if (STRCMP(name, "gamma") == 0) ++ { ++ dx_flags |= 1 << 0; ++ dx_gamma = (float)atof(value); ++ } ++ else if (STRCMP(name, "contrast") == 0) ++ { ++ dx_flags |= 1 << 1; ++ dx_contrast = (float)atof(value); ++ } ++ else if (STRCMP(name, "level") == 0) ++ { ++ dx_flags |= 1 << 2; ++ dx_level = (float)atof(value); ++ } ++ else if (STRCMP(name, "geom") == 0) ++ { ++ dx_flags |= 1 << 3; ++ dx_geom = atoi(value); ++ if (dx_geom < 0 || dx_geom > 2) ++ return FAIL; ++ } ++ else if (STRCMP(name, "renmode") == 0) ++ { ++ dx_flags |= 1 << 4; ++ dx_renmode = atoi(value); ++ if (dx_renmode < 0 || dx_renmode > 6) ++ return FAIL; ++ } ++ else if (STRCMP(name, "taamode") == 0) ++ { ++ dx_flags |= 1 << 5; ++ dx_taamode = atoi(value); ++ if (dx_taamode < 0 || dx_taamode > 3) ++ return FAIL; ++ } ++ else ++ return FAIL; ++ } ++ ++ /* Enable DirectX/DirectWrite */ ++ if (dx_enable) ++ { ++ if (!directx_enabled()) ++ return FAIL; ++ DWriteContext_SetRenderingParams(s_dwc, NULL); ++ if (dx_flags) ++ { ++ DWriteRenderingParams param; ++ DWriteContext_GetRenderingParams(s_dwc, ¶m); ++ if (dx_flags & (1 << 0)) ++ param.gamma = dx_gamma; ++ if (dx_flags & (1 << 1)) ++ param.enhancedContrast = dx_contrast; ++ if (dx_flags & (1 << 2)) ++ param.clearTypeLevel = dx_level; ++ if (dx_flags & (1 << 3)) ++ param.pixelGeometry = dx_geom; ++ if (dx_flags & (1 << 4)) ++ param.renderingMode = dx_renmode; ++ if (dx_flags & (1 << 5)) ++ param.textAntialiasMode = dx_taamode; ++ DWriteContext_SetRenderingParams(s_dwc, ¶m); ++ } ++ } ++ s_directx_enabled = dx_enable; ++ ++ return OK; ++ #else ++ return FAIL; ++ #endif ++ } ++ #endif ++ + /* + * These are new in Windows ME/XP, only defined in recent compilers. + */ +*************** +*** 1624,1629 **** +--- 1763,1773 ---- + set_vim_var_nr(VV_WINDOWID, HandleToLong(s_hwnd)); + #endif + ++ #ifdef FEAT_RENDER_OPTIONS ++ if (p_rop) ++ (void)gui_mch_set_rendering_options(p_rop); ++ #endif ++ + theend: + /* Display any pending error messages */ + display_errors(); +*************** +*** 1695,1703 **** + + /* compute the size of the outside of the window */ + win_width = width + (GetSystemMetrics(SM_CXFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; + win_height = height + (GetSystemMetrics(SM_CYFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 + + GetSystemMetrics(SM_CYCAPTION) + #ifdef FEAT_MENU + + gui_mswin_get_menu_height(FALSE) +--- 1839,1847 ---- + + /* compute the size of the outside of the window */ + win_width = width + (GetSystemMetrics(SM_CXFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; + win_height = height + (GetSystemMetrics(SM_CYFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 + + GetSystemMetrics(SM_CYCAPTION) + #ifdef FEAT_MENU + + gui_mswin_get_menu_height(FALSE) +*************** +*** 2239,2244 **** +--- 2383,2391 ---- + #endif + HPEN hpen, old_pen; + int y; ++ #ifdef FEAT_DIRECTX ++ int font_is_ttf_or_vector = 0; ++ #endif + + #ifndef MSWIN16_FASTTEXT + /* +*************** +*** 2326,2331 **** +--- 2473,2492 ---- + SetTextColor(s_hdc, gui.currFgColor); + SelectFont(s_hdc, gui.currFont); + ++ #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) + { + vim_free(padding); +*************** +*** 2360,2365 **** +--- 2521,2534 ---- + if (text[n] >= 0x80) + break; + ++ #if defined(FEAT_DIRECTX) ++ /* Quick hack to enable DirectWrite. To use DirectWrite (antialias), it is ++ * required that unicode drawing routine, currently. So this forces it ++ * enabled. */ ++ if (enc_utf8 && IS_ENABLE_DIRECTX()) ++ n = 0; /* Keep n < len, to enter block for unicode. */ ++ #endif ++ + /* Check if the Unicode buffer exists and is big enough. Create it + * with the same length as the multi-byte string, the number of wide + * characters is always equal or smaller. */ +*************** +*** 2418,2425 **** + i += utfc_ptr2len_len(text + i, len - i); + ++clen; + } +! ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row), +! foptions, pcliprect, unicodebuf, wlen, unicodepdy); + len = cells; /* used for underlining */ + } + else if ((enc_codepage > 0 && (int)GetACP() != enc_codepage) || enc_latin9) +--- 2587,2603 ---- + i += utfc_ptr2len_len(text + i, len - i); + ++clen; + } +! #if defined(FEAT_DIRECTX) +! if (IS_ENABLE_DIRECTX() && font_is_ttf_or_vector) +! { +! DWriteContext_DrawText(s_dwc, s_hdc, unicodebuf, wlen, +! TEXT_X(col), TEXT_Y(row), FILL_X(cells), FILL_Y(1), +! gui.char_width, gui.currFgColor); +! } +! else +! #endif +! ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row), +! foptions, pcliprect, unicodebuf, wlen, unicodepdy); + len = cells; /* used for underlining */ + } + else if ((enc_codepage > 0 && (int)GetACP() != enc_codepage) || enc_latin9) +*************** +*** 2549,2562 **** + + *screen_w = workarea_rect.right - workarea_rect.left + - (GetSystemMetrics(SM_CXFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; + + /* FIXME: dirty trick: Because the gui_get_base_height() doesn't include + * the menubar for MSwin, we subtract it from the screen height, so that + * the window size can be made to fit on the screen. */ + *screen_h = workarea_rect.bottom - workarea_rect.top + - (GetSystemMetrics(SM_CYFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 + - GetSystemMetrics(SM_CYCAPTION) + #ifdef FEAT_MENU + - gui_mswin_get_menu_height(FALSE) +--- 2727,2740 ---- + + *screen_w = workarea_rect.right - workarea_rect.left + - (GetSystemMetrics(SM_CXFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; + + /* FIXME: dirty trick: Because the gui_get_base_height() doesn't include + * the menubar for MSwin, we subtract it from the screen height, so that + * the window size can be made to fit on the screen. */ + *screen_h = workarea_rect.bottom - workarea_rect.top + - (GetSystemMetrics(SM_CYFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 + - GetSystemMetrics(SM_CYCAPTION) + #ifdef FEAT_MENU + - gui_mswin_get_menu_height(FALSE) +*************** +*** 3188,3200 **** + GetWindowRect(s_hwnd, &rect); + maxDialogWidth = rect.right - rect.left + - (GetSystemMetrics(SM_CXFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; + if (maxDialogWidth < DLG_MIN_MAX_WIDTH) + maxDialogWidth = DLG_MIN_MAX_WIDTH; + + maxDialogHeight = rect.bottom - rect.top + - (GetSystemMetrics(SM_CYFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 4 + - GetSystemMetrics(SM_CYCAPTION); + if (maxDialogHeight < DLG_MIN_MAX_HEIGHT) + maxDialogHeight = DLG_MIN_MAX_HEIGHT; +--- 3366,3378 ---- + GetWindowRect(s_hwnd, &rect); + maxDialogWidth = rect.right - rect.left + - (GetSystemMetrics(SM_CXFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; + if (maxDialogWidth < DLG_MIN_MAX_WIDTH) + maxDialogWidth = DLG_MIN_MAX_WIDTH; + + maxDialogHeight = rect.bottom - rect.top + - (GetSystemMetrics(SM_CYFRAME) + +! GetSystemMetrics(SM_CXPADDEDBORDER)) * 4 + - GetSystemMetrics(SM_CYCAPTION); + if (maxDialogHeight < DLG_MIN_MAX_HEIGHT) + maxDialogHeight = DLG_MIN_MAX_HEIGHT; +*************** +*** 3351,3361 **** + /* Restrict the size to a maximum. Causes a scrollbar to show up. */ + if (dlgheight > maxDialogHeight) + { +! msgheight = msgheight - (dlgheight - maxDialogHeight); +! dlgheight = maxDialogHeight; +! scroll_flag = WS_VSCROLL; +! /* Make sure scrollbar doesn't appear in the middle of the dialog */ +! messageWidth = dlgwidth - DLG_ICON_WIDTH - 3 * dlgPaddingX; + } + + add_word(PixelToDialogY(dlgheight)); +--- 3529,3539 ---- + /* Restrict the size to a maximum. Causes a scrollbar to show up. */ + if (dlgheight > maxDialogHeight) + { +! msgheight = msgheight - (dlgheight - maxDialogHeight); +! dlgheight = maxDialogHeight; +! scroll_flag = WS_VSCROLL; +! /* Make sure scrollbar doesn't appear in the middle of the dialog */ +! messageWidth = dlgwidth - DLG_ICON_WIDTH - 3 * dlgPaddingX; + } + + add_word(PixelToDialogY(dlgheight)); +*** ../vim-7.4.392/src/gui_w48.c 2014-03-23 15:12:29.923264336 +0100 +--- src/gui_w48.c 2014-08-06 14:21:57.463249166 +0200 +*************** +*** 2785,2790 **** +--- 2785,2794 ---- + + 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 +*************** +*** 2800,2808 **** +--- 2804,2823 ---- + #endif + + 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); + } + } +*************** +*** 3043,3048 **** +--- 3058,3069 ---- + void + gui_mch_exit(int rc) + { ++ #if defined(FEAT_DIRECTX) ++ DWriteContext_Close(s_dwc); ++ DWrite_Final(); ++ s_dwc = NULL; ++ #endif ++ + ReleaseDC(s_textArea, s_hdc); + DeleteObject(s_brush); + +*** ../vim-7.4.392/src/option.c 2014-06-25 14:44:04.458358774 +0200 +--- src/option.c 2014-08-06 14:33:24.503244228 +0200 +*************** +*** 2124,2129 **** +--- 2124,2138 ---- + {"remap", NULL, P_BOOL|P_VI_DEF, + (char_u *)&p_remap, PV_NONE, + {(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT}, ++ {"renderoptions", "rop", P_STRING|P_COMMA|P_RCLR|P_VI_DEF, ++ #ifdef FEAT_RENDER_OPTIONS ++ (char_u *)&p_rop, PV_NONE, ++ {(char_u *)"", (char_u *)0L} ++ #else ++ (char_u *)NULL, PV_NONE, ++ {(char_u *)NULL, (char_u *)0L} ++ #endif ++ SCRIPTID_INIT}, + {"report", NULL, P_NUM|P_VI_DEF, + (char_u *)&p_report, PV_NONE, + {(char_u *)2L, (char_u *)0L} SCRIPTID_INIT}, +*************** +*** 6999,7004 **** +--- 7008,7021 ---- + } + #endif + ++ #if defined(FEAT_RENDER_OPTIONS) ++ else if (varp == &p_rop && gui.in_use) ++ { ++ if (!gui_mch_set_rendering_options(p_rop)) ++ errmsg = e_invarg; ++ } ++ #endif ++ + /* Options that are a list of flags. */ + else + { +*** ../vim-7.4.392/src/option.h 2014-06-25 14:39:35.110348584 +0200 +--- src/option.h 2014-08-06 14:23:25.419248534 +0200 +*************** +*** 655,660 **** +--- 655,663 ---- + #endif + EXTERN int p_remap; /* 'remap' */ + EXTERN long p_re; /* 'regexpengine' */ ++ #ifdef FEAT_RENDER_OPTIONS ++ EXTERN char_u *p_rop; /* 'renderoptions' */ ++ #endif + EXTERN long p_report; /* 'report' */ + #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) + EXTERN long p_pvh; /* 'previewheight' */ +*** ../vim-7.4.392/src/version.c 2014-08-06 13:36:56.091268582 +0200 +--- src/version.c 2014-08-06 14:29:39.183245847 +0200 +*************** +*** 189,194 **** +--- 189,201 ---- + #else + "-digraphs", + #endif ++ #ifdef FEAT_GUI_W32 ++ # ifdef FEAT_DIRECTX ++ "+directx", ++ # else ++ "-directx", ++ # endif ++ #endif + #ifdef FEAT_DND + "+dnd", + #else +*** ../vim-7.4.392/src/vim.h 2014-04-02 19:54:58.275599459 +0200 +--- src/vim.h 2014-08-06 14:21:57.467249166 +0200 +*************** +*** 134,139 **** +--- 134,146 ---- + # endif + #endif + ++ /* Check support for rendering options */ ++ #ifdef FEAT_GUI ++ # if defined(FEAT_DIRECTX) ++ # define FEAT_RENDER_OPTIONS ++ # endif ++ #endif ++ + /* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */ + #if _MSC_VER >= 1400 + # define _CRT_SECURE_NO_DEPRECATE +*** ../vim-7.4.392/src/proto/gui_w32.pro 2013-08-10 13:37:36.000000000 +0200 +--- src/proto/gui_w32.pro 2014-08-06 14:33:04.155244374 +0200 +*************** +*** 1,4 **** +--- 1,6 ---- + /* gui_w32.c */ ++ int directx_enabled __ARGS((void)); ++ int gui_mch_set_rendering_options __ARGS((char_u *s)); + void gui_mch_set_blinking __ARGS((long wait, long on, long off)); + void gui_mch_stop_blink __ARGS((void)); + void gui_mch_start_blink __ARGS((void)); +*** ../vim-7.4.392/src/version.c 2014-08-06 13:36:56.091268582 +0200 +--- src/version.c 2014-08-06 14:29:39.183245847 +0200 +*************** +*** 736,737 **** +--- 743,746 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 393, + /**/ + +-- +A consultant is a person who takes your money and annoys your employees while +tirelessly searching for the best way to extend the consulting contract. + (Scott Adams - The Dilbert principle) + + /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 ///