Skip to content

Commit

Permalink
minimal integration of direct2d and directwrite
Browse files Browse the repository at this point in the history
  • Loading branch information
fanlumaster committed Jan 27, 2025
1 parent 2547b90 commit f29d6ad
Show file tree
Hide file tree
Showing 12 changed files with 239 additions and 10 deletions.
1 change: 1 addition & 0 deletions .clangd
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CompileFlags:
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\IMECodes\\DeerWritingBrush\\src\\Composition",
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\IMECodes\\DeerWritingBrush\\src\\DictEngine",
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\IMECodes\\DeerWritingBrush\\src\\DisplayAttribute",
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\IMECodes\\DeerWritingBrush\\src\\Drawing",
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\IMECodes\\DeerWritingBrush\\src\\Edit",
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\IMECodes\\DeerWritingBrush\\src\\File",
"-IC:\\Users\\SonnyCalcr\\EDisk\\CppCodes\\IMECodes\\DeerWritingBrush\\src\\Global",
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ include_directories("./src/Compartment")
include_directories("./src/Composition")
include_directories("./src/DictEngine")
include_directories("./src/DisplayAttribute")
include_directories("./src/Drawing")
include_directories("./src/Edit")
include_directories("./src/File")
include_directories("./src/Global")
Expand Down Expand Up @@ -72,6 +73,9 @@ add_library(DeerWritingBrush SHARED
"./src/DisplayAttribute/DisplayString.h"
"./src/DisplayAttribute/EnumDisplayAttributeInfo.cpp"
"./src/DisplayAttribute/EnumDisplayAttributeInfo.h"
# Drawing
"./src/Drawing/D2DSource.cpp"
"./src/Drawing/D2DSource.h"
# Edit
"./src/Edit/EditSession.cpp"
"./src/Edit/EditSession.h"
Expand Down
62 changes: 62 additions & 0 deletions scripts/lcompile.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# generate and compile exe files
# 默认是编译 64 位的 dll,如果指定 32 位,则编译 32 位 dll
$currentDirectory = Get-Location
$cmakeListsPath = Join-Path -Path $currentDirectory -ChildPath "CMakeLists.txt"

if (-not (Test-Path $cmakeListsPath))
{
Write-Host("No CMakeLists.txt in current directory, please check.")
return
}

Write-Host "Start generating and compiling..."


$arch = $args[0]

if ($arch -eq "32")
{
$buildFolderPath = ".\build32"

if (-not (Test-Path $buildFolderPath))
{
New-Item -ItemType Directory -Path $buildFolderPath | Out-Null
Write-Host "build32 folder created."
}
cmake -G "Visual Studio 17 2022" -A Win32 -S . -B ./build32/

if ($LASTEXITCODE -eq 0)
{
cmake --build ./build32/ --config DEBUG
}
} elseif ($arch -eq "64")
{
$buildFolderPath = ".\build64"

if (-not (Test-Path $buildFolderPath))
{
New-Item -ItemType Directory -Path $buildFolderPath | Out-Null
Write-Host "build64 folder created."
}
cmake -G "Visual Studio 17 2022" -A x64 -S . -B ./build64/

if ($LASTEXITCODE -eq 0)
{
cmake --build ./build64/ --config DEBUG
}
} else
{ # 默认是 64 位
$buildFolderPath = ".\build64"

if (-not (Test-Path $buildFolderPath))
{
New-Item -ItemType Directory -Path $buildFolderPath | Out-Null
Write-Host "build64 folder created."
}
cmake -G "Visual Studio 17 2022" -A x64 -S . -B ./build64/

if ($LASTEXITCODE -eq 0)
{
cmake --build ./build64/ --config DEBUG
}
}
2 changes: 1 addition & 1 deletion src/Candidate/CandidateListUIPresenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ HRESULT CSampleIME::_HandleCandidateWorker(TfEditCookie ec, _In_ ITfContext *pCo
candidateString.Set(pCandidateString, candidateLen);

BOOL fMakePhraseFromText = _pCompositionProcessorEngine->IsMakePhraseFromText();
if (fMakePhraseFromText)
if (fMakePhraseFromText) // NOTICE: always no
{
_pCompositionProcessorEngine->GetCandidateStringInConverted(candidateString, &candidatePhraseList);
LCID locale = _pCompositionProcessorEngine->GetLocale();
Expand Down
88 changes: 88 additions & 0 deletions src/Drawing/D2DSource.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "D2DSource.h"
#include "Define.h"

void Direct2DSource::CreateGlobalD2DResources()
{

if (!pD2DFactory)
{
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
}

if (!pDWriteFactory)
{
DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
reinterpret_cast<IUnknown **>(&pDWriteFactory));
}

if (!pTextFormat)
{
pDWriteFactory->CreateTextFormat(SAMPLEIME_FONT_DEFAULT, nullptr, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 16.0f,
SAMPLEIME_LOCALE_DEFAULT, &pTextFormat);
}
}

void Direct2DSource::ReleaseGlobalD2DResources()
{

if (pD2DFactory)
pD2DFactory->Release();
if (pDWriteFactory)
pDWriteFactory->Release();
if (pTextFormat)
pTextFormat->Release();

pD2DFactory = nullptr;
pDWriteFactory = nullptr;
pTextFormat = nullptr;
}

void Direct2DSource::CreateWindowD2DResources(HWND hwnd)
{
if (!pRenderTarget)
{
RECT rc;
GetClientRect(hwnd, &rc);
pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hwnd, D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)),
&pRenderTarget);
pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &pBrush);
}
}

void Direct2DSource::ReleaseWindowD2DResources()
{
if (pRenderTarget)
pRenderTarget->Release();
if (pBrush)
pBrush->Release();

pRenderTarget = nullptr;
pBrush = nullptr;
}

void Direct2DSource::DrawWithDirect2D(HWND hwnd)
{
if (!pRenderTarget || !pTextFormat)
return;

pRenderTarget->BeginDraw();
// RGB(25, 25, 25)
pRenderTarget->Clear(D2D1::ColorF(25.0f / 255.0f, 25.0f / 255.0f, 25.0f / 255.0f));

// set brush color
pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &pBrush);
// draw text
pRenderTarget->DrawText(L"毛笔", 2, pTextFormat, D2D1::RectF(2, 2, 100, 100), pBrush);

HRESULT hr = pRenderTarget->EndDraw();
if (hr == D2DERR_RECREATE_TARGET)
{
ReleaseGlobalD2DResources();
ReleaseWindowD2DResources();
CreateGlobalD2DResources();
CreateWindowD2DResources(hwnd);
}
}
30 changes: 30 additions & 0 deletions src/Drawing/D2DSource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <d2d1.h>
#include <dwrite.h>

#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "dwrite.lib")

struct Direct2DSource
{
ID2D1Factory *pD2DFactory = nullptr;
ID2D1HwndRenderTarget *pRenderTarget = nullptr;
ID2D1SolidColorBrush *pBrush = nullptr;
IDWriteFactory *pDWriteFactory = nullptr;
IDWriteTextFormat *pTextFormat = nullptr;

//
// pD2DFactory, pDWriteFactory, pTextFormat
//
void CreateGlobalD2DResources();
void ReleaseGlobalD2DResources();

//
// pRenderTarget, pBrush
//
void CreateWindowD2DResources(HWND hwnd);
void ReleaseWindowD2DResources();

void DrawWithDirect2D(HWND hwnd);
};
4 changes: 4 additions & 0 deletions src/Global/Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <iostream>
#include <string>
#include "FanDictionaryDbUtils.h"
#include "D2DSource.h"

void DllAddRef();
void DllRelease();
Expand Down Expand Up @@ -176,4 +177,7 @@ std::string wstring_to_string(const std::wstring &wstr);
inline std::vector<FanDictionaryDb::DbWordItem> CandidateList;
inline std::vector<std::wstring> WStringCandidateList;
inline std::wstring FindKeyCode;

// Direct2D
inline Direct2DSource D2DSource;
} // namespace Global
1 change: 1 addition & 0 deletions src/Header/Define.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define IME_PUNCTUATION_OFF_INDEX IDI_PUNCTUATION_OFF

#define SAMPLEIME_FONT_DEFAULT L"Microsoft YaHei UI"
#define SAMPLEIME_LOCALE_DEFAULT L"zh-CN"

//---------------------------------------------------------------------
// defined Candidated Window
Expand Down
6 changes: 6 additions & 0 deletions src/IME/SampleIME.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "CandidateListUIPresenter.h"
#include "CompositionProcessorEngine.h"
#include "Compartment.h"
#include "D2DSource.h"

//+---------------------------------------------------------------------------
//
Expand Down Expand Up @@ -265,6 +266,8 @@ STDAPI CSampleIME::ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, D
goto ExitError;
}

Global::D2DSource.CreateGlobalD2DResources();

return S_OK;

ExitError:
Expand Down Expand Up @@ -340,6 +343,9 @@ STDAPI CSampleIME::Deactivate()
_pDocMgrLastFocused = nullptr;
}

Global::D2DSource.ReleaseGlobalD2DResources();
Global::D2DSource.ReleaseWindowD2DResources();

return S_OK;
}

Expand Down
5 changes: 5 additions & 0 deletions src/Window/BaseWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ class CBaseWindow
return _wndHandle;
}

void _SetWnd(_In_ HWND wndHandle)
{
_wndHandle = wndHandle;
}

CBaseWindow *_GetParent()
{
return _pParentWnd;
Expand Down
45 changes: 36 additions & 9 deletions src/Window/CandidateWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,31 @@ BOOL CCandidateWindow::_Create(ATOM atom, _In_ UINT wndWidth, _In_opt_ HWND pare
goto Exit;
}

// ret = _CreateVScrollWindow();
// if (FALSE == ret)
// {
// goto Exit;
// }
//
// Create D2D target
//
Global::D2DSource.CreateWindowD2DResources(this->_GetWnd());

_ResizeWindow();

Exit:
return TRUE;
}

void CCandidateWindow::_Destroy()
{
if (this->_GetWnd() != nullptr)
{
DestroyWindow(this->_GetWnd());
this->_SetWnd(nullptr);
}

//
// Release D2D target
//
Global::D2DSource.ReleaseWindowD2DResources();
}

BOOL CCandidateWindow::_CreateMainWindow(ATOM atom, _In_opt_ HWND parentWndHandle)
{
_SetUIWnd(this);
Expand Down Expand Up @@ -266,11 +279,25 @@ LRESULT CALLBACK CCandidateWindow::_WindowProcCallback(_In_ HWND wndHandle, UINT
case WM_PAINT: {
HDC dcHandle = nullptr;
PAINTSTRUCT ps;
if (Global::D2DSource.pRenderTarget)
{
// 释放旧的渲染目标
Global::D2DSource.pRenderTarget->Release();
Global::D2DSource.pRenderTarget = nullptr;
}

dcHandle = BeginPaint(wndHandle, &ps);
_OnPaint(dcHandle, &ps);
_DrawBorder(wndHandle, CANDWND_BORDER_WIDTH * 2);
EndPaint(wndHandle, &ps);
// 创建新的渲染目标
RECT rc;
GetClientRect(this->_GetWnd(), &rc);
Global::D2DSource.pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(this->_GetWnd(), D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)),
&Global::D2DSource.pRenderTarget);
Global::D2DSource.DrawWithDirect2D(this->_GetWnd());
// dcHandle = BeginPaint(wndHandle, &ps);
// _OnPaint(dcHandle, &ps);
// _DrawBorder(wndHandle, CANDWND_BORDER_WIDTH * 2);
// EndPaint(wndHandle, &ps);
}
return 0;

Expand Down
1 change: 1 addition & 0 deletions src/Window/CandidateWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class CCandidateWindow : public CBaseWindow
virtual ~CCandidateWindow();

BOOL _Create(ATOM atom, _In_ UINT wndWidth, _In_opt_ HWND parentWndHandle);
void _Destroy();

void _Move(int x, int y);
void _Show(BOOL isShowWnd);
Expand Down

0 comments on commit f29d6ad

Please sign in to comment.