1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_IMAGE_IMAGE_LAYOUT_PROPERTY_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_IMAGE_IMAGE_LAYOUT_PROPERTY_H
18 
19 #include "core/common/ace_application_info.h"
20 #include "core/components/common/properties/text_style.h"
21 #include "core/components_ng/base/inspector_filter.h"
22 #include "core/components_ng/layout/layout_property.h"
23 #include "core/components_ng/property/property.h"
24 #include "core/image/image_source_info.h"
25 #include "core/pipeline_ng/pipeline_context.h"
26 
27 namespace OHOS::Ace::NG {
28 class ImagePattern;
29 struct ImageSizeStyle {
30     ACE_DEFINE_PROPERTY_GROUP_ITEM(AutoResize, bool);
31     ACE_DEFINE_PROPERTY_GROUP_ITEM(SourceSize, SizeF);
32     ACE_DEFINE_PROPERTY_GROUP_ITEM(FitOriginalSize, bool);
ToJsonValueImageSizeStyle33     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
34     {
35         /* no fixed attr below, just return */
36         if (filter.IsFastFilter()) {
37             return;
38         }
39         json->PutExtAttr("sourceSize", propSourceSize.value_or(SizeF()).ToString().c_str(), filter);
40         json->PutExtAttr("fitOriginalSize", propFitOriginalSize.value_or(false) ? "true" : "false", filter);
41         json->PutExtAttr("autoResize", propAutoResize.value_or(true) ? "true" : "false", filter);
42     }
43 };
44 
45 class ACE_EXPORT ImageLayoutProperty : public LayoutProperty {
46     DECLARE_ACE_TYPE(ImageLayoutProperty, LayoutProperty);
47 
48 public:
49     ImageLayoutProperty() = default;
50 
51     ~ImageLayoutProperty() override = default;
52 
Clone()53     RefPtr<LayoutProperty> Clone() const override
54     {
55         auto value = MakeRefPtr<ImageLayoutProperty>();
56         value->LayoutProperty::UpdateLayoutProperty(DynamicCast<LayoutProperty>(this));
57         value->propImageSourceInfo_ = CloneImageSourceInfo();
58         value->propAlt_ = CloneAlt();
59         value->propImageFit_ = CloneImageFit();
60         value->propImageSizeStyle_ = CloneImageSizeStyle();
61         value->propVerticalAlign_ = CloneVerticalAlign();
62         return value;
63     }
64 
Reset()65     void Reset() override
66     {
67         LayoutProperty::Reset();
68         ResetImageSourceInfo();
69         ResetAlt();
70         ResetImageFit();
71         ResetImageSizeStyle();
72         ResetVerticalAlign();
73     }
74 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)75     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
76     {
77         LayoutProperty::ToJsonValue(json, filter);
78         ACE_PROPERTY_TO_JSON_VALUE(propImageSizeStyle_, ImageSizeStyle);
79         if (GetHasPlaceHolderStyle().has_value()) {
80             TextBackgroundStyle::ToJsonValue(json, GetPlaceHolderStyle(), filter);
81         }
82         std::string src;
83         if (propImageSourceInfo_.has_value()) {
84             src = propImageSourceInfo_->GetSrc();
85             if (src.find("resources") != std::string::npos) {
86                 auto num = src.find("resources");
87                 src = src.substr(num);
88             }
89             for (auto& character : src) {
90                 character = tolower(character);
91             }
92         }
93         if (filter.IsFastFilter()) {
94             json->PutFixedAttr("src", src.c_str(), filter, FIXED_ATTR_SRC);
95             return;
96         }
97         static const char* OBJECTFITVALUE[] = { "ImageFit.Fill", "ImageFit.Contain", "ImageFit.Cover", "ImageFit.Auto",
98             "ImageFit.FitHeight", "ImageFit.None", "ImageFit.ScaleDown", "ImageFit.TOP_START", "ImageFit.TOP",
99             "ImageFit.TOP_END", "ImageFit.START", "ImageFit.CENTER", "ImageFit.END", "ImageFit.BOTTOM_START",
100             "ImageFit.BOTTOM", "ImageFit.BOTTOM_END" };
101         static const char* VERTICALALIGNVALUE[] = { "VerticalAlign.NONE", "VerticalAlign.TOP", "VerticalAlign.CENTER",
102             "VerticalAlign.BOTTOM", "VerticalAlign.BASELINE", "VerticalAlign.NONE" };
103         json->PutExtAttr("alt", propAlt_.value_or(ImageSourceInfo("")).GetSrc().c_str(), filter);
104         json->PutExtAttr("objectFit",
105             OBJECTFITVALUE[static_cast<int32_t>(propImageFit_.value_or(ImageFit::COVER))], filter);
106         json->PutExtAttr("verticalAlign",
107             VERTICALALIGNVALUE[static_cast<int32_t>(propVerticalAlign_.value_or(VerticalAlign::BOTTOM))], filter);
108         json->PutFixedAttr("src", src.c_str(), filter, FIXED_ATTR_SRC);
109         json->PutExtAttr("rawSrc", propImageSourceInfo_->GetSrc().c_str(), filter);
110         json->PutExtAttr("moduleName", propImageSourceInfo_->GetModuleName().c_str(), filter);
111         json->PutExtAttr("baselineOffset", GetBaselineOffsetValue(Dimension(0)).Value(), filter);
112         auto host = GetHost();
113         CHECK_NULL_VOID(host);
114         json->PutExtAttr("privacySensitive", host->IsPrivacySensitive(), filter);
115     }
116 
FromJson(const std::unique_ptr<JsonValue> & json)117     void FromJson(const std::unique_ptr<JsonValue>& json) override
118     {
119         static const std::unordered_map<std::string, ImageFit> uMap {
120             { "ImageFit.Fill", ImageFit::FILL },
121             { "ImageFit.Contain", ImageFit::CONTAIN },
122             { "ImageFit.Cover", ImageFit::COVER },
123             { "ImageFit.FitWidth", ImageFit::FITWIDTH },
124             { "ImageFit.FitHeight", ImageFit::FITHEIGHT },
125             { "ImageFit.None", ImageFit::NONE },
126             { "ImageFit.ScaleDown", ImageFit::SCALE_DOWN },
127             { "ImageFit.TOP_START", ImageFit::TOP_LEFT },
128             { "ImageFit.TOP", ImageFit::TOP },
129             { "ImageFit.TOP_END", ImageFit::TOP_END },
130             { "ImageFit.START", ImageFit::START },
131             { "ImageFit.CENTER", ImageFit::CENTER },
132             { "ImageFit.END", ImageFit::END },
133             { "ImageFit.BOTTOM_START", ImageFit::BOTTOM_START },
134             { "ImageFit.BOTTOM", ImageFit::BOTTOM },
135             { "ImageFit.BOTTOM_END", ImageFit::BOTTOM_END },
136         };
137 
138         std::string src = json->GetString("rawSrc");
139         std::string bundleName = AceApplicationInfo::GetInstance().GetPackageName();
140         std::string moduleName = json->GetString("moduleName");
141         UpdateImageSourceInfo(ImageSourceInfo(src, bundleName, moduleName));
142         auto objectFit = json->GetString("objectFit");
143         ImageFit imageFit = ImageFit::COVER;
144         auto iter = uMap.find(objectFit);
145         if (iter != uMap.end()) {
146             imageFit = iter->second;
147         }
148         UpdateImageFit(imageFit);
149         UpdateAutoResize(json->GetString("autoResize") == "true" ? true : false);
150         UpdateBaselineOffset(Dimension(json->GetDouble("baselineOffset")));
151         /* register image frame node to pipeline context to receive memory level notification and window state change
152          * notification */
153         auto frameNode = GetHost();
154         CHECK_NULL_VOID(frameNode);
155         auto pipeline = frameNode->GetContext();
156         CHECK_NULL_VOID(pipeline);
157         pipeline->AddNodesToNotifyMemoryLevel(frameNode->GetId());
158         pipeline->AddWindowStateChangedCallback(frameNode->GetId());
159         LayoutProperty::FromJson(json);
160     }
161 
162     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ImageFit, ImageFit, PROPERTY_UPDATE_LAYOUT);
163     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ImageSourceInfo, ImageSourceInfo, PROPERTY_UPDATE_NORMAL);
164     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Alt, ImageSourceInfo, PROPERTY_UPDATE_NORMAL);
165     ACE_DEFINE_PROPERTY_GROUP(ImageSizeStyle, ImageSizeStyle);
166     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ImageSizeStyle, AutoResize, bool, PROPERTY_UPDATE_LAYOUT);
167     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ImageSizeStyle, SourceSize, SizeF, PROPERTY_UPDATE_LAYOUT);
168     ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(ImageSizeStyle, FitOriginalSize, bool, PROPERTY_UPDATE_BY_CHILD_REQUEST);
169     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(VerticalAlign, VerticalAlign, PROPERTY_UPDATE_MEASURE);
170 
171     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(PlaceHolderStyle, TextBackgroundStyle, PROPERTY_UPDATE_NORMAL);
172     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(HasPlaceHolderStyle, bool, PROPERTY_UPDATE_NORMAL);
173     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(BaselineOffset, Dimension, PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
174     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ImageRotateOrientation, ImageRotateOrientation, PROPERTY_UPDATE_MEASURE);
175 
176 private:
177     ACE_DISALLOW_COPY_AND_MOVE(ImageLayoutProperty);
178 };
179 } // namespace OHOS::Ace::NG
180 
181 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_IMAGE_IMAGE_LAYOUT_PROPERTY_H
182