• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "adapter/ohos/osal/resource_theme_style.h"
17 
18 #include <set>
19 
20 namespace OHOS::Ace {
21 namespace {
22 constexpr char COLOR_VALUE_PREFIX[] = "$color:";
23 constexpr char MEDIA_VALUE_PREFIX[] = "/";
24 constexpr char REF_ATTR_VALUE_KEY_WORD[] = "?theme:";
25 
26 constexpr char RES_TAG[] = "resource:///";
27 // resource manager hap for system resource
28 constexpr char RES_HAP_PREFIX[] = "ohos.global.systemres";
29 #ifdef PREVIEW
30 constexpr char RES_PATH_TAG[] = "file://";
31 // resource manager hap absolute path, as resource manager api don't return
32 constexpr char RES_HAP_PATH[] = "../resources/";
33 #else
34 constexpr char RES_PATH_TAG[] = "file:///";
35 // resource manager hap absolute path, as resource manager api don't return
36 constexpr char RES_HAP_PATH[] = "/data/storage/el1/bundle/ohos.global.systemres/ohos.global.systemres/assets/";
37 #endif
38 
39 static const std::set<std::string> stringAttrs = {
40     "attribute_text_font_family_regular",
41     "attribute_text_font_family_medium",
42     "description_current_location",
43     "description_add_location",
44     "description_select_location",
45     "description_share_location",
46     "description_send_location",
47     "description_locating",
48     "description_location",
49     "description_send_current_location",
50     "description_relocation",
51     "description_punch_in",
52     "description_current_position",
53     "description_paste",
54     "description_download",
55     "description_download_file",
56     "description_save",
57     "description_save_image",
58     "description_save_file",
59     "description_download_and_share",
60     "description_receive",
61     "description_continue_to_receive",
62     "draggable",
63     "divider_shadow_enable",
64     "camera_input",
65     "menu_bg_blur_effect_enable",
66     "menu_double_border_enable",
67     "section_unfocus_effect_enable",
68     "section_unfocus_color",
69     "sheet_type",
70     "multiple_dialog_display",
71     "menu_expand_display",
72     "popup_double_border_enable",
73     "popup_outer_border_color",
74     "popup_inner_border_color",
75     "dialog_expand_display"
76 };
77 
ParseDoubleUnit(const std::string & value,std::string & unit)78 double ParseDoubleUnit(const std::string& value, std::string& unit)
79 {
80     for (size_t i = 0; i < value.length(); i++) {
81         if (i == 0 && (value[i] == '-' || value[i] == '+')) {
82             continue;
83         }
84         if (value[i] != '.' && (value[i] < '0' || value[i] > '9')) {
85             unit = value.substr(i);
86             return std::atof(value.substr(0, i).c_str());
87         }
88     }
89     return std::atof(value.c_str());
90 }
91 
ParseDimensionUnit(const std::string & unit)92 DimensionUnit ParseDimensionUnit(const std::string& unit)
93 {
94     if (unit == "px") {
95         return DimensionUnit::PX;
96     } else if (unit == "fp") {
97         return DimensionUnit::FP;
98     } else if (unit == "lpx") {
99         return DimensionUnit::LPX;
100     } else if (unit == "%") {
101         return DimensionUnit::PERCENT;
102     } else {
103         return DimensionUnit::VP;
104     }
105 }
106 }
107 
ParseContent()108 void ResourceThemeStyle::ParseContent()
109 {
110     for (auto& [attrName, attrValue] : rawAttrs_) {
111         if (attrName.empty() || attrValue.empty()) {
112             continue;
113         }
114         if (attrValue.front() == '#' || attrValue.find(COLOR_VALUE_PREFIX) != std::string::npos) {
115             // color
116             attributes_[attrName] = { .type = ThemeConstantsType::COLOR, .value = Color::FromString(attrValue) };
117         } else if (attrValue.find(MEDIA_VALUE_PREFIX) != std::string::npos) {
118             OnParseResourceMedia(attrName, attrValue);
119         } else if (stringAttrs.find(attrName) != stringAttrs.end()) {
120             // string
121             attributes_[attrName] = { .type = ThemeConstantsType::STRING, .value = attrValue };
122         } else if (attrValue.find(REF_ATTR_VALUE_KEY_WORD) != std::string::npos) {
123             attributes_[attrName] = { .type = ThemeConstantsType::REFERENCE_ATTR, .value = attrValue };
124         } else {
125             // double & dimension
126             std::string unit = "";
127             auto doubleValue = ParseDoubleUnit(attrValue, unit);
128             if (unit.empty()) {
129                 attributes_[attrName] = { .type = ThemeConstantsType::DOUBLE, .value = doubleValue };
130             } else {
131                 attributes_[attrName] = { .type = ThemeConstantsType::DIMENSION,
132                     .value = Dimension(doubleValue, ParseDimensionUnit(unit)) };
133             }
134         }
135     }
136     OnParseStyle();
137 }
138 
OnParseStyle()139 void ResourceThemeStyle::OnParseStyle()
140 {
141     for (auto& [patternName, patternMap]: patternAttrs_) {
142         auto patternStyle = AceType::MakeRefPtr<ResourceThemeStyle>(resAdapter_);
143         patternStyle->SetName(patternName);
144         patternStyle->parentStyle_ = AceType::WeakClaim(this);
145         patternStyle->rawAttrs_ = patternMap;
146         patternStyle->ParseContent();
147         attributes_[patternName] = { .type = ThemeConstantsType::PATTERN,
148             .value = RefPtr<ThemeStyle>(std::move(patternStyle)) };
149     }
150 }
151 
OnParseResourceMedia(const std::string & attrName,const std::string & attrValue)152 void ResourceThemeStyle::OnParseResourceMedia(const std::string& attrName, const std::string& attrValue)
153 {
154     std::string mediaPath;
155     if (SystemProperties::GetUnZipHap()) {
156         mediaPath = RES_PATH_TAG;
157         if (attrValue.find(RES_HAP_PREFIX) == std::string::npos) {
158             mediaPath.append(RES_HAP_PATH);
159         }
160         mediaPath += attrValue;
161     } else {
162         // hap is not unzip, should use resource name to read file
163         auto pos = attrValue.find_last_of(MEDIA_VALUE_PREFIX);
164         if (pos == std::string::npos) {
165             LOGW("resource media invalid:[%{public}s, %{public}s]", attrName.c_str(), attrValue.c_str());
166             return;
167         }
168         mediaPath = std::string(RES_TAG) + attrValue.substr(pos + 1);
169     }
170     attributes_[attrName] = { .type = ThemeConstantsType::STRING, .value = mediaPath };
171 }
172 } // namespace OHOS::Ace
173