mirror of
https://github.com/zoriya/vim.git
synced 2025-12-19 13:45:18 +00:00
updated for version 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)
This commit is contained in:
@@ -6622,6 +6622,7 @@ dialog_con Compiled with console dialog support.
|
|||||||
dialog_gui Compiled with GUI dialog support.
|
dialog_gui Compiled with GUI dialog support.
|
||||||
diff Compiled with |vimdiff| and 'diff' support.
|
diff Compiled with |vimdiff| and 'diff' support.
|
||||||
digraphs Compiled with support for digraphs.
|
digraphs Compiled with support for digraphs.
|
||||||
|
directx Compiled with support for Direct-X and 'renderoptions'.
|
||||||
dnd Compiled with support for the "~ register |quote_~|.
|
dnd Compiled with support for the "~ register |quote_~|.
|
||||||
dos16 16 bits DOS version of Vim.
|
dos16 16 bits DOS version of Vim.
|
||||||
dos32 32 bits DOS (DJGPP) version of Vim.
|
dos32 32 bits DOS (DJGPP) version of Vim.
|
||||||
|
|||||||
@@ -5650,6 +5650,77 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
this option at the default "on". Only switch it off when working with
|
this option at the default "on". Only switch it off when working with
|
||||||
old Vi scripts.
|
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'*
|
||||||
'report' number (default 2)
|
'report' number (default 2)
|
||||||
global
|
global
|
||||||
|
|||||||
@@ -337,6 +337,7 @@ N *+dialog_con* Support for |:confirm| with console dialog.
|
|||||||
N *+dialog_con_gui* Support for |:confirm| with GUI and console dialog.
|
N *+dialog_con_gui* Support for |:confirm| with GUI and console dialog.
|
||||||
N *+diff* |vimdiff| and 'diff'
|
N *+diff* |vimdiff| and 'diff'
|
||||||
N *+digraphs* |digraphs| *E196*
|
N *+digraphs* |digraphs| *E196*
|
||||||
|
m *+directx* Win32 GUI only: DirectX and |'renderoptions'|
|
||||||
*+dnd* Support for DnD into the "~ register |quote_~|.
|
*+dnd* Support for DnD into the "~ register |quote_~|.
|
||||||
B *+emacs_tags* |emacs-tags| files
|
B *+emacs_tags* |emacs-tags| files
|
||||||
N *+eval* expression evaluation |eval.txt|
|
N *+eval* expression evaluation |eval.txt|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
# Cygwin application use the Makefile (just like on Unix).
|
# Cygwin application use the Makefile (just like on Unix).
|
||||||
#
|
#
|
||||||
# GUI no or yes: set to yes if you want the GUI version (yes)
|
# 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 define to path to Perl dir to get Perl support (not defined)
|
||||||
# PERL_VER define to version of Perl being used (56)
|
# 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)
|
# DYNAMIC_PERL no or yes: set to yes to load the Perl DLL dynamically (yes)
|
||||||
@@ -88,6 +89,10 @@ ifndef ARCH
|
|||||||
ARCH = i386
|
ARCH = i386
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef DIRECTX
|
||||||
|
DIRECTX = no
|
||||||
|
endif
|
||||||
|
|
||||||
ifndef WINVER
|
ifndef WINVER
|
||||||
WINVER = 0x0500
|
WINVER = 0x0500
|
||||||
endif
|
endif
|
||||||
@@ -469,6 +474,15 @@ endif
|
|||||||
|
|
||||||
endif
|
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
|
ifdef XPM
|
||||||
# Only allow XPM for a GUI build.
|
# Only allow XPM for a GUI build.
|
||||||
@@ -495,11 +509,7 @@ ifeq (yes, $(OLE))
|
|||||||
DEFINES += -DFEAT_OLE
|
DEFINES += -DFEAT_OLE
|
||||||
EXTRA_OBJS += $(OUTDIR)/if_ole.o
|
EXTRA_OBJS += $(OUTDIR)/if_ole.o
|
||||||
EXTRA_LIBS += -loleaut32
|
EXTRA_LIBS += -loleaut32
|
||||||
ifeq (yes, $(STATIC_STDCPLUS))
|
USE_STDCPLUS = yes
|
||||||
EXTRA_LIBS += -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
|
|
||||||
else
|
|
||||||
EXTRA_LIBS += -lstdc++
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
@@ -513,6 +523,15 @@ MKDIR = mkdir
|
|||||||
DIRSLASH = \\
|
DIRSLASH = \\
|
||||||
endif
|
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
|
#>>>>> end of choices
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
@@ -643,6 +662,9 @@ $(OUTDIR)/ex_eval.o: ex_eval.c $(INCL) ex_cmds.h
|
|||||||
$(OUTDIR)/gui_w32.o: gui_w32.c gui_w48.c $(INCL)
|
$(OUTDIR)/gui_w32.o: gui_w32.c gui_w48.c $(INCL)
|
||||||
$(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o
|
$(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
|
$(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h
|
||||||
$(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o
|
$(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ DEBUG=no
|
|||||||
OPTIMIZE=MAXSPEED
|
OPTIMIZE=MAXSPEED
|
||||||
# set to yes to make gvim, no for vim
|
# set to yes to make gvim, no for vim
|
||||||
GUI=yes
|
GUI=yes
|
||||||
|
# set to yes if you want to use DirectWrite (DirectX)
|
||||||
|
DIRECTX=no
|
||||||
# FEATURES=[TINY | SMALL | NORMAL | BIG | HUGE]
|
# FEATURES=[TINY | SMALL | NORMAL | BIG | HUGE]
|
||||||
# Set to TINY to make minimal version (few features).
|
# Set to TINY to make minimal version (few features).
|
||||||
FEATURES=BIG
|
FEATURES=BIG
|
||||||
@@ -456,6 +458,14 @@ endif
|
|||||||
endif
|
endif
|
||||||
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.
|
# Only allow XPM for a GUI build.
|
||||||
ifeq (yes, $(GUI))
|
ifeq (yes, $(GUI))
|
||||||
|
|
||||||
@@ -593,6 +603,14 @@ OBJ += $(OUTDIR)/netbeans.o
|
|||||||
LIB += -lwsock32
|
LIB += -lwsock32
|
||||||
endif
|
endif
|
||||||
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
|
ifdef XPM
|
||||||
# Only allow XPM for a GUI build.
|
# Only allow XPM for a GUI build.
|
||||||
ifeq (yes, $(GUI))
|
ifeq (yes, $(GUI))
|
||||||
@@ -650,11 +668,7 @@ endif
|
|||||||
ifeq (yes, $(OLE))
|
ifeq (yes, $(OLE))
|
||||||
LIB += -loleaut32
|
LIB += -loleaut32
|
||||||
OBJ += $(OUTDIR)/if_ole.o
|
OBJ += $(OUTDIR)/if_ole.o
|
||||||
ifeq (yes, $(STATIC_STDCPLUS))
|
USE_STDCPLUS = yes
|
||||||
LIB += -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
|
|
||||||
else
|
|
||||||
LIB += -lstdc++
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (yes, $(MBYTE))
|
ifeq (yes, $(MBYTE))
|
||||||
@@ -678,6 +692,14 @@ endif
|
|||||||
DEFINES+=-DDYNAMIC_ICONV
|
DEFINES+=-DDYNAMIC_ICONV
|
||||||
endif
|
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
|
all: $(TARGET) vimrun.exe xxd/xxd.exe install.exe uninstal.exe GvimExt/gvimext.dll
|
||||||
|
|
||||||
vimrun.exe: vimrun.c
|
vimrun.exe: vimrun.c
|
||||||
@@ -751,6 +773,9 @@ $(OUTDIR)/ex_eval.o: ex_eval.c $(INCL) ex_cmds.h
|
|||||||
$(OUTDIR)/gui_w32.o: gui_w32.c gui_w48.c $(INCL)
|
$(OUTDIR)/gui_w32.o: gui_w32.c gui_w48.c $(INCL)
|
||||||
$(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o
|
$(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
|
$(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h
|
||||||
$(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o
|
$(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
#
|
#
|
||||||
# GUI interface: GUI=yes (default is no)
|
# 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)
|
# OLE interface: OLE=yes (usually with GUI=yes)
|
||||||
#
|
#
|
||||||
# Multibyte support: MBYTE=yes (default is no)
|
# Multibyte support: MBYTE=yes (default is no)
|
||||||
@@ -168,6 +171,9 @@ OBJDIR = .\ObjG
|
|||||||
!else
|
!else
|
||||||
OBJDIR = .\ObjC
|
OBJDIR = .\ObjC
|
||||||
!endif
|
!endif
|
||||||
|
!if "$(DIRECTX)" == "yes"
|
||||||
|
OBJDIR = $(OBJDIR)X
|
||||||
|
!endif
|
||||||
!if "$(OLE)" == "yes"
|
!if "$(OLE)" == "yes"
|
||||||
OBJDIR = $(OBJDIR)O
|
OBJDIR = $(OBJDIR)O
|
||||||
!endif
|
!endif
|
||||||
@@ -292,6 +298,13 @@ NBDEBUG_SRC = nbdebug.c
|
|||||||
NETBEANS_LIB = WSock32.lib
|
NETBEANS_LIB = WSock32.lib
|
||||||
!endif
|
!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
|
!ifndef XPM
|
||||||
# XPM is not set, use the included xpm files, depending on the architecture.
|
# XPM is not set, use the included xpm files, depending on the architecture.
|
||||||
!if "$(CPU)" == "AMD64"
|
!if "$(CPU)" == "AMD64"
|
||||||
@@ -642,6 +655,12 @@ GUI_LIB = \
|
|||||||
SUBSYSTEM = console
|
SUBSYSTEM = console
|
||||||
!endif
|
!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)
|
# iconv.dll library (dynamically loaded)
|
||||||
!ifndef ICONV
|
!ifndef ICONV
|
||||||
ICONV = yes
|
ICONV = yes
|
||||||
@@ -1107,6 +1126,8 @@ $(OUTDIR)/gui_beval.obj: $(OUTDIR) gui_beval.c $(INCL) $(GUI_INCL)
|
|||||||
|
|
||||||
$(OUTDIR)/gui_w32.obj: $(OUTDIR) gui_w32.c gui_w48.c $(INCL) $(GUI_INCL)
|
$(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_cscope.obj: $(OUTDIR) if_cscope.c $(INCL)
|
||||||
|
|
||||||
$(OUTDIR)/if_lua.obj: $(OUTDIR) if_lua.c $(INCL)
|
$(OUTDIR)/if_lua.obj: $(OUTDIR) if_lua.c $(INCL)
|
||||||
|
|||||||
@@ -12464,6 +12464,9 @@ f_has(argvars, rettv)
|
|||||||
#ifdef FEAT_DIGRAPHS
|
#ifdef FEAT_DIGRAPHS
|
||||||
"digraphs",
|
"digraphs",
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FEAT_DIRECTX
|
||||||
|
"directx",
|
||||||
|
#endif
|
||||||
#ifdef FEAT_DND
|
#ifdef FEAT_DND
|
||||||
"dnd",
|
"dnd",
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
901
src/gui_dwrite.cpp
Normal file
901
src/gui_dwrite.cpp
Normal file
@@ -0,0 +1,901 @@
|
|||||||
|
/* vi:set ts=8 sts=4 sw=4 noet: */
|
||||||
|
/*
|
||||||
|
* Author: MURAOKA Taro <koron.kaoriya@gmail.com>
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* - Ken Takata
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 MURAOKA Taro <koron.kaoriya@gmail.com>
|
||||||
|
* 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 <windows.h>
|
||||||
|
#include <crtdbg.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <d2d1.h>
|
||||||
|
#include <d2d1helper.h>
|
||||||
|
#include <dwrite.h>
|
||||||
|
|
||||||
|
#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 <class T> 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<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,
|
||||||
|
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<void**>(&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<IUnknown**>(&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<float>(
|
||||||
|
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<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, 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<char*>("d2d1.dll"));
|
||||||
|
hDWriteDLL = vimLoadLib(const_cast<char*>("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;
|
||||||
|
}
|
||||||
85
src/gui_dwrite.h
Normal file
85
src/gui_dwrite.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/* vi:set ts=8 sts=4 sw=4 noet: */
|
||||||
|
/*
|
||||||
|
* Author: MURAOKA Taro <koron.kaoriya@gmail.com>
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* - Ken Takata
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 MURAOKA Taro <koron.kaoriya@gmail.com>
|
||||||
|
* 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*/
|
||||||
178
src/gui_w32.c
178
src/gui_w32.c
@@ -25,6 +25,145 @@
|
|||||||
|
|
||||||
#include "vim.h"
|
#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.
|
* These are new in Windows ME/XP, only defined in recent compilers.
|
||||||
*/
|
*/
|
||||||
@@ -1624,6 +1763,11 @@ gui_mch_init(void)
|
|||||||
set_vim_var_nr(VV_WINDOWID, HandleToLong(s_hwnd));
|
set_vim_var_nr(VV_WINDOWID, HandleToLong(s_hwnd));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FEAT_RENDER_OPTIONS
|
||||||
|
if (p_rop)
|
||||||
|
(void)gui_mch_set_rendering_options(p_rop);
|
||||||
|
#endif
|
||||||
|
|
||||||
theend:
|
theend:
|
||||||
/* Display any pending error messages */
|
/* Display any pending error messages */
|
||||||
display_errors();
|
display_errors();
|
||||||
@@ -2239,6 +2383,9 @@ gui_mch_draw_string(
|
|||||||
#endif
|
#endif
|
||||||
HPEN hpen, old_pen;
|
HPEN hpen, old_pen;
|
||||||
int y;
|
int y;
|
||||||
|
#ifdef FEAT_DIRECTX
|
||||||
|
int font_is_ttf_or_vector = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef MSWIN16_FASTTEXT
|
#ifndef MSWIN16_FASTTEXT
|
||||||
/*
|
/*
|
||||||
@@ -2326,6 +2473,20 @@ gui_mch_draw_string(
|
|||||||
SetTextColor(s_hdc, gui.currFgColor);
|
SetTextColor(s_hdc, gui.currFgColor);
|
||||||
SelectFont(s_hdc, gui.currFont);
|
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)
|
if (pad_size != Columns || padding == NULL || padding[0] != gui.char_width)
|
||||||
{
|
{
|
||||||
vim_free(padding);
|
vim_free(padding);
|
||||||
@@ -2360,6 +2521,14 @@ gui_mch_draw_string(
|
|||||||
if (text[n] >= 0x80)
|
if (text[n] >= 0x80)
|
||||||
break;
|
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
|
/* 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
|
* with the same length as the multi-byte string, the number of wide
|
||||||
* characters is always equal or smaller. */
|
* characters is always equal or smaller. */
|
||||||
@@ -2418,6 +2587,15 @@ gui_mch_draw_string(
|
|||||||
i += utfc_ptr2len_len(text + i, len - i);
|
i += utfc_ptr2len_len(text + i, len - i);
|
||||||
++clen;
|
++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),
|
ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row),
|
||||||
foptions, pcliprect, unicodebuf, wlen, unicodepdy);
|
foptions, pcliprect, unicodebuf, wlen, unicodepdy);
|
||||||
len = cells; /* used for underlining */
|
len = cells; /* used for underlining */
|
||||||
|
|||||||
@@ -2785,6 +2785,10 @@ _OnPaint(
|
|||||||
|
|
||||||
out_flush(); /* make sure all output has been processed */
|
out_flush(); /* make sure all output has been processed */
|
||||||
(void)BeginPaint(hwnd, &ps);
|
(void)BeginPaint(hwnd, &ps);
|
||||||
|
#if defined(FEAT_DIRECTX)
|
||||||
|
if (IS_ENABLE_DIRECTX())
|
||||||
|
DWriteContext_BeginDraw(s_dwc);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
/* prevent multi-byte characters from misprinting on an invalid
|
/* prevent multi-byte characters from misprinting on an invalid
|
||||||
@@ -2800,9 +2804,20 @@ _OnPaint(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!IsRectEmpty(&ps.rcPaint))
|
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,
|
gui_redraw(ps.rcPaint.left, ps.rcPaint.top,
|
||||||
ps.rcPaint.right - ps.rcPaint.left + 1,
|
ps.rcPaint.right - ps.rcPaint.left + 1,
|
||||||
ps.rcPaint.bottom - ps.rcPaint.top + 1);
|
ps.rcPaint.bottom - ps.rcPaint.top + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(FEAT_DIRECTX)
|
||||||
|
if (IS_ENABLE_DIRECTX())
|
||||||
|
DWriteContext_EndDraw(s_dwc);
|
||||||
|
#endif
|
||||||
EndPaint(hwnd, &ps);
|
EndPaint(hwnd, &ps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3043,6 +3058,12 @@ gui_mch_insert_lines(
|
|||||||
void
|
void
|
||||||
gui_mch_exit(int rc)
|
gui_mch_exit(int rc)
|
||||||
{
|
{
|
||||||
|
#if defined(FEAT_DIRECTX)
|
||||||
|
DWriteContext_Close(s_dwc);
|
||||||
|
DWrite_Final();
|
||||||
|
s_dwc = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
ReleaseDC(s_textArea, s_hdc);
|
ReleaseDC(s_textArea, s_hdc);
|
||||||
DeleteObject(s_brush);
|
DeleteObject(s_brush);
|
||||||
|
|
||||||
|
|||||||
17
src/option.c
17
src/option.c
@@ -2124,6 +2124,15 @@ static struct vimoption
|
|||||||
{"remap", NULL, P_BOOL|P_VI_DEF,
|
{"remap", NULL, P_BOOL|P_VI_DEF,
|
||||||
(char_u *)&p_remap, PV_NONE,
|
(char_u *)&p_remap, PV_NONE,
|
||||||
{(char_u *)TRUE, (char_u *)0L} SCRIPTID_INIT},
|
{(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,
|
{"report", NULL, P_NUM|P_VI_DEF,
|
||||||
(char_u *)&p_report, PV_NONE,
|
(char_u *)&p_report, PV_NONE,
|
||||||
{(char_u *)2L, (char_u *)0L} SCRIPTID_INIT},
|
{(char_u *)2L, (char_u *)0L} SCRIPTID_INIT},
|
||||||
@@ -6999,6 +7008,14 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
|
|||||||
}
|
}
|
||||||
#endif
|
#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. */
|
/* Options that are a list of flags. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -655,6 +655,9 @@ EXTERN long p_rdt; /* 'redrawtime' */
|
|||||||
#endif
|
#endif
|
||||||
EXTERN int p_remap; /* 'remap' */
|
EXTERN int p_remap; /* 'remap' */
|
||||||
EXTERN long p_re; /* 'regexpengine' */
|
EXTERN long p_re; /* 'regexpengine' */
|
||||||
|
#ifdef FEAT_RENDER_OPTIONS
|
||||||
|
EXTERN char_u *p_rop; /* 'renderoptions' */
|
||||||
|
#endif
|
||||||
EXTERN long p_report; /* 'report' */
|
EXTERN long p_report; /* 'report' */
|
||||||
#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
|
#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
|
||||||
EXTERN long p_pvh; /* 'previewheight' */
|
EXTERN long p_pvh; /* 'previewheight' */
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/* gui_w32.c */
|
/* 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_set_blinking __ARGS((long wait, long on, long off));
|
||||||
void gui_mch_stop_blink __ARGS((void));
|
void gui_mch_stop_blink __ARGS((void));
|
||||||
void gui_mch_start_blink __ARGS((void));
|
void gui_mch_start_blink __ARGS((void));
|
||||||
|
|||||||
@@ -189,6 +189,13 @@ static char *(features[]) =
|
|||||||
#else
|
#else
|
||||||
"-digraphs",
|
"-digraphs",
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FEAT_GUI_W32
|
||||||
|
# ifdef FEAT_DIRECTX
|
||||||
|
"+directx",
|
||||||
|
# else
|
||||||
|
"-directx",
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
#ifdef FEAT_DND
|
#ifdef FEAT_DND
|
||||||
"+dnd",
|
"+dnd",
|
||||||
#else
|
#else
|
||||||
@@ -734,6 +741,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
393,
|
||||||
/**/
|
/**/
|
||||||
392,
|
392,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@@ -134,6 +134,13 @@
|
|||||||
# endif
|
# endif
|
||||||
#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 */
|
/* Visual Studio 2005 has 'deprecated' many of the standard CRT functions */
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
# define _CRT_SECURE_NO_DEPRECATE
|
# define _CRT_SECURE_NO_DEPRECATE
|
||||||
|
|||||||
Reference in New Issue
Block a user