Created
November 23, 2017 03:17
-
-
Save k-takata/efbb8ddc7d6a6c930d2edcbdd1862799 to your computer and use it in GitHub Desktop.
Don't use bmpRT. Use mRT directly for DirectWrite.
This file contains hidden or 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.c b/src/gui.c | |
--- a/src/gui.c | |
+++ b/src/gui.c | |
@@ -2419,6 +2419,7 @@ gui_outstr_nowrap( | |
if (flags & GUI_MON_TRS_CURSOR) | |
draw_flags |= DRAW_TRANSP; | |
+ gui_mch_draw_string_start(); | |
/* | |
* Draw the text. | |
*/ | |
@@ -2558,6 +2559,7 @@ gui_outstr_nowrap( | |
# endif | |
} | |
#endif /* !FEAT_GUI_GTK */ | |
+ gui_mch_draw_string_end(); | |
if (!(flags & (GUI_MON_IS_CURSOR | GUI_MON_TRS_CURSOR))) | |
gui.col = col + len; | |
diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp | |
--- a/src/gui_dwrite.cpp | |
+++ b/src/gui_dwrite.cpp | |
@@ -232,14 +232,19 @@ class GdiTextRenderer FINAL : public IDW | |
{ | |
public: | |
GdiTextRenderer( | |
- IDWriteBitmapRenderTarget* bitmapRenderTarget, | |
- IDWriteRenderingParams* renderingParams) : | |
+ //IDWriteBitmapRenderTarget* bitmapRenderTarget, | |
+ ID2D1RenderTarget* renderTarget, | |
+ IDWriteRenderingParams* renderingParams, | |
+ ID2D1Brush* brush) : | |
cRefCount_(0), | |
- pRenderTarget_(bitmapRenderTarget), | |
- pRenderingParams_(renderingParams) | |
+ //pRenderTarget_(bitmapRenderTarget), | |
+ pRenderTarget_(renderTarget), | |
+ pRenderingParams_(renderingParams), | |
+ pBrush_(brush) | |
{ | |
pRenderTarget_->AddRef(); | |
pRenderingParams_->AddRef(); | |
+ pBrush_->AddRef(); | |
AddRef(); | |
} | |
@@ -248,6 +253,7 @@ public: | |
{ | |
SafeRelease(&pRenderTarget_); | |
SafeRelease(&pRenderingParams_); | |
+ SafeRelease(&pBrush_); | |
} | |
IFACEMETHOD(IsPixelSnappingDisabled)( | |
@@ -263,7 +269,9 @@ public: | |
__out DWRITE_MATRIX* transform) | |
{ | |
// forward the render target's transform | |
- pRenderTarget_->GetCurrentTransform(transform); | |
+ //pRenderTarget_->GetCurrentTransform(transform); | |
+ pRenderTarget_->GetTransform( | |
+ reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform)); | |
return S_OK; | |
} | |
@@ -271,7 +279,10 @@ public: | |
__maybenull void* clientDrawingContext, | |
__out FLOAT* pixelsPerDip) | |
{ | |
- *pixelsPerDip = pRenderTarget_->GetPixelsPerDip(); | |
+ //*pixelsPerDip = pRenderTarget_->GetPixelsPerDip(); | |
+ float x, yUnused; | |
+ pRenderTarget_->GetDpi(&x, &yUnused); | |
+ *pixelsPerDip = x / 96; | |
return S_OK; | |
} | |
@@ -294,14 +305,21 @@ public: | |
// 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, | |
+ //hr = pRenderTarget_->DrawGlyphRun( | |
+ // baselineOriginX + context->offsetX, | |
+ // baselineOriginY, | |
+ // measuringMode, | |
+ // &adjustedGlyphRun, | |
+ // pRenderingParams_, | |
+ // context->color, | |
+ // &dirtyRect); | |
+ D2D1_POINT_2F baselineOrigin = {baselineOriginX + context->offsetX, | |
+ baselineOriginY}; | |
+ pRenderTarget_->DrawGlyphRun( | |
+ baselineOrigin, | |
&adjustedGlyphRun, | |
- pRenderingParams_, | |
- context->color, | |
- &dirtyRect); | |
+ pBrush_, | |
+ DWRITE_MEASURING_MODE_NATURAL); | |
context->offsetX += adjustedGlyphRun.getDelta(); | |
@@ -385,8 +403,10 @@ public: | |
private: | |
long cRefCount_; | |
- IDWriteBitmapRenderTarget* pRenderTarget_; | |
+ //IDWriteBitmapRenderTarget* pRenderTarget_; | |
+ ID2D1RenderTarget* pRenderTarget_; | |
IDWriteRenderingParams* pRenderingParams_; | |
+ ID2D1Brush* pBrush_; | |
}; | |
struct DWriteContext { | |
@@ -422,9 +442,22 @@ struct DWriteContext { | |
void SetFont(const LOGFONTW &logFont); | |
- void DrawText(HDC hdc, const WCHAR* text, int len, | |
+ void DrawText(HWND hwnd, HDC hdc, const WCHAR* text, int len, | |
int x, int y, int w, int h, int cellWidth, COLORREF color); | |
+ void BindDC(HDC hdc, RECT *rect); | |
+ | |
+ void AssureDrawing(void); | |
+ | |
+ ID2D1Brush* SolidBrush(COLORREF color); | |
+ | |
+// void DrawText1(const WCHAR* text, int len, | |
+// int x, int y, int w, int h, COLORREF color); | |
+ | |
+ void FillRect(RECT *rc, COLORREF color); | |
+ | |
+ void Flush(void); | |
+ | |
float PixelsToDipsX(int x); | |
float PixelsToDipsY(int y); | |
@@ -663,11 +696,11 @@ DWriteContext::SetFont(const LOGFONTW &l | |
} | |
void | |
-DWriteContext::DrawText(HDC hdc, const WCHAR* text, int len, | |
+DWriteContext::DrawText(HWND hwnd, 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; | |
+ //IDWriteBitmapRenderTarget *bmpRT = NULL; | |
// Skip when any fonts are not set. | |
if (mTextFormat == NULL) | |
@@ -677,19 +710,51 @@ DWriteContext::DrawText(HDC hdc, const W | |
if (cellWidth == 0 || mDpiScaleX == 0.0f || mDpiScaleY == 0.0f) | |
return; | |
- if (SUCCEEDED(hr)) | |
- hr = mGdiInterop->CreateBitmapRenderTarget(hdc, w, h, &bmpRT); | |
+// 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); | |
+ mRT->SetDpi(mDpiScaleX * 96.0f, mDpiScaleY * 96.0f); | |
+ | |
+ //RECT rect = { x, y, x + w, y + h }; | |
+ RECT rect; | |
+ static RECT rcOld = {0}; | |
+ static HDC hdcOld = NULL; | |
+ GetClientRect(hwnd, &rect); | |
+ | |
+ //if (hdc != hdcOld || memcmp(&rect, &rcOld, sizeof(RECT)) != 0) | |
+ //{ | |
+ // mRT->BindDC(hdc, &rect); | |
+ // hdcOld = hdc; | |
+ // rcOld = rect; | |
+ //} | |
+ | |
+ //mRT->BeginDraw(); | |
+ | |
+ COLORREF rgb = GetTextColor(hdc); | |
- hr = mDWriteFactory->CreateGdiCompatibleTextLayout( | |
+ ID2D1SolidColorBrush* pBrush = NULL; | |
+ D2D1_COLOR_F colorBrush = { | |
+ GetRValue(rgb) / 255.0f, | |
+ GetGValue(rgb) / 255.0f, | |
+ GetBValue(rgb) / 255.0f, | |
+ 1.0f | |
+ }; | |
+ | |
+ mRT->CreateSolidColorBrush(colorBrush, &pBrush); | |
+ | |
+// 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); | |
+ hr = mDWriteFactory->CreateTextLayout( | |
text, len, mTextFormat, PixelsToDipsX(w), | |
- PixelsToDipsY(h), mDpiScaleX, NULL, TRUE, &textLayout); | |
+ PixelsToDipsY(h), &textLayout); | |
if (SUCCEEDED(hr)) | |
{ | |
@@ -700,25 +765,98 @@ DWriteContext::DrawText(HDC hdc, const W | |
if (SUCCEEDED(hr)) | |
{ | |
- GdiTextRenderer *renderer = new GdiTextRenderer(bmpRT, | |
- mRenderingParams); | |
+ GdiTextRenderer *renderer = new GdiTextRenderer(/*bmpRT*/mRT, | |
+ mRenderingParams, pBrush); | |
GdiTextRendererContext data = { | |
color, | |
PixelsToDipsX(cellWidth), | |
0.0f | |
}; | |
- textLayout->Draw(&data, renderer, 0, 0); | |
+ //textLayout->Draw(&data, renderer, 0, 0); | |
+ textLayout->Draw(&data, renderer, PixelsToDipsX(x), PixelsToDipsY(y)); | |
SafeRelease(&renderer); | |
} | |
- BitBlt(hdc, x, y, w, h, memdc, 0, 0, SRCCOPY); | |
+ //BitBlt(hdc, x, y, w, h, memdc, 0, 0, SRCCOPY); | |
+ | |
+ //mRT->EndDraw(); | |
SafeRelease(&textLayout); | |
+ SafeRelease(&pBrush); | |
} | |
- SafeRelease(&bmpRT); | |
+ //SafeRelease(&bmpRT); | |
+} | |
+ | |
+ void | |
+DWriteContext::BindDC(HDC hdc, RECT *rect) | |
+{ | |
+ Flush(); | |
+ mRT->BindDC(hdc, rect); | |
+ mRT->SetTransform(D2D1::IdentityMatrix()); | |
+} | |
+ | |
+ void | |
+DWriteContext::AssureDrawing(void) | |
+{ | |
+ if (mDrawing == false) | |
+ { | |
+ mRT->BeginDraw(); | |
+ mDrawing = true; | |
+ } | |
+} | |
+ | |
+ ID2D1Brush* | |
+DWriteContext::SolidBrush(COLORREF color) | |
+{ | |
+ mBrush->SetColor(D2D1::ColorF(UINT32(GetRValue(color)) << 16 | | |
+ UINT32(GetGValue(color)) << 8 | UINT32(GetBValue(color)))); | |
+ return mBrush; | |
} | |
+// void | |
+//DWriteContext::DrawText1(const WCHAR* text, int len, | |
+// int x, int y, int w, int h, COLORREF color) | |
+//{ | |
+// AssureDrawing(); | |
+// mBrush->SetColor(D2D1::ColorF(UINT32(GetRValue(color)) << 16 | | |
+// UINT32(GetGValue(color)) << 8 | UINT32(GetBValue(color)))); | |
+// mRT->DrawText(text, len, mTextFormat, | |
+// D2D1::RectF( | |
+// PixelsToDipsX(x), | |
+// PixelsToDipsY(y), | |
+// PixelsToDipsX(x + w), | |
+// PixelsToDipsY(y + h)), | |
+// SolidBrush(color), | |
+// (D2D1_DRAW_TEXT_OPTIONS)D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT); | |
+// if (mVersion == 2) | |
+// Flush(); | |
+//} | |
+ | |
+ void | |
+DWriteContext::FillRect(RECT *rc, COLORREF color) | |
+{ | |
+// if (mVersion == 1) | |
+// return; | |
+ AssureDrawing(); | |
+ mRT->FillRectangle( | |
+ D2D1::RectF( | |
+ PixelsToDipsX(rc->left), | |
+ PixelsToDipsY(rc->top), | |
+ PixelsToDipsX(rc->right), | |
+ PixelsToDipsY(rc->bottom)), | |
+ SolidBrush(color)); | |
+} | |
+ | |
+ void | |
+DWriteContext::Flush(void) | |
+{ | |
+ if (mDrawing) | |
+ { | |
+ mRT->EndDraw(); | |
+ mDrawing = false; | |
+ } | |
+} | |
float | |
DWriteContext::PixelsToDipsX(int x) | |
{ | |
@@ -838,11 +976,8 @@ DWriteContext_BeginDraw(DWriteContext *c | |
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); | |
- } | |
+ if (ctx != NULL) | |
+ ctx->BindDC(hdc, rect); | |
} | |
void | |
@@ -857,6 +992,7 @@ DWriteContext_SetFont(DWriteContext *ctx | |
void | |
DWriteContext_DrawText( | |
DWriteContext *ctx, | |
+ HWND hwnd, | |
HDC hdc, | |
const WCHAR* text, | |
int len, | |
@@ -867,8 +1003,8 @@ DWriteContext_DrawText( | |
int cellWidth, | |
COLORREF color) | |
{ | |
- if (ctx != NULL) | |
- ctx->DrawText(hdc, text, len, x, y, w, h, cellWidth, color); | |
+ if (ctx != NULL && ctx->mRT != NULL) | |
+ ctx->DrawText(hwnd, hdc, text, len, x, y, w, h, cellWidth, color); | |
} | |
void | |
@@ -882,6 +1018,20 @@ DWriteContext_EndDraw(DWriteContext *ctx | |
} | |
void | |
+DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color) | |
+{ | |
+ if (ctx != NULL) | |
+ ctx->FillRect(rc, color); | |
+} | |
+ | |
+ void | |
+DWriteContext_Flush(DWriteContext *ctx) | |
+{ | |
+ if (ctx != NULL) | |
+ ctx->Flush(); | |
+} | |
+ | |
+ void | |
DWriteContext_Close(DWriteContext *ctx) | |
{ | |
delete ctx; | |
diff --git a/src/gui_dwrite.h b/src/gui_dwrite.h | |
--- a/src/gui_dwrite.h | |
+++ b/src/gui_dwrite.h | |
@@ -59,6 +59,7 @@ void DWriteContext_BindDC(DWriteContext | |
void DWriteContext_SetFont(DWriteContext *ctx, HFONT hFont); | |
void DWriteContext_DrawText( | |
DWriteContext *ctx, | |
+ HWND hwnd, | |
HDC hdc, | |
const WCHAR* text, | |
int len, | |
@@ -69,6 +70,8 @@ void DWriteContext_DrawText( | |
int cellWidth, | |
COLORREF color); | |
void DWriteContext_EndDraw(DWriteContext *ctx); | |
+void DWriteContext_FillRect(DWriteContext *ctx, RECT *rc, COLORREF color); | |
+void DWriteContext_Flush(DWriteContext *ctx); | |
void DWriteContext_Close(DWriteContext *ctx); | |
void DWriteContext_SetRenderingParams( | |
diff --git a/src/gui_w32.c b/src/gui_w32.c | |
--- a/src/gui_w32.c | |
+++ b/src/gui_w32.c | |
@@ -2858,10 +2858,10 @@ gui_mch_show_popupmenu_at(vimmenu_T *men | |
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 | |
+//#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 | |
@@ -2878,19 +2878,19 @@ gui_mch_show_popupmenu_at(vimmenu_T *men | |
if (!IsRectEmpty(&ps.rcPaint)) | |
{ | |
-#if defined(FEAT_DIRECTX) | |
- if (IS_ENABLE_DIRECTX()) | |
- DWriteContext_BindDC(s_dwc, s_hdc, &ps.rcPaint); | |
-#endif | |
+//#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 | |
+//#if defined(FEAT_DIRECTX) | |
+// if (IS_ENABLE_DIRECTX()) | |
+// DWriteContext_EndDraw(s_dwc); | |
+//#endif | |
EndPaint(hwnd, &ps); | |
} | |
} | |
@@ -6127,6 +6127,29 @@ RevOut( HDC s_hdc, | |
#endif | |
void | |
+gui_mch_draw_string_start(void) | |
+{ | |
+#if defined(FEAT_DIRECTX) | |
+ if (IS_ENABLE_DIRECTX()) | |
+ { | |
+ RECT rc; | |
+ GetClientRect(s_hwnd, &rc); | |
+ DWriteContext_BindDC(s_dwc, s_hdc, &rc); | |
+ DWriteContext_BeginDraw(s_dwc); | |
+ } | |
+#endif | |
+} | |
+ | |
+ void | |
+gui_mch_draw_string_end(void) | |
+{ | |
+#if defined(FEAT_DIRECTX) | |
+ if (IS_ENABLE_DIRECTX()) | |
+ DWriteContext_EndDraw(s_dwc); | |
+#endif | |
+} | |
+ | |
+ void | |
gui_mch_draw_string( | |
int row, | |
int col, | |
@@ -6210,6 +6233,12 @@ gui_mch_draw_string( | |
hbr = hbr_cache[brush_lru]; | |
brush_lru = !brush_lru; | |
} | |
+ | |
+#if defined(FEAT_DIRECTX) | |
+ if (IS_ENABLE_DIRECTX()) | |
+ DWriteContext_FillRect(s_dwc, &rc, gui.currBgColor); | |
+#endif | |
+ | |
FillRect(s_hdc, &rc, hbr); | |
SetBkMode(s_hdc, TRANSPARENT); | |
@@ -6352,7 +6381,7 @@ gui_mch_draw_string( | |
if (IS_ENABLE_DIRECTX() && font_is_ttf_or_vector) | |
{ | |
/* Add one to "cells" for italics. */ | |
- DWriteContext_DrawText(s_dwc, s_hdc, unicodebuf, wlen, | |
+ DWriteContext_DrawText(s_dwc, s_hwnd, s_hdc, unicodebuf, wlen, | |
TEXT_X(col), TEXT_Y(row), FILL_X(cells + 1), FILL_Y(1), | |
gui.char_width, gui.currFgColor); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment