From 2fd15ff98f0eece63d7bd6d091ece99793cd2c65 Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Fri, 7 Nov 2025 13:52:42 +0800 Subject: [PATCH] =?utf8?q?=E5=A2=9E=E5=8A=A0=E9=98=B4=E5=BD=B1Lable?= =?utf8?q?=E5=AD=90=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../components/ui_label_ext_with_shadow.h | 84 ++++++++++++++++ .../components/ui_label_ext_with_shadow.cpp | 75 +++++++++++++++ .../ui/frameworks/common/text_with_shadow.cpp | 91 ++++++++++++++++++ .../uikit/ui/frameworks/draw/draw_label.cpp | 64 +++++++++++++ .../gui/uikit/ui/frameworks/draw/draw_label.h | 2 + .../interfaces/kits/common/text_with_shadow.h | 95 +++++++++++++++++++ 6 files changed, 411 insertions(+) create mode 100644 code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_label_ext_with_shadow.h create mode 100644 code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_label_ext_with_shadow.cpp create mode 100644 code/sdk/middleware/services/gui/uikit/ui/frameworks/common/text_with_shadow.cpp create mode 100644 code/sdk/middleware/services/gui/uikit/ui/interfaces/kits/common/text_with_shadow.h diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_label_ext_with_shadow.h b/code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_label_ext_with_shadow.h new file mode 100644 index 000000000..a760e6175 --- /dev/null +++ b/code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_label_ext_with_shadow.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRAPHIC_LITE_UI_LABEL_EXT_WITH_SHADOW_H +#define GRAPHIC_LITE_UI_LABEL_EXT_WITH_SHADOW_H + +#include "graphic_config.h" +#include "components/ui_label_ext.h" +#include "common/text_with_shadow.h" + +#if ENABLE_FONT_VECTOR_GLOBAL || ENABLE_SHAPING +namespace OHOS { +/** + * @brief Class to extend UILabel with shadow effect support. + * The shadow is drawn 2 pixels to the right in black color. + */ +class UILabelExtWithShadow : public UILabelExt { +public: + /** + * @brief A constructor used to create a UILabelExtWithShadow instance. + */ + UILabelExtWithShadow(); + + /** + * @brief A destructor used to delete the UILabelExtWithShadow instance. + */ + ~UILabelExtWithShadow() override {} + + /** + * @brief Obtains the view type. + * @return Returns the view type. + */ + UIViewType GetViewType() const override + { + return UI_LABEL_EXT; + } + + /** + * @brief Sets the shadow offset in X direction. + * @param offsetX The shadow offset in pixels (default: 2). + */ + void SetShadowOffsetX(int16_t offsetX); + + /** + * @brief Gets the shadow offset in X direction. + * @return Returns the shadow offset in pixels. + */ + int16_t GetShadowOffsetX() const; + + /** + * @brief Sets the shadow offset in Y direction. + * @param offsetY The shadow offset in pixels (default: 2). + */ + void SetShadowOffsetY(int16_t offsetY); + + /** + * @brief Gets the shadow offset in Y direction. + * @return Returns the shadow offset in pixels. + */ + int16_t GetShadowOffsetY() const; + +protected: + /** + * @brief Initialize label text with shadow effect. + * Overrides UILabelExt::InitLabelText to use TextWithShadow. + */ + void InitLabelText() override; +}; +} // OHOS +#endif // ENABLE_FONT_VECTOR_GLOBAL || ENABLE_SHAPING +#endif // GRAPHIC_LITE_UI_LABEL_EXT_WITH_SHADOW_H + diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_label_ext_with_shadow.cpp b/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_label_ext_with_shadow.cpp new file mode 100644 index 000000000..0b53f5490 --- /dev/null +++ b/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_label_ext_with_shadow.cpp @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "components/ui_label_ext_with_shadow.h" +#include "common/text_with_shadow.h" + +namespace OHOS { +UILabelExtWithShadow::UILabelExtWithShadow() : UILabelExt() +{ +} + +void UILabelExtWithShadow::InitLabelText() +{ + if (labelText_ == nullptr) { + labelText_ = new TextWithShadow(); + } +} + +void UILabelExtWithShadow::SetShadowOffsetX(int16_t offsetX) +{ + InitLabelText(); + if (labelText_ != nullptr) { + TextWithShadow* textWithShadow = static_cast(labelText_); + if (textWithShadow != nullptr) { + textWithShadow->SetShadowOffsetX(offsetX); + } + } +} + +int16_t UILabelExtWithShadow::GetShadowOffsetX() const +{ + if (labelText_ != nullptr) { + const TextWithShadow* textWithShadow = static_cast(labelText_); + if (textWithShadow != nullptr) { + return textWithShadow->GetShadowOffsetX(); + } + } + return 2; // Default shadow offset +} + +void UILabelExtWithShadow::SetShadowOffsetY(int16_t offsetY) +{ + InitLabelText(); + if (labelText_ != nullptr) { + TextWithShadow* textWithShadow = static_cast(labelText_); + if (textWithShadow != nullptr) { + textWithShadow->SetShadowOffsetY(offsetY); + } + } +} + +int16_t UILabelExtWithShadow::GetShadowOffsetY() const +{ + if (labelText_ != nullptr) { + const TextWithShadow* textWithShadow = static_cast(labelText_); + if (textWithShadow != nullptr) { + return textWithShadow->GetShadowOffsetY(); + } + } + return 2; // Default shadow offset +} +} // namespace OHOS + diff --git a/code/sdk/middleware/services/gui/uikit/ui/frameworks/common/text_with_shadow.cpp b/code/sdk/middleware/services/gui/uikit/ui/frameworks/common/text_with_shadow.cpp new file mode 100644 index 000000000..cb55f1d91 --- /dev/null +++ b/code/sdk/middleware/services/gui/uikit/ui/frameworks/common/text_with_shadow.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common/text_with_shadow.h" +#include "draw/draw_label.h" +#include "draw/draw_utils.h" +#include "font/ui_font.h" +#include + +namespace OHOS { +void TextWithShadow::Draw(BufferInfo& gfxDstBuffer, + const Rect& mask, + const Rect& coords, + const Style& style, + int16_t offsetX, + uint16_t tailIndex, + OpacityType opaScale) +{ + if ((text_ == nullptr) || (strlen(text_) == 0) || (fontSize_ == 0)) { + return; + } + UIFont::GetInstance()->SetCurrentFontId(fontId_, fontSize_); + Rect drawMask = mask; + + if (transMap_ == nullptr) { + drawMask.Intersect(drawMask, coords); + } + + if (!drawMask.IsValid()) { + return; + } + + Point offset = {offsetX, 0}; + int16_t lineMaxWidth = expandWidth_ ? textSize_.x : coords.GetWidth(); + int16_t lineHeight = style.lineHeight_; + if (lineHeight == 0) { + lineHeight = UIFont::GetInstance()->GetHeight() + style.lineSpace_; + } + uint16_t lineBegin = 0; + uint32_t maxLineBytes = 0; + uint16_t lineCount = GetLine(lineMaxWidth, style.letterSpace_, tailIndex, maxLineBytes); + Point pos; + if (lineHeight == style.lineHeight_) { + pos.y = TextPositionY(coords, (lineCount * lineHeight)); + } else { + pos.y = TextPositionY(coords, (lineCount * lineHeight - style.lineSpace_)); + } + OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.textOpa_); + bool isTransValid = false; + if (transMap_ != nullptr && !transMap_->IsInvalid()) { + isTransValid = true; + } + for (int i = 0; i < lineCount; i++) { + if (!isTransValid && pos.y > drawMask.GetBottom()) { + return; + } + int16_t nextLine = pos.y + lineHeight; + if (isTransValid || nextLine >= drawMask.GetTop()) { + pos.x = LineStartPos(coords, textLine_[i].linePixelWidth); + LabelLineInfo labelLine{pos, offset, drawMask, lineHeight, textLine_[i].lineBytes, + 0, opa, style, &text_[lineBegin], textLine_[i].lineBytes, + lineBegin, fontId_, fontSize_, 0, static_cast(direct_), + nullptr, transMap_}; + // Use DrawTextOneLineWithShadow instead of DrawTextOneLine + DrawLabel::DrawTextOneLineWithShadow(gfxDstBuffer, labelLine, shadowOffsetX_, shadowOffsetY_); + if ((i == (lineCount - 1)) && (tailIndex != TEXT_ELLIPSIS_END_INV) && !isTruncateMode_) { + labelLine.offset.x = 0; + labelLine.text = TEXT_ELLIPSIS; + labelLine.lineLength = TEXT_ELLIPSIS_DOT_NUM; + labelLine.length = TEXT_ELLIPSIS_DOT_NUM; + DrawLabel::DrawTextOneLineWithShadow(gfxDstBuffer, labelLine, shadowOffsetX_, shadowOffsetY_); + } + } + lineBegin += textLine_[i].lineBytes; + pos.y = nextLine; + } +} +} // namespace OHOS + diff --git a/code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.cpp b/code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.cpp index 888f92f90..dd06942ba 100644 --- a/code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.cpp +++ b/code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.cpp @@ -59,6 +59,70 @@ void DrawLabel::DrawTextOneLine(BufferInfo& gfxDstBuffer, const LabelLineInfo& l } } } +// 雷鸟项目增加,阴影Lable子组件 +void DrawLabel::DrawTextOneLineWithShadow(BufferInfo& gfxDstBuffer, const LabelLineInfo& labelLine, int16_t shadowOffsetX, int16_t shadowOffsetY) +{ + UIFont* fontEngine = UIFont::GetInstance(); + Point textPos = labelLine.pos; + Point shadowPos = labelLine.pos; + + if (labelLine.direct == TEXT_DIRECT_RTL) { + textPos.x -= labelLine.offset.x; + shadowPos.x = textPos.x - shadowOffsetX; + } else { + textPos.x += labelLine.offset.x; + shadowPos.x = textPos.x + shadowOffsetX; + } + shadowPos.y = textPos.y + shadowOffsetY; // 向下偏移 + + uint32_t i = 0; + uint32_t letter; + uint16_t letterWidth; + ColorType shadowColor = Color::GetColorFromRGB(0x00, 0x00, 0x00); // 黑色阴影 + + while (i < labelLine.lineLength) { + letter = TypedText::GetUTF8Next(labelLine.text, i, i); + + // 先绘制阴影(向右偏移2像素,黑色) + LabelLetterInfo shadowLetterInfo{shadowPos, + labelLine.mask, + shadowColor, + labelLine.opaScale, + 0, + 0, + letter, + labelLine.direct, + labelLine.fontId, + 0, + labelLine.fontSize, + labelLine.transMap}; + DrawUtils::GetInstance()->DrawLetter(gfxDstBuffer, shadowLetterInfo); + + // 再绘制原始文字 + LabelLetterInfo letterInfo{textPos, + labelLine.mask, + labelLine.style.textColor_, + labelLine.opaScale, + 0, + 0, + letter, + labelLine.direct, + labelLine.fontId, + 0, + labelLine.fontSize, + labelLine.transMap}; + DrawUtils::GetInstance()->DrawLetter(gfxDstBuffer, letterInfo); + + letterWidth = fontEngine->GetWidth(letter, 0); + if (labelLine.direct == TEXT_DIRECT_RTL) { + textPos.x -= (letterWidth + labelLine.style.letterSpace_); + shadowPos.x -= (letterWidth + labelLine.style.letterSpace_); + } else { + textPos.x += (letterWidth + labelLine.style.letterSpace_); + shadowPos.x += (letterWidth + labelLine.style.letterSpace_); + } + } +} void DrawLabel::DrawArcText(BufferInfo& gfxDstBuffer, const Rect& mask, diff --git a/code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.h b/code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.h index f497feb55..3695fa56f 100644 --- a/code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.h +++ b/code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.h @@ -27,6 +27,8 @@ class DrawLabel : public HeapBase { public: static void DrawTextOneLine(BufferInfo& gfxDstBuffer, const LabelLineInfo& labelLine); + static void DrawTextOneLineWithShadow(BufferInfo& gfxDstBuffer, const LabelLineInfo& labelLine, int16_t shadowOffsetX = 2, int16_t shadowOffsetY = 2); + static void DrawArcText(BufferInfo& gfxDstBuffer, const Rect& mask, const char* text, const Point& arcCenter, uint8_t fontId, const UIArcLabel::ArcTextInfo arcTextInfo, UIArcLabel::TextOrientation orientation, const Style& style, uint8_t opaScale); diff --git a/code/sdk/middleware/services/gui/uikit/ui/interfaces/kits/common/text_with_shadow.h b/code/sdk/middleware/services/gui/uikit/ui/interfaces/kits/common/text_with_shadow.h new file mode 100644 index 000000000..6ad287b28 --- /dev/null +++ b/code/sdk/middleware/services/gui/uikit/ui/interfaces/kits/common/text_with_shadow.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GRAPHIC_LITE_TEXT_WITH_SHADOW_H +#define GRAPHIC_LITE_TEXT_WITH_SHADOW_H + +#include "common/text.h" +#include "draw/draw_label.h" + +namespace OHOS { +/** + * @brief Text class with shadow effect support. + * The shadow is drawn 2 pixels to the right and 2 pixels down in black color. + * The shadow does not affect the original font size. + */ +class TextWithShadow : public Text { +public: + /** + * @brief A constructor used to create a TextWithShadow instance. + */ + TextWithShadow() : Text(), shadowOffsetX_(2), shadowOffsetY_(2) {} + + /** + * @brief A destructor used to delete the TextWithShadow instance. + */ + virtual ~TextWithShadow() {} + + /** + * @brief Sets the shadow offset in X direction. + * @param offsetX The shadow offset in pixels (default: 2). + */ + void SetShadowOffsetX(int16_t offsetX) + { + shadowOffsetX_ = offsetX; + } + + /** + * @brief Gets the shadow offset in X direction. + * @return Returns the shadow offset in pixels. + */ + int16_t GetShadowOffsetX() const + { + return shadowOffsetX_; + } + + /** + * @brief Sets the shadow offset in Y direction. + * @param offsetY The shadow offset in pixels (default: 2). + */ + void SetShadowOffsetY(int16_t offsetY) + { + shadowOffsetY_ = offsetY; + } + + /** + * @brief Gets the shadow offset in Y direction. + * @return Returns the shadow offset in pixels. + */ + int16_t GetShadowOffsetY() const + { + return shadowOffsetY_; + } + +protected: + /** + * @brief Draws text with shadow effect. + * Overrides Text::Draw to use DrawTextOneLineWithShadow. + */ + void Draw(BufferInfo& gfxDstBuffer, + const Rect& mask, + const Rect& coords, + const Style& style, + int16_t offsetX, + uint16_t tailIndex, + OpacityType opaScale) override; + +private: + int16_t shadowOffsetX_; // Shadow offset in X direction (default: 2 pixels) + int16_t shadowOffsetY_; // Shadow offset in Y direction (default: 2 pixels) +}; +} // namespace OHOS +#endif // GRAPHIC_LITE_TEXT_WITH_SHADOW_H + -- 2.17.1