1 #include "stdafx.h"
2 #include "CUIDrawer.h"
3 #include "MusicPlayer2.h"
4 #include "Player.h"
5
CUIDrawer(UIColors & colors)6 CUIDrawer::CUIDrawer(UIColors& colors)
7 : m_colors(colors)
8 {
9 }
10
11
~CUIDrawer()12 CUIDrawer::~CUIDrawer()
13 {
14 }
15
SetLyricFont(CFont * lyric_font,CFont * lyric_tr_font)16 void CUIDrawer::SetLyricFont(CFont* lyric_font, CFont* lyric_tr_font)
17 {
18 m_lyric_font = lyric_font;
19 m_lyric_tr_font = lyric_tr_font;
20 }
21
DrawLryicCommon(CRect rect,Alignment align,bool show_song_info)22 void CUIDrawer::DrawLryicCommon(CRect rect, Alignment align, bool show_song_info)
23 {
24 DrawAreaGuard guard(this, rect);
25 static int flag{};
26 if (!IsDrawMultiLine(rect.Height()))
27 DrawLyricTextSingleLine(rect, flag, true, align, show_song_info);
28 else
29 DrawLyricTextMultiLine(rect, align, show_song_info);
30 }
31
GetLyricTextHeight() const32 int CUIDrawer::GetLyricTextHeight() const
33 {
34 //计算文本高度
35 CFont* pOldFont = m_pDC->SelectObject(m_lyric_font);
36 int height = m_pDC->GetTextExtent(L"文").cy;
37 m_pDC->SelectObject(pOldFont);
38 return height; //根据当前的字体设置计算文本的高度
39 }
40
Create(CDC * pDC,CFont * pFont)41 void CUIDrawer::Create(CDC* pDC, CFont* pFont)
42 {
43 CDrawCommon::Create(pDC, pFont);
44 }
45
IsDrawMultiLine(int height) const46 bool CUIDrawer::IsDrawMultiLine(int height) const
47 {
48 return height >= static_cast<int>(GetLyricTextHeight() * 3.5);
49 }
50
SetForCortanaLyric(bool for_cortana_lyric)51 void CUIDrawer::SetForCortanaLyric(bool for_cortana_lyric)
52 {
53 m_for_cortana_lyric = for_cortana_lyric;
54 }
55
DrawLyricTextMultiLine(CRect lyric_area,Alignment align,bool show_song_info)56 void CUIDrawer::DrawLyricTextMultiLine(CRect lyric_area, Alignment align, bool show_song_info)
57 {
58 // AUTO时多行歌词居中显示
59 if (align == Alignment::AUTO) align = Alignment::CENTER;
60
61 int line_space{};
62 if (m_for_cortana_lyric)
63 {
64 line_space = theApp.DPI(4);
65 }
66 else
67 {
68 line_space = theApp.m_lyric_setting_data.lyric_line_space;
69 if (theApp.m_ui_data.full_screen)
70 line_space = static_cast<int>(line_space * CONSTVAL::FULL_SCREEN_ZOOM_FACTOR);
71 }
72
73 int lyric_height = GetLyricTextHeight() + line_space; //文本高度加上行间距
74 int lyric_height2 = lyric_height * 2 + line_space; //包含翻译的歌词高度
75
76 CFont* pOldFont = SetFont(m_lyric_font);
77 if (CPlayer::GetInstance().IsPlaylistEmpty()) //当前播放为空时在歌词区域显示播放提示
78 {
79 CFont* font = SetFont(&theApp.m_font_set.GetFontBySize(10).GetFont());
80 wstring no_track_tip_str = theApp.m_str_table.LoadTextFormat(L"UI_LYRIC_NO_TRACKS_TIP", {
81 theApp.m_accelerator_res.GetShortcutDescriptionById(ID_SHOW_PLAYLIST),
82 theApp.m_accelerator_res.GetShortcutDescriptionById(ID_FILE_OPEN),
83 theApp.m_accelerator_res.GetShortcutDescriptionById(ID_FILE_OPEN_FOLDER),
84 theApp.m_accelerator_res.GetShortcutDescriptionById(ID_MEDIA_LIB)});
85 DrawWindowText(lyric_area, no_track_tip_str.c_str(), m_colors.color_text_2, Alignment::LEFT, false, true);
86 SetFont(font);
87 }
88 else if (CPlayerUIHelper::IsMidiLyric())
89 {
90 wstring current_lyric{ CPlayer::GetInstance().GetMidiLyric() };
91 DrawWindowText(lyric_area, current_lyric.c_str(), m_colors.color_text, Alignment::CENTER, false, true);
92 }
93 else if (CPlayer::GetInstance().m_Lyrics.IsEmpty())
94 {
95 //没有歌词时显示歌曲信息
96 if (theApp.m_lyric_setting_data.show_song_info_if_lyric_not_exist || show_song_info)
97 {
98 CString song_info_str;
99 const SongInfo& cur_song{ CPlayer::GetInstance().GetCurrentSongInfo() };
100 std::wstring artist{ cur_song.album_artist };
101 if (artist.empty())
102 artist = cur_song.GetArtist();
103 song_info_str.Format(_T("%s - %s\r\n%s"), artist.c_str(), cur_song.GetAlbum().c_str(), cur_song.GetTitle().c_str());
104 DrawWindowText(lyric_area, song_info_str, m_colors.color_text, align, false, true);
105 }
106 //显示“当前歌曲没有歌词”
107 else
108 {
109 static const wstring& no_lyric_info = theApp.m_str_table.LoadText(L"UI_LYRIC_NONE");
110 DrawWindowText(lyric_area, no_lyric_info.c_str(), m_colors.color_text_2, Alignment::CENTER);
111 }
112 }
113 else
114 {
115 //CRect arect{ lyric_area }; //一行歌词的矩形区域
116 //arect.bottom = arect.top + lyric_height;
117 //vector<CRect> rects(CPlayer::GetInstance().m_Lyrics.GetLyricCount() + 1, arect);
118 //为每一句歌词创建一个矩形,保存在容器里
119 vector<CRect> rects;
120 int lyric_count = CPlayer::GetInstance().m_Lyrics.GetLyricCount() + 1; //获取歌词数量(由于第一行歌词需要显示标题,所以这里要+1)
121 for (int i{}; i < lyric_count; i++)
122 {
123 CRect arect{ lyric_area };
124 if (!CPlayer::GetInstance().m_Lyrics.GetLyric(i - 1).translate.empty() && theApp.m_lyric_setting_data.show_translate)
125 arect.bottom = arect.top + lyric_height2;
126 else
127 arect.bottom = arect.top + lyric_height;
128 rects.push_back(arect);
129 }
130 int center_pos = (lyric_area.top + lyric_area.bottom) / 2; //歌词区域的中心y坐标
131 Time time{ CPlayer::GetInstance().GetCurrentPosition() }; //当前播放时间
132 int lyric_index = CPlayer::GetInstance().m_Lyrics.GetLyricIndex(time); // 当前歌词的序号
133 int progress{ CPlayer::GetInstance().m_Lyrics.GetLyricProgress(time, false, false, [this](const wstring& str) { return GetTextExtent(str.c_str()).cx; }) }; // 当前歌词进度(范围为0~1000),多行歌词使用的进度不含进度符号
134 int y_progress; //当前歌词在y轴上的进度
135 if (!CPlayer::GetInstance().m_Lyrics.GetLyric(lyric_index).translate.empty() && theApp.m_lyric_setting_data.show_translate)
136 y_progress = progress * lyric_height2 / 1000;
137 else
138 y_progress = progress * lyric_height / 1000;
139 //int start_pos = center_pos - y_progress - (lyric_index + 1)*lyric_height; //第1句歌词的起始y坐标
140 //计算第1句歌词的起始y坐标
141 //由于当前歌词需要显示在歌词区域的中心位置,因此从中心位置开始,减去当前歌词在Y轴上的进度
142 //再依次减去之前每一句歌词的高度,即得到了第一句歌词的起始位置
143 int start_pos;
144 start_pos = center_pos - y_progress;
145 for (int i{ lyric_index - 1 }; i >= -1; i--)
146 {
147 if (theApp.m_lyric_setting_data.show_translate && !CPlayer::GetInstance().m_Lyrics.GetLyric(i).translate.empty())
148 start_pos -= lyric_height2;
149 else
150 start_pos -= lyric_height;
151 }
152
153 //依次绘制每一句歌词
154 for (int i{ -1 }; i < static_cast<int>(rects.size()) - 1; i++)
155 {
156 //计算每一句歌词的位置
157 if (i == -1)
158 rects[i + 1].MoveToY(start_pos);
159 else
160 rects[i + 1].MoveToY(rects[i].bottom);
161 //绘制歌词文本
162 if (!(rects[i + 1] & lyric_area).IsRectEmpty()) //只有当一句歌词的矩形区域和歌词区域的矩形有交集时,才绘制歌词
163 {
164 //设置歌词文本和翻译文本的矩形区域
165 CRect rect_text{ rects[i + 1] };
166 CRect rect_translate;
167 const CLyrics::Lyric& lyric_i = CPlayer::GetInstance().m_Lyrics.GetLyric(i);
168 if (!lyric_i.translate.empty() && theApp.m_lyric_setting_data.show_translate)
169 {
170 rect_text.MoveToY(rect_text.top + line_space);
171 rect_text.bottom = rect_text.top + GetLyricTextHeight();
172 rect_translate = rect_text;
173 rect_translate.MoveToY(rect_text.bottom + line_space);
174 }
175
176 if (i == lyric_index && progress < 1000) //绘制正在播放的歌词(处于逐渐过度到高亮过程中的歌词)
177 {
178 //这里实现文本从非高亮缓慢变化到高亮效果
179 int last_time_span = time - lyric_i.time_start; //当前播放的歌词已持续的时间
180 int fade_percent = last_time_span / 8; //计算颜色高亮变化的百分比,除数越大则持续时间越长,10则为1秒
181 COLORREF text_color = CColorConvert::GetGradientColor(m_colors.color_text_2, m_colors.color_text, fade_percent);
182 //绘制歌词文本
183 SetFont(m_lyric_font);
184 if (theApp.m_lyric_setting_data.lyric_karaoke_disp)
185 DrawWindowText(rect_text, lyric_i.text.c_str(), m_colors.color_text, m_colors.color_text_2, progress, align, true);
186 else
187 DrawWindowText(rect_text, lyric_i.text.c_str(), text_color, text_color, progress, align, true);
188 //绘制翻译文本
189 if (!lyric_i.translate.empty() && theApp.m_lyric_setting_data.show_translate)
190 {
191 SetFont(m_lyric_tr_font);
192 DrawWindowText(rect_translate, lyric_i.translate.c_str(), text_color, text_color, progress, align, true);
193 }
194 }
195 else //绘制非正在播放的歌词
196 {
197 SetFont(m_lyric_font);
198 COLORREF text_color;
199 if (i == lyric_index - 1 || (i == lyric_index && progress == 1000)) // 绘制正在取消高亮的歌词(这里实现一句歌词颜色从高亮缓慢变化到非高亮效果),逐字歌词最后一句在此处取消高亮
200 {
201 int last_time_span = time - (lyric_i.time_start + lyric_i.time_span); // 引入逐字歌词后上句歌词结束后时长不等于当前播放的歌词已持续的时间,此处应当使用上句歌词结束时间
202 int fade_percent = last_time_span / 20; //计算颜色高亮变化的百分比,当持续时间为2000毫秒时为100%,即颜色缓慢变化的时间为2秒
203 text_color = CColorConvert::GetGradientColor(m_colors.color_text, m_colors.color_text_2, fade_percent);
204 }
205 else
206 {
207 text_color = m_colors.color_text_2;
208 }
209 //绘制歌词文本
210 DrawWindowText(rect_text, lyric_i.text.c_str(), text_color, align, true);
211 //绘制翻译文本
212 if (!lyric_i.translate.empty() && theApp.m_lyric_setting_data.show_translate)
213 {
214 SetFont(m_lyric_tr_font);
215 DrawWindowText(rect_translate, lyric_i.translate.c_str(), text_color, align, true);
216 }
217 }
218 }
219 }
220 }
221 SetFont(pOldFont);
222 }
223
DrawLyricTextSingleLine(CRect rect,int & flag,bool double_line,Alignment align,bool show_song_info)224 void CUIDrawer::DrawLyricTextSingleLine(CRect rect, int& flag, bool double_line, Alignment align, bool show_song_info)
225 {
226 CFont* pOldFont = SetFont(m_lyric_font);
227
228 if (CPlayerUIHelper::IsMidiLyric())
229 {
230 wstring current_lyric{ CPlayer::GetInstance().GetMidiLyric() };
231 DrawWindowText(rect, current_lyric.c_str(), m_colors.color_text, Alignment::CENTER, false, true);
232 }
233 else if (CPlayer::GetInstance().m_Lyrics.IsEmpty())
234 {
235 //没有歌词时显示歌曲信息
236 if (theApp.m_lyric_setting_data.show_song_info_if_lyric_not_exist || show_song_info)
237 {
238 CString song_info_str;
239 const SongInfo& cur_song{ CPlayer::GetInstance().GetCurrentSongInfo() };
240 song_info_str.Format(_T("%s - %s"), cur_song.GetArtist().c_str(), cur_song.GetTitle().c_str());
241 static CDrawCommon::ScrollInfo lyric_scroll_info;
242 DrawScrollText(rect, song_info_str, m_colors.color_text, CPlayerUIHelper::GetScrollTextPixel(), theApp.m_lyric_setting_data.lyric_align != Alignment::LEFT, lyric_scroll_info);
243 }
244 //显示“当前歌曲没有歌词”
245 else
246 {
247 static const wstring& no_lyric_info = theApp.m_str_table.LoadText(L"UI_LYRIC_NONE");
248 DrawWindowText(rect, no_lyric_info.c_str(), m_colors.color_text_2, Alignment::CENTER);
249 }
250 }
251 else
252 {
253 DrawAreaGuard guard(this, rect);
254 CRect lyric_rect = rect;
255
256 static const wstring& empty_lyric = theApp.m_str_table.LoadText(L"UI_LYRIC_EMPTY_LINE");
257 const bool karaoke{ theApp.m_lyric_setting_data.lyric_karaoke_disp };
258 const bool ignore_blank{ theApp.m_lyric_setting_data.donot_show_blank_lines};
259 auto& now_lyrics{ CPlayer::GetInstance().m_Lyrics };
260 Time time{ CPlayer::GetInstance().GetCurrentPosition() };
261 CLyrics::Lyric current_lyric{ now_lyrics.GetLyric(time, false, ignore_blank, karaoke) };
262 int progress{ now_lyrics.GetLyricProgress(time, ignore_blank, karaoke, [this](const wstring& str) { return GetTextExtent(str.c_str()).cx; }) };
263
264 //当前歌词为空,且持续了超过了20秒
265 bool no_lyric = (current_lyric.text.empty() && CPlayer::GetInstance().GetCurrentPosition() - current_lyric.time_start > 20000) || progress >= 1000;
266 //当指定了show_song_info时,如果当前歌词为空,且持续了超过了20秒,则显示歌曲信息
267 if (no_lyric && show_song_info)
268 {
269 //显示歌曲信息
270 CString song_info_str;
271 const SongInfo& cur_song{ CPlayer::GetInstance().GetCurrentSongInfo() };
272 song_info_str.Format(_T("%s - %s"), cur_song.GetArtist().c_str(), cur_song.GetTitle().c_str());
273 static CDrawCommon::ScrollInfo lyric_scroll_info;
274 DrawScrollText(rect, song_info_str, m_colors.color_text, CPlayerUIHelper::GetScrollTextPixel(), theApp.m_lyric_setting_data.lyric_align != Alignment::LEFT, lyric_scroll_info);
275 }
276 else
277 {
278 bool switch_flag{ flag > 5000 };
279 switch_flag ^= (flag % 5000) > progress;
280 flag = switch_flag ? 10000 + progress : progress;
281
282 if (current_lyric.text.empty())
283 current_lyric.text = empty_lyric;
284 //双行显示歌词
285 if (double_line && (current_lyric.translate.empty() || !theApp.m_lyric_setting_data.show_translate) && rect.Height() > static_cast<int>(GetLyricTextHeight() * 1.73))
286 {
287 wstring next_lyric_text;
288 next_lyric_text = now_lyrics.GetLyric(time, true, ignore_blank, karaoke).text;
289 if (next_lyric_text.empty())
290 next_lyric_text = empty_lyric;
291 //这里实现文本从非高亮缓慢变化到高亮效果
292 int last_time_span = time - current_lyric.time_start; //当前播放的歌词已持续的时间
293 int fade_percent = last_time_span / 8; //计算颜色高亮变化的百分比,除数越大则持续时间越长,10则为1秒
294 if (progress == 1000) fade_percent = 0; // 进度为1000时当前歌词“已完成”不再高亮
295 // 这里的fade_percent当合并空行开启时可能为负,在颜色渐变处规范取值,此处不再处理
296 DrawLyricDoubleLine(lyric_rect, current_lyric.text.c_str(), next_lyric_text.c_str(), align, progress, switch_flag, fade_percent);
297 }
298 else
299 {
300 // AUTO时单行歌词居中显示
301 if (align == Alignment::AUTO) align = Alignment::CENTER;
302 // 单行歌词在这里显示翻译,同时更新歌词区域为单行有翻译时的位置
303 if (theApp.m_lyric_setting_data.show_translate && !current_lyric.translate.empty() && rect.Height() > static_cast<int>(GetLyricTextHeight() * 1.73))
304 {
305 lyric_rect.bottom = lyric_rect.top + rect.Height() / 2;
306 CRect translate_rect = lyric_rect;
307 translate_rect.MoveToY(lyric_rect.bottom);
308
309 SetFont(m_lyric_tr_font);
310 DrawWindowText(translate_rect, current_lyric.translate.c_str(), m_colors.color_text, m_colors.color_text, progress, align, true);
311 }
312 // 绘制单行歌词
313 SetFont(m_lyric_font);
314 if (theApp.m_lyric_setting_data.lyric_karaoke_disp)
315 DrawWindowText(lyric_rect, current_lyric.text.c_str(), m_colors.color_text, m_colors.color_text_2, progress, align, true);
316 else if (0 < progress && progress < 1000) // 仅高亮“正在进行”的歌词
317 DrawWindowText(lyric_rect, current_lyric.text.c_str(), m_colors.color_text, m_colors.color_text, progress, align, true);
318 else
319 DrawWindowText(lyric_rect, current_lyric.text.c_str(), m_colors.color_text_2, m_colors.color_text_2, progress, align, true);
320 }
321 }
322 }
323
324 SetFont(pOldFont);
325 }
326
DrawSpectrum(CRect rect,SpectrumCol col,bool draw_reflex,bool low_freq_in_center,bool fixed_width,Alignment alignment)327 void CUIDrawer::DrawSpectrum(CRect rect, SpectrumCol col, bool draw_reflex /*= false*/, bool low_freq_in_center, bool fixed_width, Alignment alignment)
328 {
329 int cols; //要显示的频谱柱形的数量
330 switch (col)
331 {
332 case CUIDrawer::SC_64:
333 cols = 64;
334 break;
335 case CUIDrawer::SC_32:
336 cols = 32;
337 break;
338 case CUIDrawer::SC_16:
339 cols = 16;
340 break;
341 case CUIDrawer::SC_8:
342 cols = 8;
343 break;
344 default:
345 cols = SPECTRUM_COL;
346 break;
347 }
348 int max_width{ rect.Width() };
349 if (fixed_width)
350 {
351 if (col == SC_64)
352 {
353 max_width = DPI(280);
354 }
355 }
356 double gap_width_double{ max_width * (SPECTRUM_COL / cols) / 168.0 }; //频谱柱形间隙宽度
357 if (theApp.m_ui_data.full_screen && !m_for_cortana_lyric)
358 gap_width_double *= CONSTVAL::FULL_SCREEN_ZOOM_FACTOR;
359 int gap_width{ static_cast<int>(gap_width_double + 0.5) }; //这里加0.5用作将小数四舍五入处理
360 int width = (max_width - (cols - 1) * gap_width) / (cols - 1);
361 if (gap_width < 1)
362 gap_width = 1;
363 if (width < 1)
364 width = 1;
365
366 DrawAreaGuard guard(this, rect, true, fixed_width);
367 DrawSpectrum(rect, width, gap_width, cols, m_colors.color_spectrum, draw_reflex, low_freq_in_center, alignment);
368 }
369
DrawSpectrum(CRect rect,int col_width,int gap_width,int cols,COLORREF color,bool draw_reflex,bool low_freq_in_center,Alignment alignment,bool draw_peak,int sprctrum_height)370 void CUIDrawer::DrawSpectrum(CRect rect, int col_width, int gap_width, int cols, COLORREF color, bool draw_reflex, bool low_freq_in_center, Alignment alignment, bool draw_peak, int sprctrum_height)
371 {
372 CRect rc_spectrum_top = rect;
373 if (draw_reflex) //如果要绘制倒影,则倒影占总高度的1/3
374 rc_spectrum_top.bottom = rect.top + (rect.Height() * 2 / 3);
375
376 CRect rects[SPECTRUM_COL];
377 rects[0] = rc_spectrum_top;
378 rects[0].right = rects[0].left + col_width;
379
380 //频谱的实际宽度
381 int width_actrual{ col_width * cols + gap_width * (cols - 1) };
382 //如果频谱的实际宽度小于矩形的宽度,则让根据alignment的值让频谱居中或右对齐显示
383 if ((width_actrual < rect.Width() && alignment == Alignment::CENTER) || (width_actrual >= rect.Width() && theApp.m_app_setting_data.spectrum_low_freq_in_center))
384 rects[0].MoveToX(rects[0].left + (rect.Width() - width_actrual) / 2);
385 else if (width_actrual < rect.Width() && alignment == Alignment::RIGHT)
386 rects[0].MoveToX(rects[0].left + (rect.Width() - width_actrual));
387
388 for (int i{ 1 }; i < cols; i++)
389 {
390 rects[i] = rects[0];
391 rects[i].left += (i * (col_width + gap_width));
392 rects[i].right += (i * (col_width + gap_width));
393 }
394 for (int i{}; i < cols; i++)
395 {
396 int index;
397 if (low_freq_in_center)
398 {
399 if (i < cols / 2)
400 index = (-i + cols / 2) * 2 - 1;
401 else
402 index = (i - cols / 2) * 2;
403 }
404 else
405 {
406 index = i;
407 }
408 if (index >= cols)
409 index = cols;
410 if (index < 0)
411 index = 0;
412 float spetral_data = CPlayer::GetInstance().GetSpectralData()[index * (SPECTRUM_COL / cols)];
413 float peak_data = CPlayer::GetInstance().GetSpectralPeakData()[index * (SPECTRUM_COL / cols)];
414
415 CRect rect_tmp{ rects[i] };
416 if (sprctrum_height <= 0)
417 sprctrum_height = theApp.m_app_setting_data.sprctrum_height;
418 int spetral_height = static_cast<int>(spetral_data * rects[0].Height() / 30 * sprctrum_height / 100);
419 int peak_height = static_cast<int>(peak_data * rects[0].Height() / 30 * sprctrum_height / 100);
420 if (spetral_height < 0 || CPlayer::GetInstance().IsError()) spetral_height = 0; //如果播放出错,不显示频谱
421 if (peak_height < 0 || CPlayer::GetInstance().IsError()) peak_height = 0;
422
423 int peak_rect_height = max(theApp.DPIRound(1.1), gap_width / 2); //顶端矩形的高度
424 spetral_height += peak_rect_height; //频谱至少和顶端矩形一样高
425 peak_height += peak_rect_height;
426
427 rect_tmp.top = rect_tmp.bottom - spetral_height;
428 if (rect_tmp.top < rects[0].top) rect_tmp.top = rects[0].top;
429 FillRect(rect_tmp, color, true);
430 //绘制倒影
431 if (draw_reflex)
432 {
433 CRect rc_invert = rect_tmp;
434 rc_invert.bottom = rect_tmp.top + rect_tmp.Height() * 2 / 3;
435 rc_invert.MoveToY(rect_tmp.bottom + gap_width);
436 FillAlphaRect(rc_invert, color, 96, true);
437 }
438
439 if (draw_peak)
440 {
441 //绘制顶端
442 CRect rect_peak{ rect_tmp };
443 rect_peak.bottom = rect_tmp.bottom - peak_height - gap_width;
444 rect_peak.top = rect_peak.bottom - peak_rect_height;
445 FillRect(rect_peak, color, true);
446 ////绘制顶端倒影
447 //CRect rc_peak_invert = rect_peak;
448 //rc_peak_invert.MoveToY(rc_invert.top + peak_height + theApp.DPIRound(1.1));
449 //FillAlphaRect(rc_peak_invert, color, 96);
450 }
451 }
452
453 }
454
DPI(int pixel)455 int CUIDrawer::DPI(int pixel)
456 {
457 if (theApp.m_ui_data.full_screen && !m_for_cortana_lyric)
458 return theApp.DPI(pixel * CONSTVAL::FULL_SCREEN_ZOOM_FACTOR);
459 else
460 return theApp.DPI(pixel);
461 }
462
DrawLyricDoubleLine(CRect rect,LPCTSTR lyric,LPCTSTR next_lyric,Alignment align,int progress,bool switch_flag,int fade_percent)463 void CUIDrawer::DrawLyricDoubleLine(CRect rect, LPCTSTR lyric, LPCTSTR next_lyric, Alignment align, int progress, bool switch_flag, int fade_percent)
464 {
465 CFont* pOldFont = SetFont(m_lyric_font);
466
467 CRect up_rect{ rect }, down_rect{ rect }; //上半部分和下半部分歌词的矩形区域
468 up_rect.bottom = up_rect.top + (up_rect.Height() / 2);
469 down_rect.top = down_rect.bottom - (down_rect.Height() / 2);
470
471 // 对齐方式为AUTO时使用上左下右的卡拉OK对齐方式
472 Alignment up_align{ Alignment::LEFT }, down_align{ Alignment::RIGHT };
473 if (align != Alignment::AUTO)
474 up_align = down_align = align;
475
476 COLORREF color1, color2;
477 if (theApp.m_lyric_setting_data.lyric_karaoke_disp)
478 {
479 color1 = m_colors.color_text;
480 color2 = m_colors.color_text_2;
481 }
482 else
483 {
484 color1 = color2 = CColorConvert::GetGradientColor(m_colors.color_text_2, m_colors.color_text, fade_percent);
485 }
486
487 // 绘制当前歌词
488 if (!switch_flag)
489 {
490 DrawWindowText(up_rect, lyric, color1, color2, progress, up_align);
491 DrawWindowText(down_rect, next_lyric, m_colors.color_text_2, down_align);
492 }
493 else
494 {
495 DrawWindowText(up_rect, next_lyric, m_colors.color_text_2, up_align);
496 DrawWindowText(down_rect, lyric, color1, color2, progress, down_align);
497 }
498 SetFont(pOldFont);
499 }
500