增加阴影Lable子组件
authorxue <2144439972@qq.com>
Fri, 7 Nov 2025 05:52:42 +0000 (13:52 +0800)
committerxue <2144439972@qq.com>
Fri, 7 Nov 2025 05:52:42 +0000 (13:52 +0800)
code/sdk/middleware/services/gui/uikit/proprietary/include/components/ui_label_ext_with_shadow.h [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/components/ui_label_ext_with_shadow.cpp [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/ui/frameworks/common/text_with_shadow.cpp [new file with mode: 0644]
code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.cpp
code/sdk/middleware/services/gui/uikit/ui/frameworks/draw/draw_label.h
code/sdk/middleware/services/gui/uikit/ui/interfaces/kits/common/text_with_shadow.h [new file with mode: 0644]

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 (file)
index 0000000..a760e61
--- /dev/null
@@ -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 <b>UILabelExtWithShadow</b> instance.
+     */
+    UILabelExtWithShadow();
+
+    /**
+     * @brief A destructor used to delete the <b>UILabelExtWithShadow</b> 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 (file)
index 0000000..0b53f54
--- /dev/null
@@ -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<TextWithShadow*>(labelText_);
+        if (textWithShadow != nullptr) {
+            textWithShadow->SetShadowOffsetX(offsetX);
+        }
+    }
+}
+
+int16_t UILabelExtWithShadow::GetShadowOffsetX() const
+{
+    if (labelText_ != nullptr) {
+        const TextWithShadow* textWithShadow = static_cast<const TextWithShadow*>(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<TextWithShadow*>(labelText_);
+        if (textWithShadow != nullptr) {
+            textWithShadow->SetShadowOffsetY(offsetY);
+        }
+    }
+}
+
+int16_t UILabelExtWithShadow::GetShadowOffsetY() const
+{
+    if (labelText_ != nullptr) {
+        const TextWithShadow* textWithShadow = static_cast<const TextWithShadow*>(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 (file)
index 0000000..cb55f1d
--- /dev/null
@@ -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 <cstring>
+
+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<UITextLanguageDirect>(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
+
index 888f92f..dd06942 100644 (file)
@@ -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,
index f497feb..3695fa5 100644 (file)
@@ -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 (file)
index 0000000..6ad287b
--- /dev/null
@@ -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 <b>TextWithShadow</b> instance.
+     */
+    TextWithShadow() : Text(), shadowOffsetX_(2), shadowOffsetY_(2) {}
+
+    /**
+     * @brief A destructor used to delete the <b>TextWithShadow</b> 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
+