forked from rutice/NicoJK
-
Notifications
You must be signed in to change notification settings - Fork 7
/
CommentWindow.h
184 lines (180 loc) · 5.25 KB
/
CommentWindow.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#pragma once
#include "OsdCompositor.h"
#include <atomic>
#include <thread>
namespace Gdiplus
{
class Bitmap;
class Graphics;
}
class CCommentWindow
{
public:
static const int DEFAULT_LINE_COUNT = 14;
static const int DEFAULT_LINE_DRAW_COUNT = 9999;
static const int DISPLAY_DURATION = 4000;
// 表示すべきコメントがないときウィンドウを非表示にするまでの猶予[秒]
// (レイヤードウィンドウは被せているだけでもそれなりのコストがかかるため)
static const int AUTOHIDE_DELAY = 10;
static const int FONT_SMALL_RATIO = 75;
// テクスチャ用ビットマップの幅の最小値(メモリや局所参照性の面で十分小さな値)
static const int TEXTURE_BITMAP_WIDTH_MIN = 640;
enum CHAT_POSITION {
CHAT_POS_DEFAULT,
CHAT_POS_SHITA,
CHAT_POS_UE,
};
enum CHAT_SIZE {
CHAT_SIZE_DEFAULT,
CHAT_SIZE_SMALL,
};
enum CHAT_ALIGN {
CHAT_ALIGN_CENTER,
CHAT_ALIGN_LEFT,
CHAT_ALIGN_RIGHT,
};
bool Initialize(HINSTANCE hinst, bool *pbEnableOsdCompositor, bool bSetHookOsdCompositor);
void Finalize();
CCommentWindow();
~CCommentWindow();
bool Create(HWND hwndParent);
void Destroy();
void SetStyle(LPCTSTR fontName, LPCTSTR fontNameMulti, LPCTSTR fontNameEmoji, bool bBold, bool bAntiAlias,
int fontOutline, bool bUseOsdCompositor, bool bUseTexture, bool bUseDrawingThread);
void SetCommentSize(int size, int sizeMin, int sizeMax, int lineMargin);
void SetDrawLineCount(int lineDrawCount);
int GetDisplayDuration() const { return displayDuration_; }
void SetDisplayDuration(int duration);
BYTE GetOpacity() const { return opacity_; }
void SetOpacity(BYTE opacity);
void SetDebugFlags(int debugFlags);
void OnParentMove();
void OnParentSize();
void AddChat(LPCTSTR text, COLORREF color, COLORREF shadowColor, CHAT_POSITION position, CHAT_SIZE size = CHAT_SIZE_DEFAULT,
CHAT_ALIGN align = CHAT_ALIGN_CENTER, bool bInsertLast = false, BYTE backOpacity = 0, int delay = 0);
void ScatterLatestChats(int duration);
void ClearChat();
void Forward(int duration);
void Update();
bool IsCreated() const { return hwnd_ != nullptr; }
void OnFilterGraphInitialized(IGraphBuilder *pGraphBuilder) { osdCompositor_.OnFilterGraphInitialized(pGraphBuilder); }
void OnFilterGraphFinalize(IGraphBuilder *pGraphBuilder) { osdCompositor_.OnFilterGraphFinalize(pGraphBuilder); }
private:
struct CHAT {
DWORD pts;
DWORD count;
int line;
BYTE colorB;
BYTE colorG;
BYTE colorR;
BYTE colorA;
BYTE shadowColorB;
BYTE shadowColorG;
BYTE shadowColorR;
CHAT_POSITION position;
bool bSmall;
BYTE alignFactor;
bool bInsertLast;
bool bMultiLine;
bool bDrew;
int currentDrawWidth;
int currentDrawHeight;
tstring text;
};
struct TEXTURE {
bool bUsed;
bool bSmall;
RECT rc;
BYTE colorB;
BYTE colorG;
BYTE colorR;
BYTE colorA;
BYTE shadowColorB;
BYTE shadowColorG;
BYTE shadowColorR;
tstring text;
bool IsMatch(const CHAT &c) const {
return c.colorB == colorB &&
c.colorG == colorG &&
c.colorR == colorR &&
c.colorA == colorA &&
c.shadowColorB == shadowColorB &&
c.shadowColorG == shadowColorG &&
c.shadowColorR == shadowColorR &&
c.bSmall == bSmall &&
c.text == text;
}
void AssignAttributes(const CHAT &c) {
colorB = c.colorB;
colorG = c.colorG;
colorR = c.colorR;
colorA = c.colorA;
shadowColorB = c.shadowColorB;
shadowColorG = c.shadowColorG;
shadowColorR = c.shadowColorR;
bSmall = c.bSmall;
text = c.text;
}
};
bool AllocateWorkBitmap(int width, int height, bool *pbRealloc);
bool IsParentSized();
void UpdateLayeredWindow();
void DrawingThread();
bool WaitForIdleDrawingThread();
void UpdateChat();
static BOOL CALLBACK UpdateCallback(void *pBits, const RECT *pSurfaceRect, int pitch, void *pClientData);
void DrawChat(Gdiplus::Graphics &g, int width, int height, RECT *prcUnused, RECT *prcUnusedWoShita, bool *pbHasFirstDrawShita);
static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HINSTANCE hinst_;
ULONG_PTR gdiplusToken_;
bool bSse2Available_;
HWND hwnd_;
HWND hwndParent_;
HBITMAP hbmWork_;
void *pBits_;
HDC hdcWork_;
std::thread drawingThread_;
HANDLE hDrawingEvent_;
HANDLE hDrawingIdleEvent_;
std::atomic_bool bQuitDrawingThread_;
int commentSizeMin_;
int commentSizeMax_;
int lineCount_;
double lineDrawCount_;
double fontScale_;
double fontSmallScale_;
TCHAR fontName_[LF_FACESIZE];
TCHAR fontNameMulti_[LF_FACESIZE];
TCHAR fontNameEmoji_[LF_FACESIZE];
int fontStyle_;
bool bAntiAlias_;
BYTE opacity_;
int fontOutline_;
int displayDuration_;
DWORD rts_;
DWORD chatCount_;
int currentWindowWidth_;
std::list<CHAT> chatList_;
std::list<CHAT> chatPoolList_;
// chatList_(リスト構造のみ),chatPoolList_を保護
recursive_mutex_ chatLock_;
int autoHideCount_;
int parentSizedCount_;
RECT rcParent_;
RECT rcOsdSurface_;
COsdCompositor osdCompositor_;
bool bUseOsd_;
bool bShowOsd_;
bool bUseTexture_;
bool bUseDrawingThread_;
Gdiplus::Bitmap *pTextureBitmap_;
Gdiplus::Graphics *pgTexture_;
int currentTextureHeight_;
std::list<TEXTURE> textureList_;
RECT rcUnused_;
RECT rcUnusedWoShita_;
RECT rcUnusedIntersect_;
RECT rcDirty_;
bool bForceRefreshDirty_;
int debugFlags_;
};