1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components/calendar/rosen_render_calendar.h"
17
18 #ifndef USE_GRAPHIC_TEXT_GINE
19 #include "txt/paragraph_builder.h"
20 #include "txt/paragraph_style.h"
21 #else
22 #include "rosen_text/typography_create.h"
23 #include "rosen_text/typography_style.h"
24 #endif
25
26 #include "base/i18n/localization.h"
27 #include "core/components/font/rosen_font_collection.h"
28 #include "core/pipeline/base/rosen_render_context.h"
29
30 namespace OHOS::Ace {
31 namespace {
32
33 const char ELLIPSIS[] = "...";
34 constexpr double CURRENT_MONTH_TRANSPARENT = 0xFF;
35 constexpr double NON_CURRENT_MONTH_TRANSPARENT = 0x32;
36 constexpr double WEEKEND_TRANSPARENT = 0x7D;
37 constexpr double SCHEDULE_MARKER_TRANSPARENT = 0x4B;
38 constexpr Dimension CARD_CALENDAR_TITLE_HEIGHT = 68.0_vp;
39
40 #ifndef USE_GRAPHIC_TEXT_GINE
GetTextParagraph(const std::string & text,const txt::TextStyle & textStyle)41 std::unique_ptr<txt::Paragraph> GetTextParagraph(const std::string& text, const txt::TextStyle& textStyle)
42 {
43 txt::ParagraphStyle style;
44 #else
45 std::unique_ptr<Rosen::Typography> GetTextParagraph(const std::string& text, const Rosen::TextStyle& textStyle)
46 {
47 Rosen::TypographyStyle style;
48 #endif
49 auto fontCollection = RosenFontCollection::GetInstance().GetFontCollection();
50 if (!fontCollection) {
51 LOGW("MeasureText: fontCollection is null");
52 return nullptr;
53 }
54 #ifndef USE_GRAPHIC_TEXT_GINE
55 std::unique_ptr<txt::ParagraphBuilder> builder = txt::ParagraphBuilder::CreateTxtBuilder(style, fontCollection);
56 builder->PushStyle(textStyle);
57 builder->AddText(StringUtils::Str8ToStr16(text));
58 return builder->Build();
59 #else
60 std::unique_ptr<Rosen::TypographyCreate> builder = Rosen::TypographyCreate::Create(style, fontCollection);
61 builder->PushStyle(textStyle);
62 builder->AppendText(StringUtils::Str8ToStr16(text));
63 return builder->CreateTypography();
64 #endif
65 }
66
67 #ifndef USE_ROSEN_DRAWING
68 #ifndef USE_GRAPHIC_TEXT_GINE
69 void DrawCalendarText(
70 SkCanvas* canvas, const std::string& text, const txt::TextStyle& textStyle, const Rect& boxRect, Rect& textRect)
71 #else
72 void DrawCalendarText(
73 SkCanvas* canvas, const std::string& text, const Rosen::TextStyle& textStyle, const Rect& boxRect, Rect& textRect)
74 #endif
75 #else
76 #ifndef USE_GRAPHIC_TEXT_GINE
77 void DrawCalendarText(RSCanvas* canvas,
78 const std::string& text, const txt::TextStyle& textStyle, const Rect& boxRect, Rect& textRect)
79 #else
80 void DrawCalendarText(RSCanvas* canvas,
81 const std::string& text, const Rosen::TextStyle& textStyle, const Rect& boxRect, Rect& textRect)
82 #endif
83 #endif
84 {
85 // The lunar calendar description is truncated by more than three characters.
86 std::string newText { text };
87 auto wText = StringUtils::ToWstring(text);
88 if (wText.size() > 3) {
89 wText = wText.substr(0, 2);
90 newText = StringUtils::ToString(wText);
91 newText += ELLIPSIS;
92 }
93
94 auto paragraph = GetTextParagraph(newText, textStyle);
95 if (!paragraph) {
96 return;
97 }
98 const auto& offset = boxRect.GetOffset();
99 paragraph->Layout(boxRect.Width());
100 double textWidth = paragraph->GetMaxIntrinsicWidth();
101 double textHeight = paragraph->GetHeight();
102 // paint text in center of item
103 double textPaintOffsetX = (boxRect.Width() - textWidth) / 2.0;
104 double textPaintOffsetY = (boxRect.Height() - textHeight) / 2.0;
105 paragraph->Paint(canvas, offset.GetX() + textPaintOffsetX, offset.GetY() + textPaintOffsetY);
106 textRect.SetRect(offset.GetX() + textPaintOffsetX, offset.GetY() + textPaintOffsetY, textWidth, textHeight);
107 }
108
109 #ifndef USE_ROSEN_DRAWING
110 #ifndef USE_GRAPHIC_TEXT_GINE
111 void DrawCalendarText(SkCanvas* canvas, const std::string& text, const txt::TextStyle& textStyle, const Rect& boxRect)
112 #else
113 void DrawCalendarText(SkCanvas* canvas, const std::string& text, const Rosen::TextStyle& textStyle, const Rect& boxRect)
114 #endif
115 #else
116 #ifndef USE_GRAPHIC_TEXT_GINE
117 void DrawCalendarText(RSCanvas* canvas,
118 const std::string& text, const txt::TextStyle& textStyle, const Rect& boxRect)
119 #else
120 void DrawCalendarText(RSCanvas* canvas,
121 const std::string& text, const Rosen::TextStyle& textStyle, const Rect& boxRect)
122 #endif
123 #endif
124 {
125 Rect textRect;
126 DrawCalendarText(canvas, text, textStyle, boxRect, textRect);
127 }
128 } // namespace
129
Update(const RefPtr<Component> & component)130 void RosenRenderCalendar::Update(const RefPtr<Component>& component)
131 {
132 auto calendarMonth = AceType::DynamicCast<CalendarMonthComponent>(component);
133 if (!calendarMonth) {
134 LOGE("calendar component is null");
135 return;
136 }
137
138 textDirection_ = calendarMonth->GetTextDirection();
139 auto calendarTheme = calendarMonth->GetCalendarTheme();
140 cardCalendar_ = calendarMonth->IsCardCalendar();
141 if (!isV2Component_) {
142 calendarTheme_ = cardCalendar_ ? calendarTheme->GetCardCalendarTheme() : calendarTheme->GetCalendarTheme();
143 }
144 RenderCalendar::Update(component);
145 if (auto rsNode = GetRSNode()) {
146 rsNode->SetClipToFrame(true);
147 }
148 }
149
Paint(RenderContext & context,const Offset & offset)150 void RosenRenderCalendar::Paint(RenderContext& context, const Offset& offset)
151 {
152 if (isV2Component_ && !isNeedRepaint_) {
153 AddContentLayer(context);
154 DrawTouchedArea(context, offset);
155 return;
156 }
157 SetCalendarTheme();
158 if (isV2Component_) {
159 #ifdef OHOS_PLATFORM
160 const Size& layout = GetLayoutSize();
161 #ifndef USE_ROSEN_DRAWING
162 OHOS::Rosen::RSRecordingCanvas canvas(layout.Width(), layout.Height());
163 #else
164 RSRecordingCanvas canvas(layout.Width(), layout.Height());
165 #endif
166 DrawWeekAndDates(&canvas, offset);
167 drawCmdList_ = canvas.GetDrawCmdList();
168 isNeedRepaint_ = false;
169 AddContentLayer(context);
170 DrawTouchedArea(context, offset);
171 #endif
172 } else {
173 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
174 if (!canvas) {
175 LOGE("paint canvas is null");
176 return;
177 }
178 DrawWeekAndDates(canvas, offset);
179 }
180 }
181
PerformLayout()182 void RosenRenderCalendar::PerformLayout()
183 {
184 RenderCalendar::PerformLayout();
185 topPadding_ = type_ == CalendarType::SIMPLE ? 0.0 : NormalizeToPx(calendarTheme_.topPadding);
186 weekFontSize_ = NormalizeToPx(calendarTheme_.weekFontSize);
187 dayFontSize_ = NormalizeToPx(calendarTheme_.dayFontSize);
188 lunarDayFontSize_ = NormalizeToPx(calendarTheme_.lunarDayFontSize);
189 workDayMarkSize_ = NormalizeToPx(calendarTheme_.workDayMarkSize);
190 offDayMarkSize_ = NormalizeToPx(calendarTheme_.offDayMarkSize);
191 focusedAreaRadius_ = NormalizeToPx(calendarTheme_.focusedAreaRadius);
192 weekHeight_ = NormalizeToPx(calendarTheme_.weekHeight);
193 dayHeight_ = NormalizeToPx(calendarTheme_.dayHeight);
194 weekWidth_ = NormalizeToPx(calendarTheme_.weekWidth);
195 dayWidth_ = NormalizeToPx(calendarTheme_.dayWidth);
196 weekAndDayRowSpace_ = NormalizeToPx(calendarTheme_.weekAndDayRowSpace);
197 touchCircleStrokeWidth_ = NormalizeToPx(calendarTheme_.touchCircleStrokeWidth);
198 double titleHeight = topPadding_ + weekHeight_ + weekAndDayRowSpace_;
199 double boundaryRowOffset = NormalizeToPx(calendarTheme_.boundaryRowOffset);
200 double boundaryColOffset = NormalizeToPx(calendarTheme_.boundaryColOffset);
201 const static int32_t daysOfWeek = 7;
202 const static int32_t fiveRow = 5;
203 const static int32_t sixRow = 6;
204 const static float heightOffset = 1.5f;
205 weekAndDayRowSpace_ = NormalizeToPx(calendarTheme_.weekAndDayRowSpace);
206 if (cardCalendar_ || isV2Component_) {
207 colSpace_ = (maxWidth_ - dayWidth_ * daysOfWeek - boundaryRowOffset) / (daysOfWeek - 1);
208 dailyFiveRowSpace_ = (maxHeight_ - titleHeight - dayHeight_ * fiveRow - boundaryColOffset) / (fiveRow - 1);
209 dailySixRowSpace_ = (maxHeight_ - titleHeight - dayHeight_ * sixRow - boundaryColOffset) / (sixRow - 1);
210 } else if (type_ == CalendarType::SIMPLE) {
211 colSpace_ = (maxWidth_ - boundaryRowOffset - dayWidth_ * daysOfWeek) / (daysOfWeek - 1);
212 dailyFiveRowSpace_ =
213 (maxHeight_ - boundaryColOffset - weekAndDayRowSpace_ - weekHeight_ - dayHeight_ * fiveRow) / (fiveRow - 1);
214 dailySixRowSpace_ =
215 (maxHeight_ - boundaryColOffset - weekAndDayRowSpace_ - weekHeight_ - dayHeight_ * sixRow) / (sixRow - 1);
216 } else {
217 colSpace_ = NormalizeToPx(calendarTheme_.colSpace);
218 dailyFiveRowSpace_ = NormalizeToPx(calendarTheme_.dailyFiveRowSpace);
219 dailySixRowSpace_ = NormalizeToPx(calendarTheme_.dailySixRowSpace);
220 }
221 gregorianCalendarHeight_ = NormalizeToPx(calendarTheme_.gregorianCalendarHeight);
222 workStateWidth_ = NormalizeToPx(calendarTheme_.workStateWidth);
223 workStateHorizontalMovingDistance_ = NormalizeToPx(calendarTheme_.workStateHorizontalMovingDistance);
224 workStateVerticalMovingDistance_ = NormalizeToPx(calendarTheme_.workStateVerticalMovingDistance);
225 auto dayHeight = rowCount_ ? (maxHeight_ - NormalizeToPx(CARD_CALENDAR_TITLE_HEIGHT)) / rowCount_ : 0.0;
226 auto heightDifference = dayWidth_ - dayHeight;
227 if (cardCalendar_ && GreatNotEqual(dayWidth_, dayHeight) && GreatNotEqual(heightDifference, heightOffset)) {
228 needShrink_ = true;
229 focusedAreaRadius_ = (maxHeight_ - NormalizeToPx(CARD_CALENDAR_TITLE_HEIGHT)) / (rowCount_ * 2);
230 } else {
231 needShrink_ = false;
232 }
233 }
234
235 #ifndef USE_ROSEN_DRAWING
DrawWeekAndDates(SkCanvas * canvas,Offset offset)236 void RosenRenderCalendar::DrawWeekAndDates(SkCanvas* canvas, Offset offset)
237 #else
238 void RosenRenderCalendar::DrawWeekAndDates(RSCanvas* canvas, Offset offset)
239 #endif
240 {
241 uint32_t totalWeek = weekNumbers_.size();
242 uint32_t daysCount = static_cast<uint32_t>(rowCount_) * totalWeek;
243 if (calendarDays_.size() < daysCount) {
244 return;
245 }
246
247 if (isV2Component_) {
248 offset += { touchCircleStrokeWidth_, 0 };
249 }
250 DrawWeek(canvas, offset);
251
252 int32_t dateNumber = 0;
253 double dailyRowSpace = 0.0;
254 static const Dimension dateOffset = 4.0_vp;
255 double dayNumberStartY = topPadding_ + weekHeight_ + weekAndDayRowSpace_;
256 if (rowCount_ == 5) { // five line calendar
257 dailyRowSpace = dailyFiveRowSpace_;
258 } else if (rowCount_ == 6) { // six line calendar
259 dailyRowSpace = dailySixRowSpace_;
260 }
261 for (int32_t row = 0; row < rowCount_; row++) {
262 double y = row * (dayHeight_ + dailyRowSpace) + dayNumberStartY;
263 for (uint32_t column = 0; column < totalWeek; column++) {
264 const auto& day = calendarDays_[dateNumber++];
265 double x = textDirection_ == TextDirection::LTR ? column * (dayWidth_ + colSpace_)
266 : (totalWeek - column - 1) * (dayWidth_ + colSpace_);
267 auto dayOffset = Offset(x, y);
268 if (cardCalendar_ || isV2Component_) {
269 DrawCardCalendar(canvas, offset + Offset(0, NormalizeToPx(dateOffset)), dayOffset, day, dateNumber);
270 } else {
271 DrawTvCalendar(canvas, offset, dayOffset, day, dateNumber);
272 }
273 }
274 }
275 }
276
277 #ifndef USE_ROSEN_DRAWING
DrawFocusedArea(SkCanvas * canvas,const Offset & offset,const CalendarDay & day,double x,double y) const278 void RosenRenderCalendar::DrawFocusedArea(
279 SkCanvas* canvas, const Offset& offset, const CalendarDay& day, double x, double y) const
280 #else
281 void RosenRenderCalendar::DrawFocusedArea(
282 RSCanvas* canvas, const Offset& offset, const CalendarDay& day, double x, double y) const
283 #endif
284 {
285 auto pipelineContext = context_.Upgrade();
286 if (!pipelineContext) {
287 LOGE("pipeline context");
288 return;
289 }
290 // start focus animation
291 Offset circleStart =
292 GetGlobalOffset() + Offset(x - (focusedAreaRadius_ * 2 - dayWidth_) / 2, y - NormalizeToPx(1.0_vp));
293 RRect focusAnimationRRect =
294 RRect::MakeRRect(Rect(0.0, 0.0, focusedAreaRadius_ * 2, focusedAreaRadius_ * 2), Radius(focusedAreaRadius_));
295 pipelineContext->ShowFocusAnimation(focusAnimationRRect, Color::WHITE, circleStart);
296
297 // draw focus background circle
298 #ifndef USE_ROSEN_DRAWING
299 SkPaint paint;
300 paint.setAntiAlias(true);
301
302 if (SystemProperties::GetDeviceType() == DeviceType::WATCH || type_ == CalendarType::SIMPLE) {
303 if (day.dayMark == "work" && showHoliday_) {
304 paint.setColor(workDayMarkColor_);
305 } else if (day.dayMark == "off" && showHoliday_) {
306 paint.setColor(offDayMarkColor_);
307 } else {
308 paint.setColor(focusedAreaBackgroundColor_);
309 }
310 } else {
311 paint.setColor(focusedAreaBackgroundColor_);
312 }
313 Offset circleCenter =
314 type_ == CalendarType::SIMPLE
315 ? Offset(x - (focusedAreaRadius_ * 2 - dayWidth_) / 2 + focusedAreaRadius_, y + focusedAreaRadius_)
316 : Offset(x - (focusedAreaRadius_ * 2 - dayWidth_) / 2 + focusedAreaRadius_,
317 y - NormalizeToPx(1.0_vp) + focusedAreaRadius_);
318 Offset bgCircleStart = offset + circleCenter;
319 canvas->drawCircle(bgCircleStart.GetX(), bgCircleStart.GetY(), focusedAreaRadius_, paint);
320 #else
321 RSBrush brush;
322 brush.SetAntiAlias(true);
323
324 if (SystemProperties::GetDeviceType() == DeviceType::WATCH || type_ == CalendarType::SIMPLE) {
325 if (day.dayMark == "work" && showHoliday_) {
326 brush.SetColor(workDayMarkColor_);
327 } else if (day.dayMark == "off" && showHoliday_) {
328 brush.SetColor(offDayMarkColor_);
329 } else {
330 brush.SetColor(focusedAreaBackgroundColor_);
331 }
332 } else {
333 brush.SetColor(focusedAreaBackgroundColor_);
334 }
335 Offset circleCenter =
336 type_ == CalendarType::SIMPLE
337 ? Offset(x - (focusedAreaRadius_ * 2 - dayWidth_) / 2 + focusedAreaRadius_, y + focusedAreaRadius_)
338 : Offset(x - (focusedAreaRadius_ * 2 - dayWidth_) / 2 + focusedAreaRadius_,
339 y - NormalizeToPx(1.0_vp) + focusedAreaRadius_);
340 Offset bgCircleStart = offset + circleCenter;
341 canvas->AttachBrush(brush);
342 canvas->DrawCircle(RSPoint(bgCircleStart.GetX(), bgCircleStart.GetY()), focusedAreaRadius_);
343 canvas->DetachBrush();
344 #endif
345 }
346
347 #ifndef USE_ROSEN_DRAWING
DrawWeek(SkCanvas * canvas,const Offset & offset) const348 void RosenRenderCalendar::DrawWeek(SkCanvas* canvas, const Offset& offset) const
349 #else
350 void RosenRenderCalendar::DrawWeek(RSCanvas* canvas, const Offset& offset) const
351 #endif
352 {
353 uint32_t totalWeek = weekNumbers_.size();
354 #ifndef USE_GRAPHIC_TEXT_GINE
355 txt::TextStyle weekTextStyle;
356 weekTextStyle.color = weekColor_;
357 weekTextStyle.font_size = weekFontSize_;
358 if (cardCalendar_) {
359 weekTextStyle.font_weight = static_cast<txt::FontWeight>(FontWeight::W500);
360 }
361 #else
362 Rosen::TextStyle weekTextStyle;
363 weekTextStyle.color = weekColor_;
364 weekTextStyle.fontSize = weekFontSize_;
365 if (cardCalendar_) {
366 weekTextStyle.fontWeight = static_cast<Rosen::FontWeight>(FontWeight::W500);
367 }
368 #endif
369 weekTextStyle.locale = Localization::GetInstance()->GetFontLocale();
370 static const int32_t daysOfWeek = 7;
371 auto startDayOfWeek = dataAdapter_->GetStartDayOfWeek();
372 for (uint32_t column = 0; column < totalWeek; column++) {
373 double x = textDirection_ == TextDirection::LTR ? column * (weekWidth_ + colSpace_)
374 : (totalWeek - column - 1) * (weekWidth_ + colSpace_);
375 Offset weekNumberOffset = offset + Offset(x, topPadding_);
376 Rect boxRect { weekNumberOffset.GetX(), weekNumberOffset.GetY(), weekWidth_, weekHeight_ };
377 std::string newText { weekNumbers_[(startDayOfWeek + 1) % daysOfWeek] };
378 auto wText = StringUtils::ToWstring(newText);
379 if (wText.size() > 3) {
380 wText = wText.substr(0, 3);
381 newText = StringUtils::ToString(wText);
382 }
383 DrawCalendarText(canvas, newText, weekTextStyle, boxRect);
384 ++startDayOfWeek;
385 }
386 }
387
388 #ifndef USE_ROSEN_DRAWING
DrawBlurArea(SkCanvas * canvas,const Offset & offset,double x,double y) const389 void RosenRenderCalendar::DrawBlurArea(SkCanvas* canvas, const Offset& offset, double x, double y) const
390 #else
391 void RosenRenderCalendar::DrawBlurArea(RSCanvas* canvas, const Offset& offset, double x, double y) const
392 #endif
393 {
394 auto pipelineContext = GetContext().Upgrade();
395 if (!pipelineContext) {
396 LOGE("pipeline context is null");
397 return;
398 }
399 // start focus animation
400 #ifndef USE_ROSEN_DRAWING
401 SkPaint paint;
402 paint.setAntiAlias(true);
403 paint.setColor(blurAreaBackgroundColor_);
404 Offset circleCenter = Offset(x - (focusedAreaRadius_ * 2 - dayWidth_) / 2 + focusedAreaRadius_,
405 y - NormalizeToPx(1.0_vp) + focusedAreaRadius_);
406 Offset bgCircleStart = offset + circleCenter;
407 canvas->drawCircle(bgCircleStart.GetX(), bgCircleStart.GetY(), focusedAreaRadius_, paint);
408 #else
409 RSBrush brush;
410 brush.SetAntiAlias(true);
411 brush.SetColor(blurAreaBackgroundColor_);
412 Offset circleCenter = Offset(x - (focusedAreaRadius_ * 2 - dayWidth_) / 2 + focusedAreaRadius_,
413 y - NormalizeToPx(1.0_vp) + focusedAreaRadius_);
414 Offset bgCircleStart = offset + circleCenter;
415 canvas->AttachBrush(brush);
416 canvas->DrawCircle(RSPoint(bgCircleStart.GetX(), bgCircleStart.GetY()), focusedAreaRadius_);
417 canvas->DetachBrush();
418 #endif
419 }
420
421 #ifndef USE_ROSEN_DRAWING
422 #ifndef USE_GRAPHIC_TEXT_GINE
PaintDay(SkCanvas * canvas,const Offset & offset,const CalendarDay & day,txt::TextStyle & textStyle) const423 void RosenRenderCalendar::PaintDay(
424 SkCanvas* canvas, const Offset& offset, const CalendarDay& day, txt::TextStyle& textStyle) const
425 #else
426 void RosenRenderCalendar::PaintDay(
427 SkCanvas* canvas, const Offset& offset, const CalendarDay& day, Rosen::TextStyle& textStyle) const
428 #endif
429 #else
430 #ifndef USE_GRAPHIC_TEXT_GINE
431 void RosenRenderCalendar::PaintDay(
432 RSCanvas* canvas, const Offset& offset, const CalendarDay& day, txt::TextStyle& textStyle) const
433 #else
434 void RosenRenderCalendar::PaintDay(
435 RSCanvas* canvas, const Offset& offset, const CalendarDay& day, Rosen::TextStyle& textStyle) const
436 #endif
437 #endif
438 {
439 // paint day
440 Rect boxRect { offset.GetX(), offset.GetY(), dayWidth_, gregorianCalendarHeight_ };
441 Rect textRect;
442 #ifndef USE_GRAPHIC_TEXT_GINE
443 txt::TextStyle workStateStyle;
444 #else
445 Rosen::TextStyle workStateStyle;
446 #endif
447 if (!day.dayMark.empty() && showHoliday_ && type_ == CalendarType::SIMPLE) {
448 #ifndef USE_ROSEN_DRAWING
449 if (day.dayMark == "work") {
450 textStyle.color = SkColor(calendarTheme_.simpleWorkTextColor.GetValue());
451 } else if (day.dayMark == "off") {
452 textStyle.color = SkColor(calendarTheme_.simpleOffTextColor.GetValue());
453 }
454 #else
455 if (day.dayMark == "work") {
456 textStyle.color = RSColorQuad(calendarTheme_.simpleWorkTextColor.GetValue());
457 } else if (day.dayMark == "off") {
458 textStyle.color = RSColorQuad(calendarTheme_.simpleOffTextColor.GetValue());
459 }
460 #endif
461 }
462 if ((SystemProperties::GetDeviceType() == DeviceType::WATCH || type_ == CalendarType::SIMPLE) && IsToday(day) &&
463 !day.dayMark.empty() && showHoliday_) {
464 auto workStateOffset = offset + Offset(0, NormalizeToPx(calendarTheme_.workStateOffset));
465 boxRect.SetOffset(workStateOffset);
466 workStateStyle.color = Color::WHITE.GetValue();
467 #ifndef USE_GRAPHIC_TEXT_GINE
468 workStateStyle.font_size = dayFontSize_;
469 #else
470 workStateStyle.fontSize = dayFontSize_;
471 #endif
472 DrawCalendarText(canvas, day.dayMarkValue, workStateStyle, boxRect, textRect);
473 return;
474 }
475 if ((SystemProperties::GetDeviceType() == DeviceType::WATCH || type_ == CalendarType::SIMPLE) &&
476 day.month.month != currentMonth_.month) {
477 return;
478 }
479 auto dayStr = std::to_string(day.day);
480 dayStr = Localization::GetInstance()->NumberFormat(day.day);
481 DrawCalendarText(canvas, dayStr, textStyle, boxRect, textRect);
482
483 if (!day.dayMark.empty() && showHoliday_ && type_ != CalendarType::SIMPLE) {
484 if (cardCalendar_) {
485 InitWorkStateStyle(day, offset, workStateStyle, boxRect);
486 } else {
487 #ifndef USE_GRAPHIC_TEXT_GINE
488 workStateStyle.font_weight = static_cast<txt::FontWeight>(workStateFontWeight_);
489 #else
490 workStateStyle.fontWeight = static_cast<Rosen::FontWeight>(workStateFontWeight_);
491 #endif
492 workStateStyle.locale = Localization::GetInstance()->GetFontLocale();
493 boxRect = { textRect.GetOffset().GetX() + textRect.Width() - workStateHorizontalMovingDistance_,
494 textRect.GetOffset().GetY() + textRect.Height() - workStateVerticalMovingDistance_, workStateWidth_,
495 workStateWidth_ };
496 if (day.month.month == currentMonth_.month) {
497 if (day.dayMark == "work") {
498 #ifndef USE_GRAPHIC_TEXT_GINE
499 workStateStyle.font_size = workDayMarkSize_;
500 #else
501 workStateStyle.fontSize = workDayMarkSize_;
502 #endif
503 workStateStyle.color = workDayMarkColor_;
504 } else if (day.dayMark == "off") {
505 #ifndef USE_GRAPHIC_TEXT_GINE
506 workStateStyle.font_size = offDayMarkSize_;
507 #else
508 workStateStyle.fontSize = offDayMarkSize_;
509 #endif
510 workStateStyle.color = offDayMarkColor_;
511 }
512 } else {
513 #ifndef USE_ROSEN_DRAWING
514 if (day.dayMark == "work") {
515 #ifndef USE_GRAPHIC_TEXT_GINE
516 workStateStyle.font_size = workDayMarkSize_;
517 #else
518 workStateStyle.fontSize = workDayMarkSize_;
519 #endif
520 workStateStyle.color = isV2Component_ ? SkColorSetA(workDayMarkColor_, WEEKEND_TRANSPARENT)
521 : nonCurrentMonthWorkDayMarkColor_;
522 } else if (day.dayMark == "off") {
523 #ifndef USE_GRAPHIC_TEXT_GINE
524 workStateStyle.font_size = offDayMarkSize_;
525 #else
526 workStateStyle.fontSize = offDayMarkSize_;
527 #endif
528 workStateStyle.color = isV2Component_ ? SkColorSetA(offDayMarkColor_, WEEKEND_TRANSPARENT)
529 : nonCurrentMonthOffDayMarkColor_;
530 }
531 #else
532 if (day.dayMark == "work") {
533 #ifndef USE_GRAPHIC_TEXT_GINE
534 workStateStyle.font_size = workDayMarkSize_;
535 #else
536 workStateStyle.fontSize = workDayMarkSize_;
537 #endif
538 workStateStyle.color = isV2Component_ ?
539 RSColor::ColorQuadSetARGB(WEEKEND_TRANSPARENT, RSColor::ColorQuadGetR(workDayMarkColor_),
540 RSColor::ColorQuadGetG(workDayMarkColor_), RSColor::ColorQuadGetB(workDayMarkColor_))
541 : nonCurrentMonthWorkDayMarkColor_;
542 } else if (day.dayMark == "off") {
543 #ifndef USE_GRAPHIC_TEXT_GINE
544 workStateStyle.font_size = offDayMarkSize_;
545 #else
546 workStateStyle.fontSize = offDayMarkSize_;
547 #endif
548 workStateStyle.color = isV2Component_ ?
549 RSColor::ColorQuadSetARGB(WEEKEND_TRANSPARENT, RSColor::ColorQuadGetR(offDayMarkColor_),
550 RSColor::ColorQuadGetG(offDayMarkColor_), RSColor::ColorQuadGetB(offDayMarkColor_))
551 : nonCurrentMonthOffDayMarkColor_;
552 }
553 #endif
554 }
555 if (day.focused) {
556 workStateStyle.color = Color::BLACK.GetValue();
557 }
558 if (isV2Component_ && IsToday(day) && day.touched) {
559 workStateStyle.color = focusedDayColor_;
560 }
561 }
562 DrawCalendarText(canvas, day.dayMarkValue, workStateStyle, boxRect);
563 }
564 }
565
566 #ifndef USE_ROSEN_DRAWING
567 #ifndef USE_GRAPHIC_TEXT_GINE
PaintLunarDay(SkCanvas * canvas,const Offset & offset,const CalendarDay & day,const txt::TextStyle & textStyle) const568 void RosenRenderCalendar::PaintLunarDay(
569 SkCanvas* canvas, const Offset& offset, const CalendarDay& day, const txt::TextStyle& textStyle) const
570 #else
571 void RosenRenderCalendar::PaintLunarDay(
572 SkCanvas* canvas, const Offset& offset, const CalendarDay& day, const Rosen::TextStyle& textStyle) const
573 #endif
574 #else
575 #ifndef USE_GRAPHIC_TEXT_GINE
576 void RosenRenderCalendar::PaintLunarDay(
577 RSCanvas* canvas, const Offset& offset, const CalendarDay& day, const txt::TextStyle& textStyle) const
578 #else
579 void RosenRenderCalendar::PaintLunarDay(
580 RSCanvas* canvas, const Offset& offset, const CalendarDay& day, const Rosen::TextStyle& textStyle) const
581 #endif
582 #endif
583 {
584 Rect boxRect;
585 cardCalendar_ || isV2Component_
586 ? boxRect = { offset.GetX(), offset.GetY(), dayWidth_, NormalizeToPx(calendarTheme_.lunarHeight) }
587 : boxRect = { offset.GetX(), offset.GetY(), dayWidth_, dayHeight_ - gregorianCalendarHeight_ };
588 DrawCalendarText(canvas, day.lunarDay, textStyle, boxRect);
589 }
590
591 #ifndef USE_GRAPHIC_TEXT_GINE
SetNonFocusStyle(const CalendarDay & day,txt::TextStyle & dateTextStyle,txt::TextStyle & lunarTextStyle)592 void RosenRenderCalendar::SetNonFocusStyle(
593 const CalendarDay& day, txt::TextStyle& dateTextStyle, txt::TextStyle& lunarTextStyle)
594 #else
595 void RosenRenderCalendar::SetNonFocusStyle(
596 const CalendarDay& day, Rosen::TextStyle& dateTextStyle, Rosen::TextStyle& lunarTextStyle)
597 #endif
598 {
599 #ifndef USE_ROSEN_DRAWING
600 SkColor dateTextColor;
601 SkColor lunarTextColor;
602 if (day.month.month != currentMonth_.month) {
603 dateTextColor = nonCurrentMonthDayColor_;
604 lunarTextColor =
605 day.markLunarDay ? SkColorSetA(markLunarColor_, WEEKEND_TRANSPARENT) : nonCurrentMonthLunarColor_;
606 #else
607 RSColorQuad dateTextColor;
608 RSColorQuad lunarTextColor;
609 if (day.month.month != currentMonth_.month) {
610 dateTextColor = nonCurrentMonthDayColor_;
611 lunarTextColor = day.markLunarDay ? RSColor::ColorQuadSetARGB(WEEKEND_TRANSPARENT,
612 RSColor::ColorQuadGetR(markLunarColor_), RSColor::ColorQuadGetG(markLunarColor_),
613 RSColor::ColorQuadGetB(markLunarColor_)) : nonCurrentMonthLunarColor_;
614 #endif
615 } else if (IsToday(day)) {
616 dateTextColor = todayDayColor_;
617 lunarTextColor = todayLunarColor_;
618 } else if (IsOffDay(day)) {
619 dateTextColor = weekendDayColor_;
620 lunarTextColor = day.markLunarDay ? markLunarColor_ : weekendLunarColor_;
621 } else {
622 dateTextColor = dayColor_;
623 lunarTextColor = day.markLunarDay ? markLunarColor_ : lunarColor_;
624 }
625
626 dateTextStyle.color = dateTextColor;
627 lunarTextStyle.color = lunarTextColor;
628 }
629
630 void RosenRenderCalendar::DrawTouchedArea(RenderContext& context, Offset offset) const
631 {
632 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
633 if (!canvas) {
634 LOGE("paint canvas is null");
635 return;
636 }
637 if (IsValid(touchIndex_) && IsToday(calendarDays_[touchIndex_])) {
638 return;
639 }
640 offset += { touchCircleStrokeWidth_, 0 };
641 #ifndef USE_ROSEN_DRAWING
642 SkPaint paint;
643 paint.setAntiAlias(true);
644 paint.setColor(focusedAreaBackgroundColor_);
645 paint.setStrokeWidth(touchCircleStrokeWidth_);
646 paint.setStyle(SkPaint::kStroke_Style);
647 #else
648 RSPen pen;
649 pen.SetAntiAlias(true);
650 pen.SetColor(focusedAreaBackgroundColor_);
651 pen.SetWidth(touchCircleStrokeWidth_);
652 #endif
653 static const Dimension dateOffset = 4.0_vp;
654 const static int32_t totalWeek = 7;
655 int32_t column = touchIndex_ % totalWeek;
656 double dailyRowSpace = rowCount_ == 5 ? dailyFiveRowSpace_ : dailySixRowSpace_;
657 double dayNumberStartY = topPadding_ + weekHeight_ + weekAndDayRowSpace_ + NormalizeToPx(dateOffset);
658 double x = textDirection_ == TextDirection::LTR ? column * (dayWidth_ + colSpace_)
659 : (totalWeek - column - 1) * (dayWidth_ + colSpace_);
660 double y = (touchIndex_ / 7) * (dayHeight_ + dailyRowSpace) + dayNumberStartY;
661 Offset circleCenter = Offset(x - (focusedAreaRadius_ * 2 - dayWidth_) / 2 + focusedAreaRadius_,
662 y - NormalizeToPx(1.0_vp) + focusedAreaRadius_);
663 Offset bgCircleStart = offset + circleCenter;
664 #ifndef USE_ROSEN_DRAWING
665 canvas->drawCircle(bgCircleStart.GetX(), bgCircleStart.GetY(), focusedAreaRadius_, paint);
666 #else
667 canvas->AttachPen(pen);
668 canvas->DrawCircle(RSPoint(bgCircleStart.GetX(), bgCircleStart.GetY()), focusedAreaRadius_);
669 canvas->DetachPen();
670 #endif
671 }
672
673 #ifndef USE_ROSEN_DRAWING
674 void RosenRenderCalendar::DrawCardCalendar(
675 SkCanvas* canvas, const Offset& offset, const Offset& dayOffset, const CalendarDay& day, int32_t dateNumber)
676 #else
677 void RosenRenderCalendar::DrawCardCalendar(
678 RSCanvas* canvas, const Offset& offset, const Offset& dayOffset, const CalendarDay& day, int32_t dateNumber)
679 #endif
680 {
681 #ifndef USE_GRAPHIC_TEXT_GINE
682 txt::TextStyle dateTextStyle;
683 txt::TextStyle lunarTextStyle;
684 #else
685 Rosen::TextStyle dateTextStyle;
686 Rosen::TextStyle lunarTextStyle;
687 #endif
688 InitTextStyle(dateTextStyle, lunarTextStyle);
689 SetNonFocusStyle(day, dateTextStyle, lunarTextStyle);
690 dateTextStyle.locale = Localization::GetInstance()->GetFontLocale();
691 auto x = dayOffset.GetX();
692 auto y = dayOffset.GetY();
693 if (isV2Component_) {
694 if (calendarController_->FirstSetToday() && IsToday(day) && (day.month.month == currentMonth_.month)) {
695 calendarDays_[day.index].touched = true;
696 touchIndex_ = day.index;
697 calendarController_->SetFirstSetToday(false);
698 }
699 }
700 if (IsToday(day) && (day.month.month == currentMonth_.month)) {
701 dateTextStyle.color = isV2Component_ ? focusedAreaBackgroundColor_ : focusedDayColor_;
702 lunarTextStyle.color = isV2Component_ ? focusedAreaBackgroundColor_ : focusedDayColor_;
703 if (!isV2Component_) {
704 DrawFocusedArea(canvas, offset, day, x, y);
705 }
706 }
707
708 if (isV2Component_ && day.touched) {
709 if (IsToday(day) && (day.month.month == currentMonth_.month)) {
710 dateTextStyle.color = focusedDayColor_;
711 lunarTextStyle.color = focusedDayColor_;
712 DrawFocusedArea(canvas, offset, day, x, y);
713 }
714 }
715
716 if (needShrink_) {
717 Offset dateNumberOffset = offset + Offset(x, y + (focusedAreaRadius_ - gregorianCalendarHeight_ / 2));
718 PaintDay(canvas, dateNumberOffset, day, dateTextStyle);
719 return;
720 }
721
722 auto dayYAxisOffset = calendarTheme_.dayYAxisOffset;
723 Offset dateNumberOffset = offset + Offset(x, y + NormalizeToPx(dayYAxisOffset));
724 PaintDay(canvas, dateNumberOffset, day, dateTextStyle);
725
726 if (dataAdapter_->ShowLunar() && !day.lunarDay.empty()) {
727 auto lunarDayYAxisOffset = calendarTheme_.lunarDayYAxisOffset;
728 Offset lunarDayOffset = offset + Offset(x, y + NormalizeToPx(lunarDayYAxisOffset));
729 PaintLunarDay(canvas, lunarDayOffset, day, lunarTextStyle);
730 }
731
732 if (day.isFirstOfLunar) {
733 auto underscoreXAxisOffset = calendarTheme_.underscoreXAxisOffset;
734 auto underscoreYAxisOffset = calendarTheme_.underscoreYAxisOffset;
735 Offset underscoreOffset =
736 offset + Offset(x + NormalizeToPx(underscoreXAxisOffset), y + NormalizeToPx(underscoreYAxisOffset));
737 PaintUnderscore(canvas, underscoreOffset, day);
738 }
739
740 if (day.hasSchedule) {
741 auto scheduleMarkerXAxisOffset = calendarTheme_.scheduleMarkerXAxisOffset;
742 auto scheduleMarkerYAxisOffset = calendarTheme_.scheduleMarkerYAxisOffset;
743 Offset scheduleMarkerOffset =
744 offset + Offset(x + NormalizeToPx(scheduleMarkerXAxisOffset), y + NormalizeToPx(scheduleMarkerYAxisOffset));
745 PaintScheduleMarker(canvas, scheduleMarkerOffset, day);
746 }
747 }
748
749 #ifndef USE_ROSEN_DRAWING
750 void RosenRenderCalendar::DrawTvCalendar(
751 SkCanvas* canvas, const Offset& offset, const Offset& dayOffset, const CalendarDay& day, int32_t dateNumber)
752 #else
753 void RosenRenderCalendar::DrawTvCalendar(RSCanvas* canvas,
754 const Offset& offset, const Offset& dayOffset, const CalendarDay& day, int32_t dateNumber)
755 #endif
756 {
757 if ((SystemProperties::GetDeviceType() == DeviceType::WATCH || type_ == CalendarType::SIMPLE) &&
758 day.month.month != currentMonth_.month) {
759 return;
760 }
761 #ifndef USE_GRAPHIC_TEXT_GINE
762 txt::TextStyle dateTextStyle;
763 txt::TextStyle lunarTextStyle;
764 #else
765 Rosen::TextStyle dateTextStyle;
766 Rosen::TextStyle lunarTextStyle;
767 #endif
768 InitTextStyle(dateTextStyle, lunarTextStyle);
769 dateTextStyle.locale = Localization::GetInstance()->GetFontLocale();
770 lunarTextStyle.locale = Localization::GetInstance()->GetFontLocale();
771
772 auto renderSwiper = calendarController_->GetRenderSwiper();
773 if (!renderSwiper) {
774 return;
775 }
776 int32_t selectedDay = selectedDayNumber_ + firstDayIndex_ - 1;
777 auto x = dayOffset.GetX();
778 auto y = dayOffset.GetY();
779 if (SystemProperties::GetDeviceType() == DeviceType::WATCH || type_ == CalendarType::SIMPLE) {
780 if (IsToday(day) && (day.month.month == currentMonth_.month)) {
781 dateTextStyle.color = focusedDayColor_;
782 lunarTextStyle.color = focusedDayColor_;
783 DrawFocusedArea(canvas, offset, day, x, y);
784 } else {
785 SetNonFocusStyle(day, dateTextStyle, lunarTextStyle);
786 }
787 } else {
788 if (day.focused && day.month.month == currentMonth_.month && !renderSwiper->GetMoveStatus() &&
789 indexOfContainer_ == calendarController_->GetCurrentIndex()) {
790 dateTextStyle.color = focusedDayColor_;
791 lunarTextStyle.color = focusedLunarColor_;
792 DrawFocusedArea(canvas, offset, day, x, y);
793 } else {
794 SetNonFocusStyle(day, dateTextStyle, lunarTextStyle);
795 }
796 }
797
798 if (selectedDay == (dateNumber - 1) && !calendarFocusStatus_ && !renderSwiper->GetMoveStatus() &&
799 hasRequestFocus_) {
800 DrawBlurArea(canvas, offset, x, y);
801 }
802
803 if (dataAdapter_->ShowLunar() && !day.lunarDay.empty()) {
804 // paint day
805 Offset dateNumberOffset = offset + Offset(x, y);
806 PaintDay(canvas, dateNumberOffset, day, dateTextStyle);
807
808 // paint lunar day
809 Offset lunarDayOffset = offset + Offset(x, y + gregorianCalendarHeight_);
810 PaintLunarDay(canvas, lunarDayOffset, day, lunarTextStyle);
811 } else {
812 // when there is no lunar calendar, the date is displayed in the center
813 Offset dateNumberOffset = offset + Offset(x, y + (focusedAreaRadius_ - gregorianCalendarHeight_ / 2));
814 PaintDay(canvas, dateNumberOffset, day, dateTextStyle);
815 }
816 }
817
818 #ifndef USE_GRAPHIC_TEXT_GINE
819 void RosenRenderCalendar::InitTextStyle(txt::TextStyle& dateTextStyle, txt::TextStyle& lunarTextStyle)
820 {
821 dateTextStyle.font_size = dayFontSize_;
822 dateTextStyle.font_weight = static_cast<txt::FontWeight>(dayFontWeight_);
823
824 lunarTextStyle.font_size = lunarDayFontSize_;
825 lunarTextStyle.font_weight = static_cast<txt::FontWeight>(lunarDayFontWeight_);
826 }
827 #else
828 void RosenRenderCalendar::InitTextStyle(Rosen::TextStyle& dateTextStyle, Rosen::TextStyle& lunarTextStyle)
829 {
830 dateTextStyle.fontSize = dayFontSize_;
831 dateTextStyle.fontWeight = static_cast<Rosen::FontWeight>(dayFontWeight_);
832
833 lunarTextStyle.fontSize = lunarDayFontSize_;
834 lunarTextStyle.fontWeight = static_cast<Rosen::FontWeight>(lunarDayFontWeight_);
835 }
836 #endif
837
838 #ifndef USE_ROSEN_DRAWING
839 void RosenRenderCalendar::PaintUnderscore(SkCanvas* canvas, const Offset& offset, const CalendarDay& day)
840 {
841 auto underscoreWidth = calendarTheme_.underscoreWidth;
842 auto underscoreLength = calendarTheme_.underscoreLength;
843 SkPaint paint;
844 SkColor color;
845 if (day.month.month != currentMonth_.month) {
846 color = SkColorSetA(focusedAreaBackgroundColor_, NON_CURRENT_MONTH_TRANSPARENT);
847 } else if (IsToday(day)) {
848 color = isV2Component_ && !day.touched ? SkColorSetA(focusedAreaBackgroundColor_, CURRENT_MONTH_TRANSPARENT)
849 : focusedDayColor_;
850 } else if (day.weekend) {
851 color = SkColorSetA(focusedAreaBackgroundColor_, WEEKEND_TRANSPARENT);
852 } else {
853 color = SkColorSetA(focusedAreaBackgroundColor_, CURRENT_MONTH_TRANSPARENT);
854 }
855 paint.setAntiAlias(true);
856 paint.setColor(color);
857 paint.setStyle(SkPaint::Style::kStroke_Style);
858 paint.setStrokeWidth(NormalizeToPx(underscoreWidth));
859 canvas->drawLine(offset.GetX(), offset.GetY() + NormalizeToPx(underscoreWidth) / 2,
860 offset.GetX() + NormalizeToPx(underscoreLength), offset.GetY() + NormalizeToPx(underscoreWidth) / 2, paint);
861 }
862 #else
863 void RosenRenderCalendar::PaintUnderscore(RSCanvas* canvas, const Offset& offset, const CalendarDay& day)
864 {
865 auto underscoreWidth = calendarTheme_.underscoreWidth;
866 auto underscoreLength = calendarTheme_.underscoreLength;
867 RSPen pen;
868 RSColorQuad color;
869 if (day.month.month != currentMonth_.month) {
870 color = RSColor::ColorQuadSetARGB(NON_CURRENT_MONTH_TRANSPARENT,
871 RSColor::ColorQuadGetR(focusedAreaBackgroundColor_), RSColor::ColorQuadGetG(focusedAreaBackgroundColor_),
872 RSColor::ColorQuadGetB(focusedAreaBackgroundColor_));
873 } else if (IsToday(day)) {
874 color = isV2Component_ && !day.touched
875 ? RSColor::ColorQuadSetARGB(CURRENT_MONTH_TRANSPARENT, RSColor::ColorQuadGetR(focusedAreaBackgroundColor_),
876 RSColor::ColorQuadGetG(focusedAreaBackgroundColor_), RSColor::ColorQuadGetB(focusedAreaBackgroundColor_))
877 : focusedDayColor_;
878 } else if (day.weekend) {
879 color = RSColor::ColorQuadSetARGB(WEEKEND_TRANSPARENT, RSColor::ColorQuadGetR(focusedAreaBackgroundColor_),
880 RSColor::ColorQuadGetG(focusedAreaBackgroundColor_), RSColor::ColorQuadGetB(focusedAreaBackgroundColor_));
881 } else {
882 color = RSColor::ColorQuadSetARGB(CURRENT_MONTH_TRANSPARENT,
883 RSColor::ColorQuadGetR(focusedAreaBackgroundColor_), RSColor::ColorQuadGetG(focusedAreaBackgroundColor_),
884 RSColor::ColorQuadGetB(focusedAreaBackgroundColor_));
885 }
886 pen.SetAntiAlias(true);
887 pen.SetColor(color);
888 pen.SetWidth(NormalizeToPx(underscoreWidth));
889 canvas->AttachPen(pen);
890 canvas->DrawLine(RSPoint(offset.GetX(), offset.GetY() + NormalizeToPx(underscoreWidth) / 2),
891 RSPoint(
892 offset.GetX() + NormalizeToPx(underscoreLength), offset.GetY() + NormalizeToPx(underscoreWidth) / 2));
893 canvas->DetachPen();
894 }
895 #endif
896
897 #ifndef USE_ROSEN_DRAWING
898 void RosenRenderCalendar::PaintScheduleMarker(SkCanvas* canvas, const Offset& offset, const CalendarDay& day)
899 {
900 auto scheduleMarkerRadius = calendarTheme_.scheduleMarkerRadius;
901 SkPaint paint;
902 SkColor color;
903 if (day.month.month != currentMonth_.month) {
904 color = SkColorSetA(focusedAreaBackgroundColor_, NON_CURRENT_MONTH_TRANSPARENT);
905 } else if (IsToday(day)) {
906 color = isV2Component_ && !day.touched ? SkColorSetA(focusedAreaBackgroundColor_, SCHEDULE_MARKER_TRANSPARENT)
907 : focusedDayColor_;
908 } else {
909 color = SkColorSetA(focusedAreaBackgroundColor_, SCHEDULE_MARKER_TRANSPARENT);
910 }
911 paint.setAntiAlias(true);
912 paint.setColor(color);
913 canvas->drawCircle(offset.GetX(), offset.GetY(), NormalizeToPx(scheduleMarkerRadius), paint);
914 }
915 #else
916 void RosenRenderCalendar::PaintScheduleMarker(RSCanvas* canvas, const Offset& offset, const CalendarDay& day)
917 {
918 auto scheduleMarkerRadius = calendarTheme_.scheduleMarkerRadius;
919 RSBrush brush;
920 RSColorQuad color;
921 if (day.month.month != currentMonth_.month) {
922 color = RSColor::ColorQuadSetARGB(NON_CURRENT_MONTH_TRANSPARENT,
923 RSColor::ColorQuadGetR(focusedAreaBackgroundColor_), RSColor::ColorQuadGetG(focusedAreaBackgroundColor_),
924 RSColor::ColorQuadGetB(focusedAreaBackgroundColor_));
925 } else if (IsToday(day)) {
926 color = isV2Component_ && !day.touched
927 ? RSColor::ColorQuadSetARGB(SCHEDULE_MARKER_TRANSPARENT,
928 RSColor::ColorQuadGetR(focusedAreaBackgroundColor_), RSColor::ColorQuadGetG(focusedAreaBackgroundColor_),
929 RSColor::ColorQuadGetB(focusedAreaBackgroundColor_)) : focusedDayColor_;
930 } else {
931 color = RSColor::ColorQuadSetARGB(SCHEDULE_MARKER_TRANSPARENT,
932 RSColor::ColorQuadGetR(focusedAreaBackgroundColor_), RSColor::ColorQuadGetG(focusedAreaBackgroundColor_),
933 RSColor::ColorQuadGetB(focusedAreaBackgroundColor_));
934 }
935 brush.SetAntiAlias(true);
936 brush.SetColor(color);
937 canvas->AttachBrush(brush);
938 canvas->DrawCircle(RSPoint(offset.GetX(), offset.GetY()), NormalizeToPx(scheduleMarkerRadius));
939 canvas->DetachBrush();
940 }
941 #endif
942
943 #ifndef USE_GRAPHIC_TEXT_GINE
944 void RosenRenderCalendar::InitWorkStateStyle(
945 const CalendarDay& day, const Offset& offset, txt::TextStyle& workStateStyle, Rect& boxRect) const
946 {
947 workStateStyle.font_weight = static_cast<txt::FontWeight>(FontWeight::W500);
948 #else
949 void RosenRenderCalendar::InitWorkStateStyle(
950 const CalendarDay& day, const Offset& offset, Rosen::TextStyle& workStateStyle, Rect& boxRect) const
951 {
952 workStateStyle.fontWeight = static_cast<Rosen::FontWeight>(FontWeight::W500);
953 #endif
954 workStateStyle.locale = Localization::GetInstance()->GetFontLocale();
955 static const Dimension workStateWidth = 8.0_vp;
956 static const int32_t twoDigitMaker = 10;
957 static const Dimension OneDigitXAxisOffset = 26.0_vp;
958 static const Dimension workStateYAxisOffset = 6.0_vp;
959 static const Dimension twoDigitXAxisOffset = 31.0_vp;
960 if (day.day < twoDigitMaker) {
961 boxRect = { offset.GetX() + NormalizeToPx(OneDigitXAxisOffset),
962 offset.GetY() + NormalizeToPx(workStateYAxisOffset), NormalizeToPx(workStateWidth),
963 NormalizeToPx(workStateWidth) };
964 } else {
965 boxRect = { offset.GetX() + NormalizeToPx(twoDigitXAxisOffset),
966 offset.GetY() + NormalizeToPx(workStateYAxisOffset), NormalizeToPx(workStateWidth),
967 NormalizeToPx(workStateWidth) };
968 }
969
970 #ifndef USE_GRAPHIC_TEXT_GINE
971 workStateStyle.font_size = NormalizeToPx(workStateWidth);
972 #else
973 workStateStyle.fontSize = NormalizeToPx(workStateWidth);
974 #endif
975
976 if (day.month.month != currentMonth_.month) {
977 #ifndef USE_ROSEN_DRAWING
978 auto offColor = SkColorSetA(markLunarColor_, WEEKEND_TRANSPARENT);
979 auto workColor = SkColorSetA(workDayMarkColor_, WEEKEND_TRANSPARENT);
980 #else
981 auto offColor = RSColor::ColorQuadSetARGB(WEEKEND_TRANSPARENT, RSColor::ColorQuadGetR(markLunarColor_),
982 RSColor::ColorQuadGetG(markLunarColor_), RSColor::ColorQuadGetB(markLunarColor_));
983 auto workColor = RSColor::ColorQuadSetARGB(WEEKEND_TRANSPARENT, RSColor::ColorQuadGetR(workDayMarkColor_),
984 RSColor::ColorQuadGetG(workDayMarkColor_), RSColor::ColorQuadGetB(workDayMarkColor_));
985 #endif
986 SetWorkStateStyle(day, workColor, offColor, workStateStyle);
987 } else if (IsToday(day)) {
988 SetWorkStateStyle(day, focusedDayColor_, focusedDayColor_, workStateStyle);
989 } else if (IsOffDay(day)) {
990 auto offColor = markLunarColor_;
991 auto workColor = workDayMarkColor_;
992 SetWorkStateStyle(day, workColor, offColor, workStateStyle);
993 } else {
994 SetWorkStateStyle(day, workDayMarkColor_, markLunarColor_, workStateStyle);
995 }
996 }
997
998 #ifndef USE_ROSEN_DRAWING
999 #ifndef USE_GRAPHIC_TEXT_GINE
1000 void RosenRenderCalendar::SetWorkStateStyle(
1001 const CalendarDay& day, SkColor workColor, SkColor offColor, txt::TextStyle& workStateStyle) const
1002 #else
1003 void RosenRenderCalendar::SetWorkStateStyle(
1004 const CalendarDay& day, SkColor workColor, SkColor offColor, Rosen::TextStyle& workStateStyle) const
1005 #endif
1006 #else
1007 #ifndef USE_GRAPHIC_TEXT_GINE
1008 void RosenRenderCalendar::SetWorkStateStyle(const CalendarDay& day, RSColorQuad workColor,
1009 RSColorQuad offColor, txt::TextStyle& workStateStyle) const
1010 #else
1011 void RosenRenderCalendar::SetWorkStateStyle(
1012 const CalendarDay& day, SkColor workColor, RSColorQuad offColor, Rosen::TextStyle& workStateStyle) const
1013 #endif
1014 #endif
1015 {
1016 if (day.dayMark == "work") {
1017 workStateStyle.color = workColor;
1018 } else if (day.dayMark == "off") {
1019 workStateStyle.color = offColor;
1020 }
1021 }
1022
1023 void RosenRenderCalendar::SetCalendarTheme()
1024 {
1025 auto theme = GetTheme<CalendarTheme>();
1026 if (cardCalendar_ && theme) {
1027 calendarTheme_ = theme->GetCardCalendarTheme();
1028 }
1029 #ifndef USE_ROSEN_DRAWING
1030 touchColor_ = SkColor(calendarTheme_.touchColor.GetValue());
1031 weekColor_ = SkColor(calendarTheme_.weekColor.GetValue());
1032 dayColor_ = SkColor(calendarTheme_.dayColor.GetValue());
1033 lunarColor_ = SkColor(calendarTheme_.lunarColor.GetValue());
1034 weekendDayColor_ = SkColor(calendarTheme_.weekendDayColor.GetValue());
1035 weekendLunarColor_ = SkColor(calendarTheme_.weekendLunarColor.GetValue());
1036 todayDayColor_ = SkColor(calendarTheme_.todayColor.GetValue());
1037 todayLunarColor_ = SkColor(calendarTheme_.todayLunarColor.GetValue());
1038 nonCurrentMonthDayColor_ = SkColor(calendarTheme_.nonCurrentMonthDayColor.GetValue());
1039 nonCurrentMonthLunarColor_ = SkColor(calendarTheme_.nonCurrentMonthLunarColor.GetValue());
1040 workDayMarkColor_ = SkColor(calendarTheme_.workDayMarkColor.GetValue());
1041 offDayMarkColor_ = SkColor(calendarTheme_.offDayMarkColor.GetValue());
1042 nonCurrentMonthWorkDayMarkColor_ = SkColor(calendarTheme_.nonCurrentMonthWorkDayMarkColor.GetValue());
1043 nonCurrentMonthOffDayMarkColor_ = SkColor(calendarTheme_.nonCurrentMonthOffDayMarkColor.GetValue());
1044 focusedDayColor_ = SkColor(calendarTheme_.focusedDayColor.GetValue());
1045 focusedLunarColor_ = SkColor(calendarTheme_.focusedLunarColor.GetValue());
1046 focusedAreaBackgroundColor_ = SkColor(calendarTheme_.focusedAreaBackgroundColor.GetValue());
1047 blurAreaBackgroundColor_ = SkColor(calendarTheme_.blurAreaBackgroundColor.GetValue());
1048 markLunarColor_ = SkColor(calendarTheme_.markLunarColor.GetValue());
1049 #else
1050 touchColor_ = RSColorQuad(calendarTheme_.touchColor.GetValue());
1051 weekColor_ = RSColorQuad(calendarTheme_.weekColor.GetValue());
1052 dayColor_ = RSColorQuad(calendarTheme_.dayColor.GetValue());
1053 lunarColor_ = RSColorQuad(calendarTheme_.lunarColor.GetValue());
1054 weekendDayColor_ = RSColorQuad(calendarTheme_.weekendDayColor.GetValue());
1055 weekendLunarColor_ = RSColorQuad(calendarTheme_.weekendLunarColor.GetValue());
1056 todayDayColor_ = RSColorQuad(calendarTheme_.todayColor.GetValue());
1057 todayLunarColor_ = RSColorQuad(calendarTheme_.todayLunarColor.GetValue());
1058 nonCurrentMonthDayColor_ = RSColorQuad(calendarTheme_.nonCurrentMonthDayColor.GetValue());
1059 nonCurrentMonthLunarColor_ = RSColorQuad(calendarTheme_.nonCurrentMonthLunarColor.GetValue());
1060 workDayMarkColor_ = RSColorQuad(calendarTheme_.workDayMarkColor.GetValue());
1061 offDayMarkColor_ = RSColorQuad(calendarTheme_.offDayMarkColor.GetValue());
1062 nonCurrentMonthWorkDayMarkColor_ = RSColorQuad(calendarTheme_.nonCurrentMonthWorkDayMarkColor.GetValue());
1063 nonCurrentMonthOffDayMarkColor_ = RSColorQuad(calendarTheme_.nonCurrentMonthOffDayMarkColor.GetValue());
1064 focusedDayColor_ = RSColorQuad(calendarTheme_.focusedDayColor.GetValue());
1065 focusedLunarColor_ = RSColorQuad(calendarTheme_.focusedLunarColor.GetValue());
1066 focusedAreaBackgroundColor_ = RSColorQuad(calendarTheme_.focusedAreaBackgroundColor.GetValue());
1067 blurAreaBackgroundColor_ = RSColorQuad(calendarTheme_.blurAreaBackgroundColor.GetValue());
1068 markLunarColor_ = RSColorQuad(calendarTheme_.markLunarColor.GetValue());
1069 #endif
1070 dayFontWeight_ = StringUtils::StringToFontWeight(calendarTheme_.dayFontWeight);
1071 lunarDayFontWeight_ = StringUtils::StringToFontWeight(calendarTheme_.lunarDayFontWeight);
1072 workStateFontWeight_ = StringUtils::StringToFontWeight(calendarTheme_.workStateFontWeight);
1073 }
1074
1075 bool RosenRenderCalendar::IsOffDay(const CalendarDay& dayInfo) const
1076 {
1077 auto weekday = Date::CalculateWeekDay(dayInfo.month.year, dayInfo.month.month + 1, dayInfo.day);
1078 std::vector<std::string> days;
1079 StringUtils::StringSplitter(offDays_, ',', days);
1080 bool setOffDay = true;
1081 for (const auto& day : days) {
1082 auto num = StringUtils::StringToInt(day);
1083 if (num < 0 || num > 6) {
1084 setOffDay = false;
1085 break;
1086 }
1087 if (num == weekday) {
1088 return true;
1089 }
1090 }
1091 if (!setOffDay) {
1092 if (weekday == 5 || weekday == 6) { // set default weekend
1093 return true;
1094 }
1095 }
1096 return false;
1097 }
1098
1099 void RosenRenderCalendar::AddContentLayer(RenderContext& context)
1100 {
1101 #ifdef OHOS_PLATFORM
1102 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
1103 if (!drawCmdList_) {
1104 return;
1105 }
1106 drawCmdList_->Playback(*canvas);
1107 #endif
1108 }
1109
1110 } // namespace OHOS::Ace
1111