1  /*
2   * Copyright (c) 2021-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  #include "frameworks/bridge/common/dom/dom_image.h"
17  
18  namespace OHOS::Ace::Framework {
19  namespace {
20  
21  const char SVG_THEME_FILL[] = "theme_fill";
22  
ConvertStrToFit(const std::string & fit)23  ImageFit ConvertStrToFit(const std::string& fit)
24  {
25      static const LinearMapNode<ImageFit> imageFitMap[] = {
26          { "contain", ImageFit::CONTAIN },
27          { "cover", ImageFit::COVER },
28          { "fill", ImageFit::FILL },
29          { "none", ImageFit::NONE },
30          { "scale-down", ImageFit::SCALE_DOWN },
31      };
32      ImageFit imageFit = ImageFit::COVER;
33      auto iter = BinarySearchFindIndex(imageFitMap, ArraySize(imageFitMap), fit.c_str());
34      if (iter != -1) {
35          imageFit = imageFitMap[iter].value;
36      }
37      return imageFit;
38  }
39  
40  } // namespace
41  
ImageObjectPosition(const std::string & value)42  ImageObjectPosition ImageObjectPosition(const std::string& value)
43  {
44      return ParseImageObjectPosition(value.c_str());
45  }
46  
InitializeStyle()47  void DOMImage::InitializeStyle()
48  {
49      theme_ = GetTheme<ImageTheme>();
50  }
51  
DOMImage(NodeId nodeId,const std::string & nodeName)52  DOMImage::DOMImage(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
53  {
54      imageChild_ = AceType::MakeRefPtr<ImageComponent>();
55      imageChild_->SetFitMaxSize(true);
56  }
57  
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)58  bool DOMImage::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
59  {
60      if (attr.first == DOM_SRC) {
61          imageChild_->SetSrc(ParseImageSrc(attr.second));
62          return true;
63      }
64      if (attr.first == DOM_IMAGE_SYNC_LOAD) {
65          imageChild_->SetSyncMode(StringToBool(attr.second));
66          return true;
67      }
68      if (attr.first == DOM_IMAGE_ALT) {
69          imageChild_->SetAlt(ParseImageSrc(attr.second));
70          return true;
71      }
72      return false;
73  }
74  
SetSpecializedStyle(const std::pair<std::string,std::string> & style)75  bool DOMImage::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
76  {
77      // static linear map must be sorted by key.
78      static const LinearMapNode<void (*)(const std::string&, DOMImage&)> imageStylesOperators[] = {
79          { DOM_IMAGE_FILL_COLOR,
80              [](const std::string& val, DOMImage& image) {
81                  if (val == SVG_THEME_FILL && image.theme_) {
82                      image.imageChild_->SetColor(image.theme_->GetFillColor());
83                  }
84              } },
85          { DOM_IMAGE_FIT_ORIGINAL_SIZE,
86              [](const std::string& val, DOMImage& image) { image.imageChild_->SetFitMaxSize(!StringToBool(val)); } },
87          { DOM_IMAGE_MATCH_TEXT_DIRECTION,
88              [](const std::string& val, DOMImage& image) {
89                  image.imageChild_->SetMatchTextDirection(StringToBool(val));
90              } },
91          { DOM_IMAGE_FIT, [](const std::string& val,
92                           DOMImage& image) { image.imageChild_->SetImageFit(ConvertStrToFit(val.c_str())); } },
93          { DOM_IMAGE_POSITION, [](const std::string& val, DOMImage& image) {
94              image.imageChild_->SetImageObjectPosition(ImageObjectPosition(val.c_str())); } },
95      };
96      auto operatorIter =
97          BinarySearchFindIndex(imageStylesOperators, ArraySize(imageStylesOperators), style.first.c_str());
98      if (operatorIter != -1) {
99          imageStylesOperators[operatorIter].value(style.second, *this);
100          return true;
101      }
102      return false;
103  }
104  
AddSpecializedEvent(int32_t pageId,const std::string & event)105  bool DOMImage::AddSpecializedEvent(int32_t pageId, const std::string& event)
106  {
107      if (event == DOM_COMPLETE) {
108          loadSuccessEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
109          imageChild_->SetLoadSuccessEvent(loadSuccessEvent_);
110      } else if (event == DOM_ERROR) {
111          loadFailEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
112          imageChild_->SetLoadFailEvent(loadFailEvent_);
113      } else {
114          return false;
115      }
116      return true;
117  }
118  
PrepareSpecializedComponent()119  void DOMImage::PrepareSpecializedComponent()
120  {
121      imageChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
122      // If there is a corresponding box decoration, specialize the box.
123      if (boxComponent_) {
124          auto backDecoration = boxComponent_->GetBackDecoration();
125          if (backDecoration) {
126              imageChild_->SetBorder(backDecoration->GetBorder());
127          }
128      }
129      if (flexItemComponent_ && !imageChild_->GetFitMaxSize()) {
130          flexItemComponent_->SetStretchFlag(false);
131      }
132  
133      imageChild_->SetImageFill(GetImageFill());
134  }
135  
136  } // namespace OHOS::Ace::Framework
137