Skip to content

Instantly share code, notes, and snippets.

@k-takata
Created November 23, 2017 03:17
Show Gist options
  • Save k-takata/efbb8ddc7d6a6c930d2edcbdd1862799 to your computer and use it in GitHub Desktop.
Save k-takata/efbb8ddc7d6a6c930d2edcbdd1862799 to your computer and use it in GitHub Desktop.
Don't use bmpRT. Use mRT directly for DirectWrite.
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