mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-24 07:31:57 +00:00
支持轻量图文混排
Signed-off-by: limeng <limeng208@huawei.com>
This commit is contained in:
parent
3a9b2c4237
commit
4e2c172686
@ -183,6 +183,7 @@ template("declarative_js_engine") {
|
||||
"jsview/js_if_else.cpp",
|
||||
"jsview/js_image.cpp",
|
||||
"jsview/js_image_animator.cpp",
|
||||
"jsview/js_image_span.cpp",
|
||||
"jsview/js_indexer.cpp",
|
||||
"jsview/js_interactable_view.cpp",
|
||||
"jsview/js_lazy_foreach.cpp",
|
||||
|
@ -1329,3 +1329,12 @@ var ContentTextStyle;
|
||||
ContentTextStyle[ContentTextStyle["DoubleLine"] = 1] = "DoubleLine";
|
||||
ContentTextStyle[ContentTextStyle["ThreeLines"] = 2] = "ThreeLines";
|
||||
})(ContentTextStyle || (ContentTextStyle = {}));
|
||||
|
||||
var ImageSpanAlignment;
|
||||
(function (ImageSpanAlignment) {
|
||||
ImageSpanAlignment[ImageSpanAlignment["NONE"] = 0] = "NONE";
|
||||
ImageSpanAlignment[ImageSpanAlignment["TOP"] = 1] = "TOP";
|
||||
ImageSpanAlignment[ImageSpanAlignment["CENTER"] = 2] = "CENTER";
|
||||
ImageSpanAlignment[ImageSpanAlignment["BOTTOM"] = 3] = "BOTTOM";
|
||||
ImageSpanAlignment[ImageSpanAlignment["BASELINE"] = 4] = "BASELINE";
|
||||
})(ImageSpanAlignment || (ImageSpanAlignment = {}));
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "bridge/declarative_frontend/jsview/js_if_else.h"
|
||||
#include "bridge/declarative_frontend/jsview/js_image.h"
|
||||
#include "bridge/declarative_frontend/jsview/js_image_animator.h"
|
||||
#include "bridge/declarative_frontend/jsview/js_image_span.h"
|
||||
#include "bridge/declarative_frontend/jsview/js_indexer.h"
|
||||
#include "bridge/declarative_frontend/jsview/js_lazy_foreach.h"
|
||||
#include "bridge/declarative_frontend/jsview/js_line.h"
|
||||
@ -593,6 +594,7 @@ static const std::unordered_map<std::string, std::function<void(BindingTarget)>>
|
||||
{ "RelativeContainer", JSRelativeContainer::JSBind },
|
||||
{ "__Common__", JSCommonView::JSBind },
|
||||
{ "LinearGradient", JSLinearGradient::JSBind },
|
||||
{ "ImageSpan", JSImageSpan::JSBind },
|
||||
#ifdef PREVIEW
|
||||
{ "FormComponent", JSForm::JSBind },
|
||||
{ "XComponent", JSXComponent::JSBind },
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -40,6 +40,7 @@
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_grid_item.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_if_else.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_image.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_image_span.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_lazy_foreach.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_list.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_list_item.h"
|
||||
@ -182,6 +183,7 @@ void JsBindViews(BindingTarget globalObj)
|
||||
JSGrid::JSBind(globalObj);
|
||||
JSGridItem::JSBind(globalObj);
|
||||
JSSwiper::JSBind(globalObj);
|
||||
JSImageSpan::JSBind(globalObj);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::Framework
|
||||
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 "frameworks/bridge/declarative_frontend/jsview/js_image_span.h"
|
||||
|
||||
#if !defined(PREVIEW)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "base/image/pixel_map.h"
|
||||
#include "base/log/ace_scoring_log.h"
|
||||
#include "base/log/ace_trace.h"
|
||||
#include "bridge/declarative_frontend/engine/js_ref_ptr.h"
|
||||
#include "core/components/common/layout/constants.h"
|
||||
#include "core/components_ng/pattern/image/image_model.h"
|
||||
#include "core/components_ng/pattern/text/image_span_view.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_image.h"
|
||||
|
||||
namespace OHOS::Ace::Framework {
|
||||
void JSImageSpan::Create(const JSCallbackInfo& info)
|
||||
{
|
||||
if (!Container::IsCurrentUseNewPipeline()) {
|
||||
return;
|
||||
}
|
||||
if (info.Length() != 1) {
|
||||
LOGE("The arg is wrong, it is supposed to have 1 argument");
|
||||
return;
|
||||
}
|
||||
std::string bundleName;
|
||||
std::string moduleName;
|
||||
std::string src;
|
||||
auto noPixmap = ParseJsMedia(info[0], src);
|
||||
JSImage::GetJsMediaBundleInfo(info[0], bundleName, moduleName);
|
||||
LOGI("JSImageSpan::Create src = %{public}s bundleName = %{public}s moduleName = %{public}s noPixmap = "
|
||||
"%{public}d",
|
||||
src.c_str(), bundleName.c_str(), moduleName.c_str(), noPixmap);
|
||||
RefPtr<PixelMap> pixmap = nullptr;
|
||||
#if defined(PIXEL_MAP_SUPPORTED)
|
||||
if (!noPixmap) {
|
||||
pixmap = CreatePixelMapFromNapiValue(info[0]);
|
||||
}
|
||||
#endif
|
||||
ImageModel::GetInstance()->Create(src, noPixmap, pixmap, bundleName, moduleName);
|
||||
}
|
||||
|
||||
void JSImageSpan::SetObjectFit(int32_t value)
|
||||
{
|
||||
auto fit = static_cast<ImageFit>(value);
|
||||
if (fit < ImageFit::FILL || fit > ImageFit::SCALE_DOWN) {
|
||||
LOGW("The value of objectFit is out of range %{public}d", value);
|
||||
fit = ImageFit::COVER;
|
||||
}
|
||||
ImageModel::GetInstance()->SetImageFit(fit);
|
||||
}
|
||||
|
||||
void JSImageSpan::SetVerticalAlign(int32_t verticalAlign)
|
||||
{
|
||||
auto align = static_cast<VerticalAlign>(verticalAlign);
|
||||
if (align < VerticalAlign::TOP || align > VerticalAlign::NONE) {
|
||||
LOGW("The value of verticalAlign is out of range %{public}d", verticalAlign);
|
||||
align = VerticalAlign::BOTTOM;
|
||||
}
|
||||
NG::ImageSpanView::SetVerticalAlign(align);
|
||||
}
|
||||
|
||||
void JSImageSpan::JSBind(BindingTarget globalObj)
|
||||
{
|
||||
JSClass<JSImageSpan>::Declare("ImageSpan");
|
||||
MethodOptions opt = MethodOptions::NONE;
|
||||
JSClass<JSImageSpan>::StaticMethod("create", &JSImageSpan::Create, opt);
|
||||
JSClass<JSImageSpan>::StaticMethod("objectFit", &JSImageSpan::SetObjectFit, opt);
|
||||
JSClass<JSImageSpan>::StaticMethod("verticalAlign", &JSImageSpan::SetVerticalAlign);
|
||||
JSClass<JSImageSpan>::Inherit<JSViewAbstract>();
|
||||
JSClass<JSImageSpan>::Bind<>(globalObj);
|
||||
}
|
||||
} // namespace OHOS::Ace::Framework
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_IMAGE_SPAN_H
|
||||
#define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_IMAGE_SPAN_H
|
||||
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_utils.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
|
||||
|
||||
namespace OHOS::Ace::Framework {
|
||||
class JSImageSpan : public JSViewAbstract {
|
||||
public:
|
||||
static void Create(const JSCallbackInfo& info);
|
||||
static void SetObjectFit(int32_t value);
|
||||
static void SetVerticalAlign(int32_t verticalAlign);
|
||||
static void GetJsMediaBundleInfo(const JSRef<JSVal>& jsValue, std::string& bundleName, std::string& moduleName);
|
||||
static void JSBind(BindingTarget globalObj);
|
||||
};
|
||||
} // namespace OHOS::Ace::Framework
|
||||
#endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_IMAGE_SPAN_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2023 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
|
||||
@ -206,6 +206,19 @@ void JSText::SetMaxLines(const JSCallbackInfo& info)
|
||||
TextModel::GetInstance()->SetMaxLines(value);
|
||||
}
|
||||
|
||||
void JSText::SetTextIndent(const JSCallbackInfo& info)
|
||||
{
|
||||
if (info.Length() < 1) {
|
||||
LOGE("The argv is wrong, it is supposed to have at least 1 argument");
|
||||
return;
|
||||
}
|
||||
Dimension value;
|
||||
if (!ParseJsDimensionFp(info[0], value)) {
|
||||
return;
|
||||
}
|
||||
TextModel::GetInstance()->SetTextIndent(value);
|
||||
}
|
||||
|
||||
void JSText::SetFontStyle(int32_t value)
|
||||
{
|
||||
if (value < 0 || value >= static_cast<int32_t>(FONT_STYLES.size())) {
|
||||
@ -551,6 +564,7 @@ void JSText::JSBind(BindingTarget globalObj)
|
||||
JSClass<JSText>::StaticMethod("fontSize", &JSText::SetFontSize, opt);
|
||||
JSClass<JSText>::StaticMethod("fontWeight", &JSText::SetFontWeight, opt);
|
||||
JSClass<JSText>::StaticMethod("maxLines", &JSText::SetMaxLines, opt);
|
||||
JSClass<JSText>::StaticMethod("textIndent", &JSText::SetTextIndent);
|
||||
JSClass<JSText>::StaticMethod("textOverflow", &JSText::SetTextOverflow, opt);
|
||||
JSClass<JSText>::StaticMethod("fontStyle", &JSText::SetFontStyle, opt);
|
||||
JSClass<JSText>::StaticMethod("align", &JSText::SetAlign, opt);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2023 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,7 @@ public:
|
||||
static void SetTextShadow(const JSCallbackInfo& info);
|
||||
static void SetTextOverflow(const JSCallbackInfo& info);
|
||||
static void SetMaxLines(const JSCallbackInfo& info);
|
||||
static void SetTextIndent(const JSCallbackInfo& info);
|
||||
static void SetFontStyle(int32_t value);
|
||||
static void SetAlign(const JSCallbackInfo& info);
|
||||
static void SetTextAlign(int32_t value);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -127,6 +127,16 @@ void TextModelImpl::SetMaxLines(uint32_t value)
|
||||
component->SetTextStyle(textStyle);
|
||||
}
|
||||
|
||||
void TextModelImpl::SetTextIndent(const Dimension& value)
|
||||
{
|
||||
auto component = GetComponent();
|
||||
CHECK_NULL_VOID(component);
|
||||
|
||||
auto textStyle = component->GetTextStyle();
|
||||
textStyle.SetTextIndent(value);
|
||||
component->SetTextStyle(textStyle);
|
||||
}
|
||||
|
||||
void TextModelImpl::SetLineHeight(const Dimension& value)
|
||||
{
|
||||
auto component = GetComponent();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -35,6 +35,7 @@ public:
|
||||
void SetTextAlign(TextAlign value) override;
|
||||
void SetTextOverflow(TextOverflow value) override;
|
||||
void SetMaxLines(uint32_t value) override;
|
||||
void SetTextIndent(const Dimension& value) override;
|
||||
void SetLineHeight(const Dimension& value) override;
|
||||
void SetTextDecoration(TextDecoration value) override;
|
||||
void SetTextDecorationColor(const Color& value) override;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2023 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
|
||||
@ -71,12 +71,59 @@ enum class TextCase {
|
||||
|
||||
enum class WordBreak { NORMAL = 0, BREAK_ALL, BREAK_WORD };
|
||||
|
||||
/// Where to vertically align the placeholder relative to the surrounding text.
|
||||
enum class PlaceholderAlignment {
|
||||
/// Match the baseline of the placeholder with the baseline.
|
||||
BASELINE,
|
||||
|
||||
/// Align the bottom edge of the placeholder with the baseline such that the
|
||||
/// placeholder sits on top of the baseline.
|
||||
ABOVEBASELINE,
|
||||
|
||||
/// Align the top edge of the placeholder with the baseline specified in
|
||||
/// such that the placeholder hangs below the baseline.
|
||||
BELOWBASELINE,
|
||||
|
||||
/// Align the top edge of the placeholder with the top edge of the font.
|
||||
/// When the placeholder is very tall, the extra space will hang from
|
||||
/// the top and extend through the bottom of the line.
|
||||
TOP,
|
||||
|
||||
/// Align the bottom edge of the placeholder with the top edge of the font.
|
||||
/// When the placeholder is very tall, the extra space will rise from
|
||||
/// the bottom and extend through the top of the line.
|
||||
BOTTOM,
|
||||
|
||||
/// Align the middle of the placeholder with the middle of the text. When the
|
||||
/// placeholder is very tall, the extra space will grow equally from
|
||||
/// the top and bottom of the line.
|
||||
MIDDLE,
|
||||
};
|
||||
|
||||
struct TextSizeGroup {
|
||||
Dimension fontSize = 14.0_px;
|
||||
uint32_t maxLines = INT32_MAX;
|
||||
TextOverflow textOverflow = TextOverflow::CLIP;
|
||||
};
|
||||
|
||||
/// Placeholder properties
|
||||
struct PlaceholderRun {
|
||||
/// Placeholder's width
|
||||
float width = 0.0f;
|
||||
|
||||
/// Placeholder's height
|
||||
float height = 0.0f;
|
||||
|
||||
/// Vertically alignment the placeholder relative to the surrounding text.
|
||||
PlaceholderAlignment alignment = PlaceholderAlignment::BOTTOM;
|
||||
|
||||
/// The placeholder with the baseline styles
|
||||
TextBaseline baseline = TextBaseline::ALPHABETIC;
|
||||
|
||||
/// The baseline offset
|
||||
float baseline_offset = 0.0f;
|
||||
};
|
||||
|
||||
class ACE_EXPORT TextStyle final {
|
||||
public:
|
||||
TextStyle() = default;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2023 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
|
||||
@ -275,4 +275,42 @@ Rect ConvertSkRect(SkRect skRect)
|
||||
return result;
|
||||
}
|
||||
|
||||
txt::PlaceholderAlignment ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration)
|
||||
{
|
||||
txt::PlaceholderAlignment convertValue = txt::PlaceholderAlignment::kBaseline;
|
||||
switch (textDecoration) {
|
||||
case PlaceholderAlignment::BASELINE:
|
||||
convertValue = txt::PlaceholderAlignment::kBaseline;
|
||||
break;
|
||||
case PlaceholderAlignment::ABOVEBASELINE:
|
||||
convertValue = txt::PlaceholderAlignment::kAboveBaseline;
|
||||
break;
|
||||
case PlaceholderAlignment::BELOWBASELINE:
|
||||
convertValue = txt::PlaceholderAlignment::kBelowBaseline;
|
||||
break;
|
||||
case PlaceholderAlignment::TOP:
|
||||
convertValue = txt::PlaceholderAlignment::kTop;
|
||||
break;
|
||||
case PlaceholderAlignment::BOTTOM:
|
||||
convertValue = txt::PlaceholderAlignment::kBottom;
|
||||
break;
|
||||
case PlaceholderAlignment::MIDDLE:
|
||||
convertValue = txt::PlaceholderAlignment::kMiddle;
|
||||
break;
|
||||
default:
|
||||
LOGW("PlaceholderAlignment setting error! Now using default PlaceholderAlignment");
|
||||
break;
|
||||
}
|
||||
return convertValue;
|
||||
}
|
||||
|
||||
void ConvertPlaceholderRun(const PlaceholderRun& span, txt::PlaceholderRun& txtSpan)
|
||||
{
|
||||
txtSpan.width = span.width;
|
||||
txtSpan.height = span.height;
|
||||
txtSpan.alignment = ConvertPlaceholderAlignment(span.alignment);
|
||||
txtSpan.baseline = ConvertTxtTextBaseline(span.baseline);
|
||||
txtSpan.baseline_offset = span.baseline_offset;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::Constants
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2021-2023 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
|
||||
@ -16,6 +16,7 @@
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_FONT_CONSTANTS_CONVERTER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_FONT_CONSTANTS_CONVERTER_H
|
||||
|
||||
#include "flutter/third_party/txt/src/txt/placeholder_run.h"
|
||||
#include "flutter/third_party/txt/src/txt/text_baseline.h"
|
||||
#include "flutter/third_party/txt/src/txt/text_decoration.h"
|
||||
#include "flutter/third_party/txt/src/txt/text_style.h"
|
||||
@ -62,6 +63,10 @@ void ConvertTxtStyle(const TextStyle& textStyle, const WeakPtr<PipelineBase>& co
|
||||
|
||||
Rect ConvertSkRect(SkRect skRect);
|
||||
|
||||
txt::PlaceholderAlignment ConvertPlaceholderAlignment(PlaceholderAlignment textDecoration);
|
||||
|
||||
void ConvertPlaceholderRun(const PlaceholderRun& span, txt::PlaceholderRun& txtSpan);
|
||||
|
||||
} // namespace Constants
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -352,6 +352,7 @@ build_component_ng("pattern_ng") {
|
||||
"tabs/tabs_model_ng.cpp",
|
||||
"tabs/tabs_node.cpp",
|
||||
"tabs/tabs_pattern.cpp",
|
||||
"text/image_span_view.cpp",
|
||||
"text/span_model_ng.cpp",
|
||||
"text/span_node.cpp",
|
||||
"text/text_accessibility_property.cpp",
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
value->propSyncMode_ = CloneSyncMode();
|
||||
value->propCopyOptions_ = CloneCopyOptions();
|
||||
value->propImageSizeStyle_ = CloneImageSizeStyle();
|
||||
value->propVerticalAlign_ = CloneVerticalAlign();
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -64,6 +65,7 @@ public:
|
||||
ResetSyncMode();
|
||||
ResetCopyOptions();
|
||||
ResetImageSizeStyle();
|
||||
ResetVerticalAlign();
|
||||
}
|
||||
|
||||
void ToJsonValue(std::unique_ptr<JsonValue>& json) const override
|
||||
@ -73,10 +75,14 @@ public:
|
||||
"ImageFit.Auto", "ImageFit.FitHeight", "ImageFit.None", "ImageFit.ScaleDown" };
|
||||
static const char* COPYOPTIONSVALUE[] = { "CopyOptions.None", "CopyOptions.InApp", "CopyOptions.Local",
|
||||
"CopyOptions.Distributed" };
|
||||
static const char* VERTICALALIGNVALUE[] = { "VerticalAlign.NONE", "VerticalAlign.TOP", "VerticalAlign.CENTER",
|
||||
"VerticalAlign.BOTTOM", "CopyOptions.BASELINE", "VerticalAlign.NONE" };
|
||||
json->Put("alt", propAlt_.value_or(ImageSourceInfo("")).GetSrc().c_str());
|
||||
json->Put("objectFit", OBJECTFITVALUE[static_cast<int32_t>(propImageFit_.value_or(ImageFit::COVER))]);
|
||||
json->Put("syncLoad", propSyncMode_.value_or(false) ? "true" : "false");
|
||||
json->Put("copyOption", COPYOPTIONSVALUE[static_cast<int32_t>(propCopyOptions_.value_or(CopyOptions::None))]);
|
||||
json->Put("verticalAlign",
|
||||
VERTICALALIGNVALUE[static_cast<int32_t>(propVerticalAlign_.value_or(VerticalAlign::BOTTOM))]);
|
||||
std::string src;
|
||||
if (propImageSourceInfo_.has_value()) {
|
||||
src = propImageSourceInfo_->GetSrc();
|
||||
@ -101,6 +107,7 @@ public:
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ImageSizeStyle, AutoResize, bool, PROPERTY_UPDATE_LAYOUT);
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ImageSizeStyle, SourceSize, SizeF, PROPERTY_UPDATE_LAYOUT);
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ImageSizeStyle, FitOriginalSize, bool, PROPERTY_UPDATE_LAYOUT);
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(VerticalAlign, VerticalAlign, PROPERTY_UPDATE_MEASURE);
|
||||
|
||||
private:
|
||||
ACE_DISALLOW_COPY_AND_MOVE(ImageLayoutProperty);
|
||||
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 "core/components_ng/pattern/text/image_span_view.h"
|
||||
|
||||
#include "base/memory/referenced.h"
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/components/common/layout/constants.h"
|
||||
#include "core/components_ng/base/view_stack_processor.h"
|
||||
#include "core/components_ng/pattern/image/image_pattern.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
void ImageSpanView::SetObjectFit(ImageFit value)
|
||||
{
|
||||
ACE_UPDATE_LAYOUT_PROPERTY(ImageLayoutProperty, ImageFit, value);
|
||||
}
|
||||
|
||||
void ImageSpanView::SetVerticalAlign(VerticalAlign verticalAlign)
|
||||
{
|
||||
ACE_UPDATE_LAYOUT_PROPERTY(ImageLayoutProperty, VerticalAlign, verticalAlign);
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
31
frameworks/core/components_ng/pattern/text/image_span_view.h
Normal file
31
frameworks/core/components_ng/pattern/text/image_span_view.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_IMAGE_SPAN_VIEW_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_IMAGE_SPAN_VIEW_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/image/pixel_map.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "core/components/common/layout/constants.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
class ACE_EXPORT ImageSpanView {
|
||||
public:
|
||||
static void SetObjectFit(ImageFit value);
|
||||
static void SetVerticalAlign(VerticalAlign verticalAlign);
|
||||
};
|
||||
} // namespace OHOS::Ace::NG
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_IMAGE_SPAN_VIEW_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -121,12 +121,13 @@ void SpanNode::RequestTextFlushDirty()
|
||||
LOGE("fail to find Text or Parent Span");
|
||||
}
|
||||
|
||||
void SpanItem::UpdateParagraph(const RefPtr<Paragraph>& builder)
|
||||
int32_t SpanItem::UpdateParagraph(
|
||||
const RefPtr<Paragraph>& builder, double /* width */, double /* height */, VerticalAlign /* verticalAlign */)
|
||||
{
|
||||
CHECK_NULL_VOID(builder);
|
||||
CHECK_NULL_RETURN(builder, -1);
|
||||
if (fontStyle) {
|
||||
auto pipelineContext = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(pipelineContext);
|
||||
CHECK_NULL_RETURN(pipelineContext, -1);
|
||||
TextStyle textStyle = CreateTextStyleUsingTheme(fontStyle, nullptr, pipelineContext->GetTheme<TextTheme>());
|
||||
builder->PushStyle(textStyle);
|
||||
}
|
||||
@ -142,5 +143,36 @@ void SpanItem::UpdateParagraph(const RefPtr<Paragraph>& builder)
|
||||
if (fontStyle) {
|
||||
builder->PopStyle();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t ImageSpanItem::UpdateParagraph(
|
||||
const RefPtr<Paragraph>& builder, double width, double height, VerticalAlign verticalAlign)
|
||||
{
|
||||
LOGI("ImageSpanItem::UpdateParagraph imageWidth = %{public}f, imageHeight = %{public}f verticalAlign = "
|
||||
"%{public}d",
|
||||
width, height, verticalAlign);
|
||||
CHECK_NULL_RETURN(builder, -1);
|
||||
PlaceholderRun run;
|
||||
run.width = width;
|
||||
run.height = height;
|
||||
switch (verticalAlign) {
|
||||
case VerticalAlign::TOP:
|
||||
run.alignment = PlaceholderAlignment::TOP;
|
||||
break;
|
||||
case VerticalAlign::CENTER:
|
||||
run.alignment = PlaceholderAlignment::MIDDLE;
|
||||
break;
|
||||
case VerticalAlign::BOTTOM:
|
||||
case VerticalAlign::NONE:
|
||||
run.alignment = PlaceholderAlignment::BOTTOM;
|
||||
break;
|
||||
case VerticalAlign::BASELINE:
|
||||
run.alignment = PlaceholderAlignment::ABOVEBASELINE;
|
||||
break;
|
||||
default:
|
||||
run.alignment = PlaceholderAlignment::BOTTOM;
|
||||
}
|
||||
return builder->AddPlaceholder(run);
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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,16 +66,39 @@ namespace OHOS::Ace::NG {
|
||||
|
||||
class Paragraph;
|
||||
|
||||
struct SpanItem : public Referenced {
|
||||
struct SpanItem : public AceType {
|
||||
DECLARE_ACE_TYPE(SpanItem, AceType);
|
||||
|
||||
public:
|
||||
SpanItem() = default;
|
||||
virtual ~SpanItem()
|
||||
{
|
||||
children.clear();
|
||||
}
|
||||
int32_t positon;
|
||||
std::string content;
|
||||
std::unique_ptr<FontStyle> fontStyle;
|
||||
GestureEventFunc onClick;
|
||||
std::list<RefPtr<SpanItem>> children;
|
||||
int32_t placeHolderIndex = -1;
|
||||
|
||||
void UpdateParagraph(const RefPtr<Paragraph>& builder);
|
||||
virtual int32_t UpdateParagraph(const RefPtr<Paragraph>& builder, double width = 0.0f, double height = 0.0f,
|
||||
VerticalAlign verticalAlign = VerticalAlign::BASELINE);
|
||||
|
||||
void ToJsonValue(std::unique_ptr<JsonValue>& json) const;
|
||||
virtual void ToJsonValue(std::unique_ptr<JsonValue>& json) const;
|
||||
};
|
||||
|
||||
struct ImageSpanItem : public SpanItem {
|
||||
DECLARE_ACE_TYPE(ImageSpanItem, SpanItem);
|
||||
|
||||
public:
|
||||
ImageSpanItem() = default;
|
||||
~ImageSpanItem() override = default;
|
||||
int32_t UpdateParagraph(
|
||||
const RefPtr<Paragraph>& builder, double width, double height, VerticalAlign verticalAlign) override;
|
||||
void ToJsonValue(std::unique_ptr<JsonValue>& json) const override {};
|
||||
|
||||
ACE_DISALLOW_COPY_AND_MOVE(ImageSpanItem);
|
||||
};
|
||||
|
||||
class ACE_EXPORT SpanNode : public UINode {
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/components/text/text_theme.h"
|
||||
#include "core/components_ng/base/frame_node.h"
|
||||
#include "core/components_ng/pattern/image/image_layout_property.h"
|
||||
#include "core/components_ng/pattern/text/text_layout_property.h"
|
||||
#include "core/components_ng/pattern/text/text_pattern.h"
|
||||
#include "core/components_ng/render/drawing_prop_convertor.h"
|
||||
@ -84,19 +85,21 @@ std::optional<SizeF> TextLayoutAlgorithm::MeasureContent(
|
||||
UpdateTextColorIfForeground(frameNode, textStyle);
|
||||
|
||||
if (textStyle.GetTextOverflow() == TextOverflow::MARQUEE) {
|
||||
return BuildTextRaceParagraph(textStyle, textLayoutProperty, contentConstraint, pipeline);
|
||||
return BuildTextRaceParagraph(textStyle, textLayoutProperty, contentConstraint, pipeline, layoutWrapper);
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
switch (textLayoutProperty->GetHeightAdaptivePolicyValue(TextHeightAdaptivePolicy::MAX_LINES_FIRST)) {
|
||||
case TextHeightAdaptivePolicy::MAX_LINES_FIRST:
|
||||
result = BuildParagraph(textStyle, textLayoutProperty, contentConstraint, pipeline);
|
||||
result = BuildParagraph(textStyle, textLayoutProperty, contentConstraint, pipeline, layoutWrapper);
|
||||
break;
|
||||
case TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST:
|
||||
result = BuildParagraphAdaptUseMinFontSize(textStyle, textLayoutProperty, contentConstraint, pipeline);
|
||||
result = BuildParagraphAdaptUseMinFontSize(
|
||||
textStyle, textLayoutProperty, contentConstraint, pipeline, layoutWrapper);
|
||||
break;
|
||||
case TextHeightAdaptivePolicy::LAYOUT_CONSTRAINT_FIRST:
|
||||
result = BuildParagraphAdaptUseLayoutConstraint(textStyle, textLayoutProperty, contentConstraint, pipeline);
|
||||
result = BuildParagraphAdaptUseLayoutConstraint(
|
||||
textStyle, textLayoutProperty, contentConstraint, pipeline, layoutWrapper);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -132,7 +135,49 @@ void TextLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
|
||||
layoutWrapper->GetGeometryNode()->SetBaselineDistance(baselineDistance);
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, std::string content)
|
||||
void TextLayoutAlgorithm::UpdateParagraph(LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
int32_t spanTextLength = 0;
|
||||
CHECK_NULL_VOID(layoutWrapper);
|
||||
auto layoutProperty = layoutWrapper->GetLayoutProperty();
|
||||
CHECK_NULL_VOID(layoutProperty);
|
||||
const auto& layoutConstrain = layoutProperty->CreateChildConstraint();
|
||||
const auto& children = layoutWrapper->GetAllChildrenWithBuild();
|
||||
auto iterItems = children.begin();
|
||||
for (const auto& child : spanItemChildren_) {
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
auto imageSpanItem = AceType::DynamicCast<ImageSpanItem>(child);
|
||||
if (imageSpanItem) {
|
||||
if (iterItems == children.end() || !(*iterItems)) {
|
||||
continue;
|
||||
}
|
||||
(*iterItems)->Measure(layoutConstrain);
|
||||
auto verticalAlign = VerticalAlign::BOTTOM;
|
||||
auto imageLayoutProperty = DynamicCast<ImageLayoutProperty>((*iterItems)->GetLayoutProperty());
|
||||
if (imageLayoutProperty) {
|
||||
verticalAlign = imageLayoutProperty->GetVerticalAlign().value_or(VerticalAlign::BOTTOM);
|
||||
}
|
||||
auto geometryNode = (*iterItems)->GetGeometryNode();
|
||||
if (!geometryNode) {
|
||||
iterItems++;
|
||||
continue;
|
||||
}
|
||||
auto width = geometryNode->GetMarginFrameSize().Width();
|
||||
auto height = geometryNode->GetMarginFrameSize().Height();
|
||||
child->placeHolderIndex = child->UpdateParagraph(paragraph_, width, height, verticalAlign);
|
||||
child->positon += 1;
|
||||
iterItems++;
|
||||
} else {
|
||||
child->UpdateParagraph(paragraph_);
|
||||
child->positon = spanTextLength + StringUtils::ToWstring(child->content).length();
|
||||
spanTextLength += StringUtils::ToWstring(child->content).length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, std::string content, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
ParagraphStyle paraStyle = { .direction = GetTextDirection(content),
|
||||
.align = textStyle.GetTextAlign(),
|
||||
@ -148,33 +193,104 @@ bool TextLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, std::strin
|
||||
StringUtils::TransformStrCase(content, static_cast<int32_t>(textStyle.GetTextCase()));
|
||||
paragraph_->AddText(StringUtils::Str8ToStr16(content));
|
||||
} else {
|
||||
int32_t spanTextLength = 0;
|
||||
for (const auto& child : spanItemChildren_) {
|
||||
if (child) {
|
||||
child->UpdateParagraph(paragraph_);
|
||||
child->positon = spanTextLength + StringUtils::ToWstring(child->content).length();
|
||||
spanTextLength += StringUtils::ToWstring(child->content).length();
|
||||
}
|
||||
}
|
||||
UpdateParagraph(layoutWrapper);
|
||||
}
|
||||
paragraph_->Build();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::CreateParagraphAndLayout(
|
||||
const TextStyle& textStyle, const std::string& content, const LayoutConstraintF& contentConstraint)
|
||||
bool TextLayoutAlgorithm::CreateParagraphAndLayout(const TextStyle& textStyle, const std::string& content,
|
||||
const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
if (!CreateParagraph(textStyle, content)) {
|
||||
if (!CreateParagraph(textStyle, content, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
CHECK_NULL_RETURN(paragraph_, false);
|
||||
auto maxSize = GetMaxMeasureSize(contentConstraint);
|
||||
if (GreatNotEqual(textStyle.GetTextIndent().Value(), 0.0)) {
|
||||
ApplyIndents(textStyle, maxSize.Width());
|
||||
}
|
||||
paragraph_->Layout(maxSize.Width());
|
||||
return true;
|
||||
}
|
||||
|
||||
OffsetF TextLayoutAlgorithm::GetContentOffset(LayoutWrapper* layoutWrapper) const
|
||||
{
|
||||
OffsetF contentOffset(0.0, 0.0);
|
||||
CHECK_NULL_RETURN(layoutWrapper, contentOffset);
|
||||
|
||||
auto size = layoutWrapper->GetGeometryNode()->GetFrameSize();
|
||||
const auto& padding = layoutWrapper->GetLayoutProperty()->CreatePaddingAndBorder();
|
||||
MinusPaddingToSize(padding, size);
|
||||
auto left = padding.left.value_or(0);
|
||||
auto top = padding.top.value_or(0);
|
||||
auto paddingOffset = OffsetF(left, top);
|
||||
auto align = Alignment::CENTER;
|
||||
if (layoutWrapper->GetLayoutProperty()->GetPositionProperty()) {
|
||||
align = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().value_or(align);
|
||||
}
|
||||
|
||||
const auto& content = layoutWrapper->GetGeometryNode()->GetContent();
|
||||
if (content) {
|
||||
contentOffset = Alignment::GetAlignPosition(size, content->GetRect().GetSize(), align) + paddingOffset;
|
||||
content->SetOffset(contentOffset);
|
||||
}
|
||||
return contentOffset;
|
||||
}
|
||||
|
||||
void TextLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
CHECK_NULL_VOID(layoutWrapper);
|
||||
auto contentOffset = GetContentOffset(layoutWrapper);
|
||||
CHECK_NULL_VOID(paragraph_);
|
||||
std::vector<int32_t> placeHolderIndex;
|
||||
for (const auto& child : spanItemChildren_) {
|
||||
if (!child) {
|
||||
continue;
|
||||
}
|
||||
auto imageSpanItem = AceType::DynamicCast<ImageSpanItem>(child);
|
||||
if (imageSpanItem) {
|
||||
placeHolderIndex.emplace_back(child->placeHolderIndex);
|
||||
}
|
||||
}
|
||||
if (spanItemChildren_.empty() || placeHolderIndex.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
size_t imageSpanIndex = 0;
|
||||
std::vector<Rect> rectsForPlaceholders;
|
||||
paragraph_->GetRectsForPlaceholders(rectsForPlaceholders);
|
||||
const auto& children = layoutWrapper->GetAllChildrenWithBuild();
|
||||
for (const auto& child : children) {
|
||||
if (!child) {
|
||||
++index;
|
||||
continue;
|
||||
}
|
||||
if (index >= placeHolderIndex.size()) {
|
||||
return;
|
||||
}
|
||||
imageSpanIndex = placeHolderIndex.at(index);
|
||||
if (imageSpanIndex >= rectsForPlaceholders.size() || imageSpanIndex < 0) {
|
||||
++index;
|
||||
continue;
|
||||
}
|
||||
auto rect = rectsForPlaceholders.at(imageSpanIndex);
|
||||
LOGI("ImageSpan Left= %{public}f, Top = %{public}f, width = %{public}f, height = %{public}f", rect.Left(),
|
||||
rect.Top(), rect.Width(), rect.Height());
|
||||
auto geometryNode = child->GetGeometryNode();
|
||||
if (!geometryNode) {
|
||||
++index;
|
||||
continue;
|
||||
}
|
||||
geometryNode->SetMarginFrameOffset(contentOffset + OffsetF(rect.Left(), rect.Top()));
|
||||
child->Layout();
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::AdaptMinTextSize(TextStyle& textStyle, const std::string& content,
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline)
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
double maxFontSize = 0.0;
|
||||
double minFontSize = 0.0;
|
||||
@ -187,7 +303,7 @@ bool TextLayoutAlgorithm::AdaptMinTextSize(TextStyle& textStyle, const std::stri
|
||||
return false;
|
||||
}
|
||||
if (LessNotEqual(maxFontSize, minFontSize) || LessOrEqual(minFontSize, 0.0)) {
|
||||
if (!CreateParagraphAndLayout(textStyle, content, contentConstraint)) {
|
||||
if (!CreateParagraphAndLayout(textStyle, content, contentConstraint, layoutWrapper)) {
|
||||
LOGE("fail to initialize text paragraph when adapt min text size.");
|
||||
return false;
|
||||
}
|
||||
@ -206,7 +322,7 @@ bool TextLayoutAlgorithm::AdaptMinTextSize(TextStyle& textStyle, const std::stri
|
||||
auto maxSize = GetMaxMeasureSize(contentConstraint);
|
||||
while (GreatOrEqual(maxFontSize, minFontSize)) {
|
||||
textStyle.SetFontSize(Dimension(maxFontSize));
|
||||
if (!CreateParagraphAndLayout(textStyle, content, contentConstraint)) {
|
||||
if (!CreateParagraphAndLayout(textStyle, content, contentConstraint, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
if (!DidExceedMaxLines(maxSize)) {
|
||||
@ -271,14 +387,16 @@ std::list<RefPtr<SpanItem>>&& TextLayoutAlgorithm::GetSpanItemChildren()
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::BuildParagraph(TextStyle& textStyle, const RefPtr<TextLayoutProperty>& layoutProperty,
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline)
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
if (!textStyle.GetAdaptTextSize()) {
|
||||
if (!CreateParagraphAndLayout(textStyle, layoutProperty->GetContent().value_or(""), contentConstraint)) {
|
||||
if (!CreateParagraphAndLayout(
|
||||
textStyle, layoutProperty->GetContent().value_or(""), contentConstraint, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!AdaptMinTextSize(textStyle, layoutProperty->GetContent().value_or(""), contentConstraint, pipeline)) {
|
||||
if (!AdaptMinTextSize(
|
||||
textStyle, layoutProperty->GetContent().value_or(""), contentConstraint, pipeline, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -298,9 +416,10 @@ bool TextLayoutAlgorithm::BuildParagraph(TextStyle& textStyle, const RefPtr<Text
|
||||
|
||||
bool TextLayoutAlgorithm::BuildParagraphAdaptUseMinFontSize(TextStyle& textStyle,
|
||||
const RefPtr<TextLayoutProperty>& layoutProperty, const LayoutConstraintF& contentConstraint,
|
||||
const RefPtr<PipelineContext>& pipeline)
|
||||
const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
if (!AdaptMaxTextSize(textStyle, layoutProperty->GetContent().value_or(""), contentConstraint, pipeline)) {
|
||||
if (!AdaptMaxTextSize(
|
||||
textStyle, layoutProperty->GetContent().value_or(""), contentConstraint, pipeline, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -320,10 +439,10 @@ bool TextLayoutAlgorithm::BuildParagraphAdaptUseMinFontSize(TextStyle& textStyle
|
||||
|
||||
bool TextLayoutAlgorithm::BuildParagraphAdaptUseLayoutConstraint(TextStyle& textStyle,
|
||||
const RefPtr<TextLayoutProperty>& layoutProperty, const LayoutConstraintF& contentConstraint,
|
||||
const RefPtr<PipelineContext>& pipeline)
|
||||
const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
// Create the paragraph and obtain the height.
|
||||
if (!BuildParagraph(textStyle, layoutProperty, contentConstraint, pipeline)) {
|
||||
if (!BuildParagraph(textStyle, layoutProperty, contentConstraint, pipeline, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
auto height = static_cast<float>(paragraph_->GetHeight());
|
||||
@ -347,7 +466,7 @@ bool TextLayoutAlgorithm::BuildParagraphAdaptUseLayoutConstraint(TextStyle& text
|
||||
textStyle.SetMaxLines(maxLines);
|
||||
textStyle.DisableAdaptTextSize();
|
||||
|
||||
if (!BuildParagraph(textStyle, layoutProperty, contentConstraint, pipeline)) {
|
||||
if (!BuildParagraph(textStyle, layoutProperty, contentConstraint, pipeline, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -361,7 +480,7 @@ bool TextLayoutAlgorithm::BuildParagraphAdaptUseLayoutConstraint(TextStyle& text
|
||||
maxLines = textStyle.GetMaxLines() - 1;
|
||||
textStyle.SetMaxLines(maxLines);
|
||||
}
|
||||
if (!BuildParagraph(textStyle, layoutProperty, contentConstraint, pipeline)) {
|
||||
if (!BuildParagraph(textStyle, layoutProperty, contentConstraint, pipeline, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
height = static_cast<float>(paragraph_->GetHeight());
|
||||
@ -371,13 +490,13 @@ bool TextLayoutAlgorithm::BuildParagraphAdaptUseLayoutConstraint(TextStyle& text
|
||||
|
||||
std::optional<SizeF> TextLayoutAlgorithm::BuildTextRaceParagraph(TextStyle& textStyle,
|
||||
const RefPtr<TextLayoutProperty>& layoutProperty, const LayoutConstraintF& contentConstraint,
|
||||
const RefPtr<PipelineContext>& pipeline)
|
||||
const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
// create a paragraph with all text in 1 line
|
||||
textStyle.SetTextOverflow(TextOverflow::CLIP);
|
||||
textStyle.SetMaxLines(1);
|
||||
textStyle.SetTextAlign(TextAlign::START);
|
||||
if (!CreateParagraph(textStyle, layoutProperty->GetContent().value_or(""))) {
|
||||
if (!CreateParagraph(textStyle, layoutProperty->GetContent().value_or(""), layoutWrapper)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!paragraph_) {
|
||||
@ -447,23 +566,21 @@ void TextLayoutAlgorithm::SetPropertyToModifier(
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::AdaptMaxTextSize(TextStyle& textStyle, const std::string& content,
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline)
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
double maxFontSize = 0.0;
|
||||
double minFontSize = 0.0;
|
||||
if (!textStyle.GetAdaptMaxFontSize().NormalizeToPx(
|
||||
pipeline->GetDipScale(), pipeline->GetFontScale(), pipeline->GetLogicScale(),
|
||||
contentConstraint.maxSize.Height(), maxFontSize)) {
|
||||
if (!textStyle.GetAdaptMaxFontSize().NormalizeToPx(pipeline->GetDipScale(), pipeline->GetFontScale(),
|
||||
pipeline->GetLogicScale(), contentConstraint.maxSize.Height(), maxFontSize)) {
|
||||
return false;
|
||||
}
|
||||
if (!textStyle.GetAdaptMinFontSize().NormalizeToPx(
|
||||
pipeline->GetDipScale(), pipeline->GetFontScale(), pipeline->GetLogicScale(),
|
||||
contentConstraint.maxSize.Height(), minFontSize)) {
|
||||
if (!textStyle.GetAdaptMinFontSize().NormalizeToPx(pipeline->GetDipScale(), pipeline->GetFontScale(),
|
||||
pipeline->GetLogicScale(), contentConstraint.maxSize.Height(), minFontSize)) {
|
||||
return false;
|
||||
}
|
||||
if (LessNotEqual(maxFontSize, minFontSize) || LessOrEqual(minFontSize, 0.0)) {
|
||||
// minFontSize or maxFontSize is invalid
|
||||
if (!CreateParagraphAndLayout(textStyle, content, contentConstraint)) {
|
||||
if (!CreateParagraphAndLayout(textStyle, content, contentConstraint, layoutWrapper)) {
|
||||
LOGE("fail to initialize text paragraph when adapt min text size.");
|
||||
return false;
|
||||
}
|
||||
@ -485,7 +602,7 @@ bool TextLayoutAlgorithm::AdaptMaxTextSize(TextStyle& textStyle, const std::stri
|
||||
// line, then increase the font size and try to layout using the maximum available fontsize.
|
||||
while (LessOrEqual(minFontSize, maxFontSize)) {
|
||||
textStyle.SetFontSize(Dimension(minFontSize));
|
||||
if (!CreateParagraphAndLayout(textStyle, content, contentConstraint)) {
|
||||
if (!CreateParagraphAndLayout(textStyle, content, contentConstraint, layoutWrapper)) {
|
||||
return false;
|
||||
}
|
||||
if (paragraph_->GetLineCount() > 1 || paragraph_->DidExceedMaxLines() ||
|
||||
@ -517,4 +634,26 @@ void TextLayoutAlgorithm::UpdateTextColorIfForeground(const RefPtr<FrameNode>& f
|
||||
textStyle.SetTextColor(Color::FOREGROUND);
|
||||
}
|
||||
}
|
||||
|
||||
void TextLayoutAlgorithm::ApplyIndents(const TextStyle& textStyle, double width)
|
||||
{
|
||||
CHECK_NULL_VOID(paragraph_);
|
||||
auto pipeline = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(pipeline);
|
||||
std::vector<float> indents;
|
||||
double indent = 0.0;
|
||||
if (textStyle.GetTextIndent().Unit() != DimensionUnit::PERCENT) {
|
||||
if (!textStyle.GetTextIndent().NormalizeToPx(
|
||||
pipeline->GetDipScale(), pipeline->GetFontScale(), pipeline->GetLogicScale(), width, indent)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
indent = width * textStyle.GetTextIndent().Value();
|
||||
}
|
||||
if (indent > 0.0) {
|
||||
indents.emplace_back(static_cast<float>(indent));
|
||||
indents.emplace_back(0.0);
|
||||
paragraph_->SetIndents(indents);
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -50,6 +50,8 @@ public:
|
||||
std::optional<SizeF> MeasureContent(
|
||||
const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) override;
|
||||
|
||||
void Layout(LayoutWrapper* layoutWrapper) override;
|
||||
|
||||
const RefPtr<Paragraph>& GetParagraph();
|
||||
|
||||
std::list<RefPtr<SpanItem>>&& GetSpanItemChildren();
|
||||
@ -57,29 +59,36 @@ public:
|
||||
float GetBaselineOffset() const;
|
||||
|
||||
std::optional<TextStyle> GetTextStyle() const;
|
||||
void ApplyIndents(const TextStyle& textStyle, double width);
|
||||
|
||||
private:
|
||||
bool CreateParagraph(const TextStyle& textStyle, std::string content);
|
||||
bool CreateParagraphAndLayout(
|
||||
const TextStyle& textStyle, const std::string& content, const LayoutConstraintF& contentConstraint);
|
||||
bool CreateParagraph(const TextStyle& textStyle, std::string content, LayoutWrapper* layoutWrapper);
|
||||
bool CreateParagraphAndLayout(const TextStyle& textStyle, const std::string& content,
|
||||
const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper);
|
||||
bool AdaptMinTextSize(TextStyle& textStyle, const std::string& content, const LayoutConstraintF& contentConstraint,
|
||||
const RefPtr<PipelineContext>& pipeline);
|
||||
const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper);
|
||||
bool DidExceedMaxLines(const SizeF& maxSize);
|
||||
static TextDirection GetTextDirection(const std::string& content);
|
||||
float GetTextWidth() const;
|
||||
SizeF GetMaxMeasureSize(const LayoutConstraintF& contentConstraint) const;
|
||||
bool BuildParagraph(TextStyle& textStyle, const RefPtr<TextLayoutProperty>& layoutProperty,
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline);
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline,
|
||||
LayoutWrapper* layoutWrapper);
|
||||
bool BuildParagraphAdaptUseMinFontSize(TextStyle& textStyle, const RefPtr<TextLayoutProperty>& layoutProperty,
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline);
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline,
|
||||
LayoutWrapper* layoutWrapper);
|
||||
bool BuildParagraphAdaptUseLayoutConstraint(TextStyle& textStyle, const RefPtr<TextLayoutProperty>& layoutProperty,
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline);
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline,
|
||||
LayoutWrapper* layoutWrapper);
|
||||
std::optional<SizeF> BuildTextRaceParagraph(TextStyle& textStyle, const RefPtr<TextLayoutProperty>& layoutProperty,
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline);
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline,
|
||||
LayoutWrapper* layoutWrapper);
|
||||
void SetPropertyToModifier(const RefPtr<TextLayoutProperty>& layoutProperty, RefPtr<TextContentModifier> modifier);
|
||||
bool AdaptMaxTextSize(TextStyle& textStyle, const std::string& content, const LayoutConstraintF& contentConstraint,
|
||||
const RefPtr<PipelineContext>& pipeline);
|
||||
const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper);
|
||||
void UpdateTextColorIfForeground(const RefPtr<FrameNode>& frameNode, TextStyle& textStyle);
|
||||
void UpdateParagraph(LayoutWrapper* layoutWrapper);
|
||||
OffsetF GetContentOffset(LayoutWrapper* layoutWrapper) const;
|
||||
|
||||
std::list<RefPtr<SpanItem>> spanItemChildren_;
|
||||
RefPtr<Paragraph> paragraph_;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -73,6 +73,7 @@ public:
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, MaxLines, uint32_t, PROPERTY_UPDATE_MEASURE);
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(
|
||||
TextLineStyle, HeightAdaptivePolicy, TextHeightAdaptivePolicy, PROPERTY_UPDATE_MEASURE);
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, TextIndent, Dimension, PROPERTY_UPDATE_MEASURE);
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Content, std::string, PROPERTY_UPDATE_MEASURE);
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(CopyOption, CopyOptions, PROPERTY_UPDATE_MEASURE);
|
||||
ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Draggable, bool, PROPERTY_UPDATE_MEASURE);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -45,6 +45,7 @@ public:
|
||||
virtual void SetTextAlign(TextAlign value) = 0;
|
||||
virtual void SetTextOverflow(TextOverflow value) = 0;
|
||||
virtual void SetMaxLines(uint32_t value) = 0;
|
||||
virtual void SetTextIndent(const Dimension& value) = 0;
|
||||
virtual void SetLineHeight(const Dimension& value) = 0;
|
||||
virtual void SetTextDecoration(TextDecoration value) = 0;
|
||||
virtual void SetTextDecorationColor(const Color& value) = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -90,6 +90,11 @@ void TextModelNG::SetMaxLines(uint32_t value)
|
||||
ACE_UPDATE_LAYOUT_PROPERTY(TextLayoutProperty, MaxLines, value);
|
||||
}
|
||||
|
||||
void TextModelNG::SetTextIndent(const Dimension& value)
|
||||
{
|
||||
ACE_UPDATE_LAYOUT_PROPERTY(TextLayoutProperty, TextIndent, value);
|
||||
}
|
||||
|
||||
void TextModelNG::SetLineHeight(const Dimension& value)
|
||||
{
|
||||
ACE_UPDATE_LAYOUT_PROPERTY(TextLayoutProperty, LineHeight, value);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -35,6 +35,7 @@ public:
|
||||
void SetTextAlign(TextAlign value) override;
|
||||
void SetTextOverflow(TextOverflow value) override;
|
||||
void SetMaxLines(uint32_t value) override;
|
||||
void SetTextIndent(const Dimension& value) override;
|
||||
void SetLineHeight(const Dimension& value) override;
|
||||
void SetTextDecoration(TextDecoration value) override;
|
||||
void SetTextDecorationColor(const Color& value) override;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -589,12 +589,10 @@ void TextPattern::BeforeCreateLayoutWrapper()
|
||||
CHECK_NULL_VOID(host);
|
||||
const auto& layoutProperty = host->GetLayoutProperty();
|
||||
auto flag = layoutProperty ? layoutProperty->GetPropertyChangeFlag() : PROPERTY_UPDATE_NORMAL;
|
||||
if (paragraph_) {
|
||||
// When updating the scenario, needs to determine whether the SpanNode node is refreshed.
|
||||
if ((flag & PROPERTY_UPDATE_BY_CHILD_REQUEST) != PROPERTY_UPDATE_BY_CHILD_REQUEST) {
|
||||
LOGD("no need to refresh span node");
|
||||
return;
|
||||
}
|
||||
// When updating the scenario, needs to determine whether the SpanNode node is refreshed.
|
||||
if (paragraph_ && (flag & PROPERTY_UPDATE_BY_CHILD_REQUEST) != PROPERTY_UPDATE_BY_CHILD_REQUEST) {
|
||||
LOGD("no need to refresh span node");
|
||||
return;
|
||||
}
|
||||
|
||||
// When dirty areas are marked because of child node changes, the text rendering node tree is reset.
|
||||
@ -635,6 +633,8 @@ void TextPattern::BeforeCreateLayoutWrapper()
|
||||
if (spanNode->GetSpanItem()->onClick) {
|
||||
isSpanHasClick = true;
|
||||
}
|
||||
} else if (current->GetTag() == V2::IMAGE_ETS_TAG) {
|
||||
AddChildSpanItem(current);
|
||||
}
|
||||
const auto& nextChildren = current->GetChildren();
|
||||
for (auto iter = nextChildren.rbegin(); iter != nextChildren.rend(); ++iter) {
|
||||
@ -673,6 +673,22 @@ void TextPattern::OnVisibleChange(bool isVisible)
|
||||
}
|
||||
}
|
||||
|
||||
void TextPattern::AddChildSpanItem(const RefPtr<UINode>& child)
|
||||
{
|
||||
CHECK_NULL_VOID(child);
|
||||
if (child->GetTag() == V2::SPAN_ETS_TAG) {
|
||||
auto spanNode = DynamicCast<SpanNode>(child);
|
||||
if (spanNode) {
|
||||
spanItemChildren_.emplace_back(spanNode->GetSpanItem());
|
||||
}
|
||||
} else if (child->GetTag() == V2::IMAGE_ETS_TAG) {
|
||||
auto imageNode = DynamicCast<FrameNode>(child);
|
||||
if (imageNode) {
|
||||
spanItemChildren_.emplace_back(MakeRefPtr<ImageSpanItem>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextPattern::DumpInfo()
|
||||
{
|
||||
auto textLayoutProp = GetLayoutProperty<TextLayoutProperty>();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -82,10 +82,7 @@ public:
|
||||
|
||||
void BeforeCreateLayoutWrapper() override;
|
||||
|
||||
void AddChildSpanItem(const RefPtr<SpanNode>& child)
|
||||
{
|
||||
spanItemChildren_.emplace_back(child->GetSpanItem());
|
||||
}
|
||||
void AddChildSpanItem(const RefPtr<UINode>& child);
|
||||
|
||||
FocusPattern GetFocusPattern() const override
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -50,6 +50,7 @@ TextStyle CreateTextStyleUsingTheme(const std::unique_ptr<FontStyle>& fontStyle,
|
||||
UPDATE_TEXT_STYLE(textLineStyle, TextOverflow, SetTextOverflow);
|
||||
UPDATE_TEXT_STYLE(textLineStyle, TextAlign, SetTextAlign);
|
||||
UPDATE_TEXT_STYLE(textLineStyle, MaxLines, SetMaxLines);
|
||||
UPDATE_TEXT_STYLE(textLineStyle, TextIndent, SetTextIndent);
|
||||
}
|
||||
return textStyle;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -47,6 +47,7 @@ struct TextLineStyle {
|
||||
ACE_DEFINE_PROPERTY_GROUP_ITEM(MaxLength, uint32_t);
|
||||
ACE_DEFINE_PROPERTY_GROUP_ITEM(MaxLines, uint32_t);
|
||||
ACE_DEFINE_PROPERTY_GROUP_ITEM(HeightAdaptivePolicy, TextHeightAdaptivePolicy);
|
||||
ACE_DEFINE_PROPERTY_GROUP_ITEM(TextIndent, Dimension);
|
||||
};
|
||||
|
||||
TextStyle CreateTextStyleUsingTheme(const std::unique_ptr<FontStyle>& fontStyle,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -82,6 +82,17 @@ void TxtParagraph::AddText(const std::u16string& text)
|
||||
builder_->AddText(text);
|
||||
}
|
||||
|
||||
int32_t TxtParagraph::AddPlaceholder(const PlaceholderRun& span)
|
||||
{
|
||||
if (!builder_) {
|
||||
CreateBuilder();
|
||||
}
|
||||
txt::PlaceholderRun txtSpan;
|
||||
Constants::ConvertPlaceholderRun(span, txtSpan);
|
||||
builder_->AddPlaceholder(txtSpan);
|
||||
return ++placeHolderIndex_;
|
||||
}
|
||||
|
||||
void TxtParagraph::Build()
|
||||
{
|
||||
CHECK_NULL_VOID_NOLOG(builder_);
|
||||
@ -255,6 +266,7 @@ bool TxtParagraph::ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics&
|
||||
|
||||
void TxtParagraph::GetRectsForRange(int32_t start, int32_t end, std::vector<Rect>& selectedRects)
|
||||
{
|
||||
CHECK_NULL_VOID(paragraph_);
|
||||
const auto& boxes = paragraph_->GetRectsForRange(
|
||||
start, end, txt::Paragraph::RectHeightStyle::kMax, txt::Paragraph::RectWidthStyle::kTight);
|
||||
if (boxes.empty()) {
|
||||
@ -266,4 +278,24 @@ void TxtParagraph::GetRectsForRange(int32_t start, int32_t end, std::vector<Rect
|
||||
}
|
||||
}
|
||||
|
||||
void TxtParagraph::GetRectsForPlaceholders(std::vector<Rect>& selectedRects)
|
||||
{
|
||||
CHECK_NULL_VOID(paragraph_);
|
||||
const auto& boxes = paragraph_->GetRectsForPlaceholders();
|
||||
if (boxes.empty()) {
|
||||
return;
|
||||
}
|
||||
for (const auto& box : boxes) {
|
||||
auto selectionRect = Constants::ConvertSkRect(box.rect);
|
||||
selectedRects.emplace_back(selectionRect);
|
||||
}
|
||||
}
|
||||
|
||||
void TxtParagraph::SetIndents(const std::vector<float>& indents)
|
||||
{
|
||||
auto* paragraphTxt = static_cast<txt::ParagraphTxt*>(paragraph_.get());
|
||||
CHECK_NULL_VOID(paragraphTxt);
|
||||
paragraphTxt->SetIndents(indents);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -43,6 +43,7 @@ public:
|
||||
void PopStyle() override;
|
||||
|
||||
void AddText(const std::u16string& text) override;
|
||||
int32_t AddPlaceholder(const PlaceholderRun& span) override;
|
||||
void Build() override;
|
||||
void Reset() override;
|
||||
|
||||
@ -64,8 +65,10 @@ public:
|
||||
// interfaces for calculate the the specified paragraph position
|
||||
int32_t GetHandlePositionForClick(const Offset& offset) override;
|
||||
void GetRectsForRange(int32_t start, int32_t end, std::vector<Rect>& selectedRects) override;
|
||||
void GetRectsForPlaceholders(std::vector<Rect>& selectedRects) override;
|
||||
bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics& result) override;
|
||||
bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& result) override;
|
||||
void SetIndents(const std::vector<float>& indents) override;
|
||||
|
||||
private:
|
||||
void CreateBuilder();
|
||||
@ -74,6 +77,7 @@ private:
|
||||
std::unique_ptr<txt::ParagraphBuilder> builder_;
|
||||
std::shared_ptr<txt::FontCollection> fontCollection_;
|
||||
std::u16string text_;
|
||||
int32_t placeHolderIndex_ = -1;
|
||||
|
||||
ACE_DISALLOW_COPY_AND_MOVE(TxtParagraph);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Copyright (c) 2022-2023 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
|
||||
@ -48,6 +48,7 @@ public:
|
||||
virtual void PushStyle(const TextStyle& style) = 0;
|
||||
virtual void PopStyle() = 0;
|
||||
virtual void AddText(const std::u16string& text) = 0;
|
||||
virtual int32_t AddPlaceholder(const PlaceholderRun& span) = 0;
|
||||
virtual void Build() = 0;
|
||||
virtual void Reset() = 0;
|
||||
|
||||
@ -63,8 +64,10 @@ public:
|
||||
virtual float GetAlphabeticBaseline() = 0;
|
||||
virtual int32_t GetHandlePositionForClick(const Offset& offset) = 0;
|
||||
virtual void GetRectsForRange(int32_t start, int32_t end, std::vector<Rect>& selectedRects) = 0;
|
||||
virtual void GetRectsForPlaceholders(std::vector<Rect>& selectedRects) = 0;
|
||||
virtual bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics& result) = 0;
|
||||
virtual bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& result) = 0;
|
||||
virtual void SetIndents(const std::vector<float>& indents) = 0;
|
||||
|
||||
// interfaces for painting
|
||||
virtual void Paint(const RSCanvas& canvas, float x, float y) = 0;
|
||||
|
@ -30,19 +30,19 @@ std::optional<SizeF> TextLayoutAlgorithm::MeasureContent(
|
||||
return SizeF(1.0f, 1.0f);
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, std::string content)
|
||||
bool TextLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, std::string content, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::CreateParagraphAndLayout(
|
||||
const TextStyle& textStyle, const std::string& content, const LayoutConstraintF& contentConstraint)
|
||||
bool TextLayoutAlgorithm::CreateParagraphAndLayout(const TextStyle& textStyle, const std::string& content,
|
||||
const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextLayoutAlgorithm::AdaptMinTextSize(TextStyle& textStyle, const std::string& content,
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline)
|
||||
const LayoutConstraintF& contentConstraint, const RefPtr<PipelineContext>& pipeline, LayoutWrapper* layoutWrapper)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -86,4 +86,6 @@ std::optional<TextStyle> TextLayoutAlgorithm::GetTextStyle() const
|
||||
{
|
||||
return std::optional<TextStyle>(TextStyle());
|
||||
}
|
||||
|
||||
void TextLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) {}
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
@ -134,4 +134,14 @@ bool TxtParagraph::ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& r
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t TxtParagraph::AddPlaceholder(const PlaceholderRun& span)
|
||||
{
|
||||
placeHolderIndex_ = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TxtParagraph::GetRectsForPlaceholders(std::vector<Rect>& selectedRects) {}
|
||||
|
||||
void TxtParagraph::SetIndents(const std::vector<float>& indents) {}
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
@ -703,7 +703,7 @@ HWTEST_F(TextTestNg, OnDirtyLayoutWrapperSwap003, TestSize.Level1)
|
||||
auto rowLayoutAlgorithm = AceType::DynamicCast<TextLayoutAlgorithm>(pattern->CreateLayoutAlgorithm());
|
||||
TextStyle textStyle;
|
||||
LayoutConstraintF contentConstraint;
|
||||
auto ret = rowLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint);
|
||||
auto ret = rowLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint, nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
layoutWrapper->SetLayoutAlgorithm(AceType::MakeRefPtr<LayoutAlgorithmWrapper>(rowLayoutAlgorithm));
|
||||
ret = pattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config);
|
||||
@ -730,7 +730,7 @@ HWTEST_F(TextTestNg, BeforeCreateLayoutWrapper001, TestSize.Level1)
|
||||
auto rowLayoutAlgorithm = AceType::DynamicCast<TextLayoutAlgorithm>(pattern->CreateLayoutAlgorithm());
|
||||
TextStyle textStyle;
|
||||
LayoutConstraintF contentConstraint;
|
||||
auto ret = rowLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint);
|
||||
auto ret = rowLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint, nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
auto layoutWrapper = AceType::MakeRefPtr<LayoutWrapper>(
|
||||
frameNode, AceType::MakeRefPtr<GeometryNode>(), frameNode->GetLayoutProperty());
|
||||
@ -785,7 +785,7 @@ HWTEST_F(TextTestNg, BeforeCreateLayoutWrapper003, TestSize.Level1)
|
||||
auto rowLayoutAlgorithm = AceType::DynamicCast<TextLayoutAlgorithm>(pattern->CreateLayoutAlgorithm());
|
||||
TextStyle textStyle;
|
||||
LayoutConstraintF contentConstraint;
|
||||
auto ret = rowLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint);
|
||||
auto ret = rowLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint, nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
|
||||
DirtySwapConfig config;
|
||||
@ -1069,7 +1069,8 @@ HWTEST_F(TextTestNg, TextLayoutTest003, TestSize.Level1)
|
||||
*/
|
||||
|
||||
auto textLayoutAlgorithm = AceType::MakeRefPtr<TextLayoutAlgorithm>();
|
||||
auto result = textLayoutAlgorithm->AdaptMinTextSize(textStyle, CREATE_VALUE, parentLayoutConstraint, pipeline);
|
||||
auto result =
|
||||
textLayoutAlgorithm->AdaptMinTextSize(textStyle, CREATE_VALUE, parentLayoutConstraint, pipeline, nullptr);
|
||||
|
||||
/**
|
||||
* @tc.steps: step4. check the fontSize.
|
||||
@ -1122,7 +1123,8 @@ HWTEST_F(TextTestNg, TextLayoutTest004, TestSize.Level1)
|
||||
*/
|
||||
|
||||
auto textLayoutAlgorithm = AceType::MakeRefPtr<TextLayoutAlgorithm>();
|
||||
auto result = textLayoutAlgorithm->AdaptMinTextSize(textStyle, CREATE_VALUE, parentLayoutConstraint, pipeline);
|
||||
auto result =
|
||||
textLayoutAlgorithm->AdaptMinTextSize(textStyle, CREATE_VALUE, parentLayoutConstraint, pipeline, nullptr);
|
||||
|
||||
/**
|
||||
* @tc.steps: step4. check the fontSize.
|
||||
@ -1175,7 +1177,8 @@ HWTEST_F(TextTestNg, TextLayoutTest005, TestSize.Level1)
|
||||
*/
|
||||
|
||||
auto textLayoutAlgorithm = AceType::MakeRefPtr<TextLayoutAlgorithm>();
|
||||
auto result = textLayoutAlgorithm->AdaptMinTextSize(textStyle, CREATE_VALUE, parentLayoutConstraint, pipeline);
|
||||
auto result =
|
||||
textLayoutAlgorithm->AdaptMinTextSize(textStyle, CREATE_VALUE, parentLayoutConstraint, pipeline, nullptr);
|
||||
|
||||
/**
|
||||
* @tc.steps: step4. check the fontSize.
|
||||
@ -1223,7 +1226,7 @@ HWTEST_F(TextTestNg, TextLayoutTest006, TestSize.Level1)
|
||||
auto textLayoutAlgorithm = AceType::MakeRefPtr<TextLayoutAlgorithm>();
|
||||
TextStyle textStyle;
|
||||
LayoutConstraintF contentConstraint;
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint);
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint, nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
auto sizeX =
|
||||
textLayoutAlgorithm->MeasureContent(parentLayoutConstraint, AccessibilityManager::RawPtr(layoutWrapper));
|
||||
@ -1276,7 +1279,7 @@ HWTEST_F(TextTestNg, TextLayoutTest007, TestSize.Level1)
|
||||
TextStyle textStyle;
|
||||
Dimension adaptMinFontSize(DIMENSION, DimensionUnit::PERCENT);
|
||||
textStyle.SetAdaptMinFontSize(adaptMinFontSize);
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", parentLayoutConstraint);
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", parentLayoutConstraint, nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
auto sizeX =
|
||||
textLayoutAlgorithm->MeasureContent(parentLayoutConstraint, AccessibilityManager::RawPtr(layoutWrapper));
|
||||
@ -1330,7 +1333,7 @@ HWTEST_F(TextTestNg, TextLayoutTest008, TestSize.Level1)
|
||||
TextStyle textStyle;
|
||||
Dimension adaptMinFontSize(DIMENSION, DimensionUnit::PERCENT);
|
||||
textStyle.SetAdaptMinFontSize(adaptMinFontSize);
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", parentLayoutConstraint);
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", parentLayoutConstraint, nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
auto sizeX =
|
||||
textLayoutAlgorithm->MeasureContent(parentLayoutConstraint, AccessibilityManager::RawPtr(layoutWrapper));
|
||||
@ -1574,7 +1577,7 @@ HWTEST_F(TextTestNg, DidExceedMaxLines001, TestSize.Level1)
|
||||
auto textLayoutAlgorithm = AceType::MakeRefPtr<TextLayoutAlgorithm>();
|
||||
TextStyle textStyle;
|
||||
LayoutConstraintF contentConstraint;
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint);
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint, nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
SizeF maxSize;
|
||||
ret = textLayoutAlgorithm->DidExceedMaxLines(maxSize);
|
||||
@ -1626,7 +1629,7 @@ HWTEST_F(TextTestNg, DidExceedMaxLines002, TestSize.Level1)
|
||||
TextStyle textStyle;
|
||||
textStyle.SetMaxLines(MAX_LINES);
|
||||
LayoutConstraintF contentConstraint;
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint);
|
||||
auto ret = textLayoutAlgorithm->CreateParagraphAndLayout(textStyle, "", contentConstraint, nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
SizeF maxSize;
|
||||
ret = textLayoutAlgorithm->DidExceedMaxLines(maxSize);
|
||||
@ -2193,25 +2196,28 @@ HWTEST_F(TextTestNg, TextLayoutAlgorithmTest008, TestSize.Level1)
|
||||
// maxFontSize < minFontSize
|
||||
textStyle.SetAdaptMaxFontSize(ADAPT_MIN_FONT_SIZE_VALUE);
|
||||
textStyle.SetAdaptMinFontSize(ADAPT_MAX_FONT_SIZE_VALUE);
|
||||
EXPECT_EQ(textLayoutAlgorithm->AdaptMaxTextSize(textStyle, "abc", parentLayoutConstraint, pipeline), false);
|
||||
EXPECT_EQ(
|
||||
textLayoutAlgorithm->AdaptMaxTextSize(textStyle, "abc", parentLayoutConstraint, pipeline, nullptr), false);
|
||||
|
||||
// create paragraph failed
|
||||
textStyle.SetAdaptMaxFontSize(ADAPT_MAX_FONT_SIZE_VALUE);
|
||||
textStyle.SetAdaptMinFontSize(ADAPT_MIN_FONT_SIZE_VALUE);
|
||||
EXPECT_EQ(textLayoutAlgorithm->AdaptMaxTextSize(textStyle, "abc", parentLayoutConstraint, pipeline), false);
|
||||
EXPECT_EQ(
|
||||
textLayoutAlgorithm->AdaptMaxTextSize(textStyle, "abc", parentLayoutConstraint, pipeline, nullptr), false);
|
||||
|
||||
MockTxtParagraph::SetCanConstruct(true);
|
||||
|
||||
// increase font size
|
||||
std::vector<bool> didExceedMaxLines = { false, true };
|
||||
MockTxtParagraph::SetDidExceedMaxLines(didExceedMaxLines);
|
||||
EXPECT_EQ(textLayoutAlgorithm->AdaptMaxTextSize(textStyle, "abc", parentLayoutConstraint, pipeline), true);
|
||||
EXPECT_EQ(textLayoutAlgorithm->AdaptMaxTextSize(textStyle, "abc", parentLayoutConstraint, pipeline, nullptr), true);
|
||||
didExceedMaxLines.clear();
|
||||
MockTxtParagraph::SetDidExceedMaxLines(didExceedMaxLines);
|
||||
|
||||
// set NormalizeToPx false
|
||||
textStyle.adaptFontSizeStep_.SetUnit(DimensionUnit::CALC);
|
||||
EXPECT_EQ(textLayoutAlgorithm->AdaptMaxTextSize(textStyle, "abc", parentLayoutConstraint, pipeline), false);
|
||||
EXPECT_EQ(
|
||||
textLayoutAlgorithm->AdaptMaxTextSize(textStyle, "abc", parentLayoutConstraint, pipeline, nullptr), false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -44,6 +44,9 @@ public:
|
||||
MOCK_METHOD1(AddText, void(const std::u16string& text));
|
||||
MOCK_METHOD1(Layout, void(float width));
|
||||
MOCK_METHOD1(GetHandlePositionForClick, int32_t(const Offset& offset));
|
||||
MOCK_METHOD1(AddPlaceholder, int32_t(const PlaceholderRun& span));
|
||||
MOCK_METHOD1(GetRectsForPlaceholders, void(std::vector<Rect>& selectedRects));
|
||||
MOCK_METHOD1(SetIndents, void(const std::vector<float>& indents));
|
||||
MOCK_METHOD2(ComputeOffsetForCaretDownstream, bool(int32_t extent, CaretMetrics& result));
|
||||
MOCK_METHOD2(ComputeOffsetForCaretUpstream, bool(int32_t extent, CaretMetrics& result));
|
||||
MOCK_METHOD3(GetRectsForRange, void(int32_t start, int32_t end, std::vector<Rect>& selectedRects));
|
||||
|
Loading…
Reference in New Issue
Block a user