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); |
ちょいと私の考え&要求を以下にまとめます。
- このコードを書き起こすに当たって、参考にした資料(URLとか)ってあったら教えてください。
- CreateGdiCompatibleTextLayout を使わない理由を教えてください。(glyphAdvances に入ってくる値が使い物にならなくなるから、と推測しています)
このコードを書き起こすに当たって、参考にした資料(URLとか)ってあったら教えてください。
ないです。
CreateGdiCompatibleTextLayout を使わない理由を教えてください。
CreateGdiCompatibleTextLayout を使っても CreateTextLayout を使っても、glyphAdvances の値を上書きしてしまっているので、同じ結果になっているはずです。(少なくとも私には判別できませんでした。)
measuringMode の値が違っているかもしれませんので、サブピクセルレベルでは配置が異なっている可能性がありますが、未確認です。
本来は Layout のほうをカスタムしてやるんじゃないかなぁ、というのが直感。
そういうやり方を探してはいるのですが、見つかってないです。
あと offset_ に差 (delta) が蓄積してんだけど、
Yが異なる=不要な offset_ が適用されることは無いのかしら?
行が異なる場合はoffset_が0に初期化されるので問題ないです。
一回の textLayout->Draw() の呼び出しで、DrawGlyphRun() が複数回呼ばれるので、それを補正しているのが offset_ です。
GdiTextRendererContext を経由して参照したほうが良い。
今のままでは結合が強くなりすぎてる。
それはそうですね。
Thanks! んでは、続きは私の方で取り込んでみます。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
検証の結果、これは実質無さそう。
というのは DrawText が行単位でしか呼ばれておらず、
またDrawText の呼び出し1回に付き1つRendererを作っているから。