diff --git a/frameworks/BUILD.gn b/frameworks/BUILD.gn index dceeb7e..2bc7370 100644 --- a/frameworks/BUILD.gn +++ b/frameworks/BUILD.gn @@ -15,6 +15,8 @@ import("//build/lite/config/component/lite_component.gni") import("//build/lite/config/subsystem/aafwk/config.gni") import("//foundation/ace/ace_engine_lite/ace_lite.gni") +defines = [] + declare_args() { LOSCFG_TEST_JS_BUILD = false } @@ -25,6 +27,7 @@ lite_component("jsfwk") { config("ace_lite_config") { include_dirs = ace_lite_include_dirs + defines += [ "FEATURE_COMPONENT_TEXT_SPANNABLE=1" ] cflags_cc = [ "-std=c++14" ] ldflags = [ "-lstdc++" ] diff --git a/frameworks/src/core/base/key_parser.cpp b/frameworks/src/core/base/key_parser.cpp index 68bcd6c..a4e21ef 100644 --- a/frameworks/src/core/base/key_parser.cpp +++ b/frameworks/src/core/base/key_parser.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright (c) 2020-2022 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 @@ -66,6 +66,17 @@ uint16_t KeyParser::ParseKeyId(const char *s, const size_t len) switch (*s++) { // clang-format off case 'a': +#if FEATURE_COMPONENT_TEXT_SPANNABLE + if (!strcmp(s, "bsolutesizespanstart")) { + return K_ABSOLUTESIZESPANSTART; + } + if (!strcmp(s, "bsolutesizespanend")) { + return K_ABSOLUTESIZESPANEND; + } + if (!strcmp(s, "bsolutesizespansize")) { + return K_ABSOLUTESIZESPANSIZE; + } +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE if (!strcmp(s, "lignItems")) { return K_ALIGN_ITEMS; } @@ -105,6 +116,17 @@ uint16_t KeyParser::ParseKeyId(const char *s, const size_t len) if (!strcmp(s, "ackgroundColor")) { return K_BACKGROUND_COLOR; } +#if FEATURE_COMPONENT_TEXT_SPANNABLE + if (!strcmp(s, "ackgroundcolorspancolor")) { + return K_BACKGROUNDCOLORSPANCOLOR; + } + if (!strcmp(s, "ackgroundcolorspanstart")) { + return K_BACKGROUNDCOLORSPANSTART; + } + if (!strcmp(s, "ackgroundcolorspanend")) { + return K_BACKGROUNDCOLORSPANEND; + } +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE if (!strcmp(s, "ackgroundImage")) { return K_BACKGROUND_IMAGE; } @@ -308,6 +330,17 @@ uint16_t KeyParser::ParseKeyId(const char *s, const size_t len) if (!strcmp(s, "ontFamily")) { return K_FONT_FAMILY; } +#if FEATURE_COMPONENT_TEXT_SPANNABLE + if (!strcmp(s, "oregroundcolorspancolor")) { + return K_FOREGROUNDCOLORSPANCOLOR; + } + if (!strcmp(s, "oregroundcolorspanstart")) { + return K_FOREGROUNDCOLORSPANSTART; + } + if (!strcmp(s, "oregroundcolorspanend")) { + return K_FOREGROUNDCOLORSPANEND; + } +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE if (!strcmp(s, "orwards")) { return K_FORWARDS; } @@ -378,6 +411,17 @@ uint16_t KeyParser::ParseKeyId(const char *s, const size_t len) if (!strcmp(s, "etterSpacing")) { return K_LETTER_SPACING; } +#if FEATURE_COMPONENT_TEXT_SPANNABLE + if (!strcmp(s, "inebackgroundcolorspancolor")) { + return K_LINEBACKGROUNDCOLORSPANCOLOR; + } + if (!strcmp(s, "inebackgroundcolorspanstart")) { + return K_LINEBACKGROUNDCOLORSPANSTART; + } + if (!strcmp(s, "inebackgroundcolorspanend")) { + return K_LINEBACKGROUNDCOLORSPANEND; + } +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE if (!strcmp(s, "ineHeight")) { return K_LINE_HEIGHT; } @@ -537,6 +581,17 @@ uint16_t KeyParser::ParseKeyId(const char *s, const size_t len) if (!strcmp(s, "ef")) { return K_REF; } +#if FEATURE_COMPONENT_TEXT_SPANNABLE + if (!strcmp(s, "elativesizespanstart")) { + return K_RELATIVESIZESPANSTART; + } + if (!strcmp(s, "elativesizespanend")) { + return K_RELATIVESIZESPANEND; + } + if (!strcmp(s, "elativesizespansize")) { + return K_RELATIVESIZESPANSIZE; + } +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE if (!strcmp(s, "everse")) { return K_REVERSE; } @@ -620,6 +675,17 @@ uint16_t KeyParser::ParseKeyId(const char *s, const size_t len) if (!strcmp(s, "pace-evenly")) { return K_SPACE_EVENLY; } +#if FEATURE_COMPONENT_TEXT_SPANNABLE + if (!strcmp(s, "pannablestyle")) { + return K_SPANNABLESTYLE; + } + if (!strcmp(s, "pannablestart")) { + return K_SPANNABLESTART; + } + if (!strcmp(s, "pannableend")) { + return K_SPANNABLEEND; + } +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE if (!strcmp(s, "rc")) { return K_SRC; } diff --git a/frameworks/src/core/base/keys.h b/frameworks/src/core/base/keys.h index eec5f01..1852ce4 100644 --- a/frameworks/src/core/base/keys.h +++ b/frameworks/src/core/base/keys.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright (c) 2020-2022 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 @@ -309,6 +309,26 @@ enum { KEYWORD(MINIMUMFRACTIONDIGITS, minimumFractionDigits) KEYWORD(MAXIMUMFRACTIONDIGITS, maximumFractionDigits) #endif +#if FEATURE_COMPONENT_TEXT_SPANNABLE + KEYWORD(BACKGROUNDCOLORSPANCOLOR, backgroundcolorspancolor) + KEYWORD(BACKGROUNDCOLORSPANSTART, backgroundcolorspanstart) + KEYWORD(BACKGROUNDCOLORSPANEND, backgroundcolorspanend) + KEYWORD(FOREGROUNDCOLORSPANCOLOR, foregroundcolorspancolor) + KEYWORD(FOREGROUNDCOLORSPANSTART, foregroundcolorspanstart) + KEYWORD(FOREGROUNDCOLORSPANEND, foregroundcolorspanend) + KEYWORD(LINEBACKGROUNDCOLORSPANCOLOR, linebackgroundcolorspancolor) + KEYWORD(LINEBACKGROUNDCOLORSPANSTART, linebackgroundcolorspanstart) + KEYWORD(LINEBACKGROUNDCOLORSPANEND, linebackgroundcolorspanend) + KEYWORD(ABSOLUTESIZESPANSTART, absolutesizespanstart) + KEYWORD(ABSOLUTESIZESPANEND, absolutesizespanend) + KEYWORD(ABSOLUTESIZESPANSIZE, absolutesizespansize) + KEYWORD(RELATIVESIZESPANSTART, relativesizespanstart) + KEYWORD(RELATIVESIZESPANEND, relativesizespanend) + KEYWORD(RELATIVESIZESPANSIZE, relativesizespansize) + KEYWORD(SPANNABLESTYLE, spannablestyle) + KEYWORD(SPANNABLESTART, spannablestart) + KEYWORD(SPANNABLEEND, spannableend) +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE // Reused by the struct end // clang-format on #ifdef KEYWORDS_ENUM_DEFINE diff --git a/frameworks/src/core/components/text_component.cpp b/frameworks/src/core/components/text_component.cpp index 59b1bdb..59d0627 100644 --- a/frameworks/src/core/components/text_component.cpp +++ b/frameworks/src/core/components/text_component.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright (c) 2020-2022 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 @@ -37,6 +37,14 @@ TextComponent::TextComponent(jerry_value_t options, jerry_value_t children, AppS { SetComponentName(K_TEXT); fontSize_ = ProductAdapter::GetDefaultFontSize(); +#if FEATURE_COMPONENT_TEXT_SPANNABLE + backgroundColorSpan_.start = -1; + backgroundColorSpan_.end = -1; + foregroundColorSpan_.start = -1; + foregroundColorSpan_.end = -1; + lineBackgroundColorSpan_.start = -1; + lineBackgroundColorSpan_.end = -1; +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE } bool TextComponent::CreateNativeViews() @@ -114,6 +122,101 @@ bool TextComponent::ApplyPrivateStyle(const AppStyleItem *styleItem) case K_LINE_HEIGHT: SetTextLineHeight(uiLabel_, styleItem); break; +#if FEATURE_COMPONENT_TEXT_SPANNABLE + case K_BACKGROUNDCOLORSPANCOLOR: { + uint32_t color = 0; + uint8_t alpha = OPA_OPAQUE; + if (GetStyleColorValue(styleItem, color, alpha)) { + backgroundColorSpan_.backgroundColor = GetRGBColor(color); + } + break; + } + case K_BACKGROUNDCOLORSPANSTART: { + backgroundColorSpan_.start = styleItem->GetNumValue(); + break; + } + case K_BACKGROUNDCOLORSPANEND: { + backgroundColorSpan_.end = styleItem->GetNumValue(); + break; + } + case K_FOREGROUNDCOLORSPANCOLOR: { + uint32_t color = 0; + uint8_t alpha = OPA_OPAQUE; + if (GetStyleColorValue(styleItem, color, alpha)) { + foregroundColorSpan_.fontColor = GetRGBColor(color); + } + break; + } + case K_FOREGROUNDCOLORSPANSTART: { + foregroundColorSpan_.start = styleItem->GetNumValue(); + break; + } + case K_FOREGROUNDCOLORSPANEND: { + foregroundColorSpan_.end = styleItem->GetNumValue(); + break; + } + case K_LINEBACKGROUNDCOLORSPANCOLOR: { + uint32_t color = 0; + uint8_t alpha = OPA_OPAQUE; + if (GetStyleColorValue(styleItem, color, alpha)) { + lineBackgroundColorSpan_.linebackgroundColor = GetRGBColor(color); + } + break; + } + case K_LINEBACKGROUNDCOLORSPANSTART: { + lineBackgroundColorSpan_.start = styleItem->GetNumValue(); + break; + } + case K_LINEBACKGROUNDCOLORSPANEND: { + lineBackgroundColorSpan_.end = styleItem->GetNumValue(); + break; + } + case K_ABSOLUTESIZESPANSTART: { + absoluteSizeSpan_.start = styleItem->GetNumValue(); + break; + } + case K_ABSOLUTESIZESPANEND: { + absoluteSizeSpan_.end = styleItem->GetNumValue(); + break; + } + case K_ABSOLUTESIZESPANSIZE: { + absoluteSizeSpan_.size = GetStylePixelValue(styleItem); + break; + } + case K_RELATIVESIZESPANSTART: { + relativeSizeSpan_.start = styleItem->GetNumValue(); + break; + } + case K_RELATIVESIZESPANEND: { + relativeSizeSpan_.end = styleItem->GetNumValue(); + break; + } + case K_RELATIVESIZESPANSIZE: { + relativeSizeSpan_.size = styleItem->GetFloatingValue(); + break; + } + case K_SPANNABLESTYLE: { + TextStyle style = TextStyle::TEXT_STYLE_NORMAL; + const char* styleStr = styleItem->GetStrValue(); + if (!strcmp(styleStr, "bold")) { + style = TextStyle::TEXT_STYLE_BOLD; + } else if (!strcmp(styleStr, "bold-italic")) { + style = TextStyle::TEXT_STYLE_BOLD_ITALIC; + } else if (!strcmp(styleStr, "italic")) { + style = TextStyle::TEXT_STYLE_ITALIC; + } + stringStyleSpan_.style = style; + break; + } + case K_SPANNABLESTART: { + stringStyleSpan_.start = styleItem->GetNumValue(); + break; + } + case K_SPANNABLEEND: { + stringStyleSpan_.end = styleItem->GetNumValue(); + break; + } +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE default: return false; } @@ -191,6 +294,9 @@ void TextComponent::OnViewAttached() uiLabel_.SetFont(fontFamily_, fontSize_); uiLabel_.SetText(textValue_); UpdateTextAlignToLabel(uiLabel_); +#if FEATURE_COMPONENT_TEXT_SPANNABLE + SetRichTextSpan(); +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE } } @@ -206,6 +312,9 @@ void TextComponent::PostUpdate(uint16_t attrKeyId) if (textValue_ != nullptr) { uiLabel_.SetText(textValue_); UpdateTextAlignToLabel(uiLabel_); +#if FEATURE_COMPONENT_TEXT_SPANNABLE + SetRichTextSpan(); +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE } break; case K_FONT_SIZE: @@ -259,5 +368,43 @@ void TextComponent::UpdateTextAlignToLabel(UILabelTypeWrapper& label) label.SetAlign(horizontalAlign_, UITextLanguageAlignment::TEXT_ALIGNMENT_CENTER); } } + +#if FEATURE_COMPONENT_TEXT_SPANNABLE +void TextComponent::SetRichTextSpan() +{ + if (backgroundColorSpan_.start != -1 && backgroundColorSpan_.end != -1) { + uiLabel_.SetBackgroundColorSpan(backgroundColorSpan_.backgroundColor, + backgroundColorSpan_.start, + backgroundColorSpan_.end); + } + if (foregroundColorSpan_.start != -1 && foregroundColorSpan_.end != -1) { + uiLabel_.SetForegroundColorSpan(foregroundColorSpan_.fontColor, + foregroundColorSpan_.start, + foregroundColorSpan_.end); + } + if (lineBackgroundColorSpan_.start != -1 && lineBackgroundColorSpan_.end != -1) { + uiLabel_.SetLineBackgroundSpan(lineBackgroundColorSpan_.linebackgroundColor, + lineBackgroundColorSpan_.start, + lineBackgroundColorSpan_.end); + } + if (absoluteSizeSpan_.start != -1 && absoluteSizeSpan_.end != -1) { + uiLabel_.SetAbsoluteSizeSpan(absoluteSizeSpan_.start, + absoluteSizeSpan_.end, + absoluteSizeSpan_.size); + } + if (relativeSizeSpan_.start != -1 && relativeSizeSpan_.end != -1) { + uiLabel_.SetRelativeSizeSpan(relativeSizeSpan_.start, + relativeSizeSpan_.end, + relativeSizeSpan_.size); + } + if (stringStyleSpan_.start != -1 && stringStyleSpan_.end != -1) { + SpannableString spanString(textValue_); + spanString.SetTextStyle(stringStyleSpan_.style, + stringStyleSpan_.start, + stringStyleSpan_.end); + uiLabel_.SetText(&spanString); + } +} +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/components/text_component.h b/frameworks/src/core/components/text_component.h index 4d1789d..185dee0 100644 --- a/frameworks/src/core/components/text_component.h +++ b/frameworks/src/core/components/text_component.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright (c) 2020-2022 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 @@ -30,6 +30,29 @@ namespace OHOS { namespace ACELite { +#if FEATURE_COMPONENT_TEXT_SPANNABLE +struct AbsoluteSizeSpan { + int16_t start; + int16_t end; + uint8_t size; + AbsoluteSizeSpan() : start(-1), end(-1), size(0) {} +}; + +struct RelativeSizeSpan { + int16_t start; + int16_t end; + float size; + RelativeSizeSpan() : start(-1), end(-1), size(0) {} +}; + +struct StringStyleSpan { + TextStyle style; + int16_t start; + int16_t end; + StringStyleSpan() : start(-1), end(-1), style(TextStyle::TEXT_STYLE_NORMAL) {} +}; +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE + class TextComponent : public Component { public: ACE_DISALLOW_COPY_AND_MOVE(TextComponent); @@ -61,12 +84,23 @@ private: void SetTextLetterSpace(UILabelTypeWrapper& label, const AppStyleItem* styleItem) const; // parse js text line height style to ui_label void SetTextLineHeight(UILabelTypeWrapper& label, const AppStyleItem* styleItem) const; +#if FEATURE_COMPONENT_TEXT_SPANNABLE + void SetRichTextSpan(); +#endif UILabelTypeWrapper uiLabel_; uint8_t fontSize_; char* fontFamily_; char* textValue_; uint8_t overflowMode_; UITextLanguageAlignment horizontalAlign_; +#if FEATURE_COMPONENT_TEXT_SPANNABLE + BackgroundColor backgroundColorSpan_; + ForegroundColor foregroundColorSpan_; + LineBackgroundColor lineBackgroundColorSpan_; + AbsoluteSizeSpan absoluteSizeSpan_; + RelativeSizeSpan relativeSizeSpan_; + StringStyleSpan stringStyleSpan_; +#endif // FEATURE_COMPONENT_TEXT_SPANNABLE }; } // namespace ACELite } // namespace OHOS diff --git a/frameworks/src/core/stylemgr/app_style_item.cpp b/frameworks/src/core/stylemgr/app_style_item.cpp index 814af0c..3fd9bc2 100644 --- a/frameworks/src/core/stylemgr/app_style_item.cpp +++ b/frameworks/src/core/stylemgr/app_style_item.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * Copyright (c) 2020-2022 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 @@ -120,7 +120,11 @@ AppStyleItem *AppStyleItem::CreateStyleItem(uint16_t keyId, const jerry_value_t newStyleItem->pseudoClassType_ = pseudoClassType; if (jerry_value_is_number(stylePropValue)) { +#if FEATURE_COMPONENT_TEXT_SPANNABLE + if (keyId == K_OPACITY || keyId == K_RELATIVESIZESPANSIZE) { +#else if (keyId == K_OPACITY) { +#endif newStyleItem->SetFloatingValue(jerry_get_number_value(stylePropValue)); } else { newStyleItem->SetNumValue((int32_t)(jerry_get_number_value(stylePropValue))); diff --git a/frameworks/tools/qt/simulator/jsfwk/jsfwk.pro b/frameworks/tools/qt/simulator/jsfwk/jsfwk.pro index 31b946f..c21eb61 100644 --- a/frameworks/tools/qt/simulator/jsfwk/jsfwk.pro +++ b/frameworks/tools/qt/simulator/jsfwk/jsfwk.pro @@ -24,6 +24,7 @@ DEFINES += "ENABLE_SHAPING=0" \ "ENABLE_BITMAP_FONT=0" \ "ENABLE_MULTI_FONT=0" \ "ENABLE_STATIC_FONT=0" \ + "FEATURE_COMPONENT_TEXT_SPANNABLE=1" \ "GRAPHIC_ENABLE_LINECAP_FLAG=1" \ "GRAPHIC_ENABLE_LINEJOIN_FLAG=1" \ "GRAPHIC_ENABLE_ELLIPSE_FLAG=1" \ diff --git a/frameworks/tools/qt/simulator/simulator.pro b/frameworks/tools/qt/simulator/simulator.pro index 6f213b8..922b664 100644 --- a/frameworks/tools/qt/simulator/simulator.pro +++ b/frameworks/tools/qt/simulator/simulator.pro @@ -8,12 +8,12 @@ system("copy ..\\..\\..\\..\\..\\..\\graphic\\ui\\tools\\qt\\simulator\\font\\So SUBDIRS += \ - $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/freetype \ $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/harfbuzz \ $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/icu \ $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/libjpeg \ $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/zlib \ $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/libpng \ + $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/freetype \ $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/giflib \ $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/third_party/qrcodegen \ $${FOUNDATION_PATH}/graphic/ui/tools/qt/simulator/libui \