Created
January 16, 2013 12:36
-
-
Save k-takata/4546842 to your computer and use it in GitHub Desktop.
additional patch No.5 for vim-kaoriya-vim-mq-ex / patch-direct_write.diff (Use GDI compatible layouts.)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp | |
--- a/src/gui_dwrite.cpp | |
+++ b/src/gui_dwrite.cpp | |
@@ -14,6 +14,10 @@ | |
#include "gui_dwrite.h" | |
+extern "C" { | |
+#include "vim.h" | |
+} | |
+ | |
#ifdef __MINGW32__ | |
# define __maybenull SAL__maybenull | |
# define __in SAL__in | |
@@ -39,10 +43,13 @@ | |
public: | |
GdiTextRenderer( | |
IDWriteBitmapRenderTarget* bitmapRenderTarget, | |
- IDWriteRenderingParams* renderingParams) : | |
+ IDWriteRenderingParams* renderingParams, | |
+ FLOAT dpiScaleX) : | |
cRefCount_(0), | |
pRenderTarget_(bitmapRenderTarget), | |
- pRenderingParams_(renderingParams) | |
+ pRenderingParams_(renderingParams), | |
+ dpiScaleX_(dpiScaleX), | |
+ offset_(0.0) | |
{ | |
pRenderTarget_->AddRef(); | |
pRenderingParams_->AddRef(); | |
@@ -97,14 +104,31 @@ | |
// Pass on the drawing call to the render target to do the real work. | |
RECT dirtyRect = {0}; | |
+ // Adjust glyphAdvances and baselineOriginX to fit with the layout of | |
+ // GDI. Using CreateGdiCompatibleTextLayout() is not enough. | |
+ DWRITE_GLYPH_RUN glyphRunAdj = *glyphRun; | |
+ FLOAT* glyphAdvances = new FLOAT[glyphRun->glyphCount]; | |
+ glyphRunAdj.glyphAdvances = glyphAdvances; | |
+ FLOAT delta = 0.0; | |
+ for (int i = 0; i < glyphRun->glyphCount; i++) { | |
+ if (glyphRun->glyphAdvances[i] > gui.char_width * 1.5 / dpiScaleX_) | |
+ glyphAdvances[i] = gui.char_width * 2 / dpiScaleX_; | |
+ else | |
+ glyphAdvances[i] = gui.char_width / dpiScaleX_; | |
+ delta += glyphAdvances[i] - glyphRun->glyphAdvances[i]; | |
+ } | |
+ | |
hr = pRenderTarget_->DrawGlyphRun( | |
- baselineOriginX, | |
+ baselineOriginX + offset_, | |
baselineOriginY, | |
measuringMode, | |
- glyphRun, | |
+ &glyphRunAdj, | |
pRenderingParams_, | |
context->color, | |
&dirtyRect); | |
+ offset_ += delta; | |
+ | |
+ delete [] glyphAdvances; | |
return hr; | |
} | |
@@ -188,6 +212,8 @@ | |
unsigned long cRefCount_; | |
IDWriteBitmapRenderTarget* pRenderTarget_; | |
IDWriteRenderingParams* pRenderingParams_; | |
+ FLOAT dpiScaleX_; | |
+ FLOAT offset_; | |
}; | |
struct DWriteContext { | |
@@ -477,9 +503,15 @@ | |
HDC memdc = bmpRT->GetMemoryDC(); | |
BitBlt(memdc, 0, 0, w, h, hdc, x, y, SRCCOPY); | |
+#if 1 | |
+ hr = mDWriteFactory->CreateTextLayout( | |
+ text, len, mTextFormat, static_cast<FLOAT>(w), | |
+ static_cast<FLOAT>(h), &textLayout); | |
+#else | |
hr = mDWriteFactory->CreateGdiCompatibleTextLayout( | |
text, len, mTextFormat, static_cast<FLOAT>(w), | |
static_cast<FLOAT>(h), mDpiScaleX, NULL, TRUE, &textLayout); | |
+#endif | |
if (SUCCEEDED(hr)) | |
{ | |
@@ -493,7 +525,7 @@ | |
if (SUCCEEDED(hr)) | |
{ | |
GdiTextRenderer *renderer = new GdiTextRenderer(bmpRT, | |
- mRenderingParams); | |
+ mRenderingParams, mDpiScaleX); | |
GdiTextRendererContext data = { color }; | |
textLayout->Draw(&data, renderer, 0, 0); | |
SafeRelease(&renderer); |
GdiTextRendererContext を経由して参照したほうが良い。
今のままでは結合が強くなりすぎてる。
それはそうですね。
Thanks! んでは、続きは私の方で取り込んでみます。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ないです。
CreateGdiCompatibleTextLayout を使っても CreateTextLayout を使っても、glyphAdvances の値を上書きしてしまっているので、同じ結果になっているはずです。(少なくとも私には判別できませんでした。)
measuringMode の値が違っているかもしれませんので、サブピクセルレベルでは配置が異なっている可能性がありますが、未確認です。
そういうやり方を探してはいるのですが、見つかってないです。
行が異なる場合はoffset_が0に初期化されるので問題ないです。
一回の textLayout->Draw() の呼び出しで、DrawGlyphRun() が複数回呼ばれるので、それを補正しているのが offset_ です。