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 #include "printer_capability_helper.h"
16 #include "napi_print_utils.h"
17 #include "print_constant.h"
18 #include "print_log.h"
19 #include "print_margin_helper.h"
20 #include "print_page_size_helper.h"
21 #include "print_resolution_helper.h"
22
23 namespace OHOS::Print {
24 static constexpr const char *PARAM_CAPABILITY_COLORMODE = "colorMode";
25 static constexpr const char *PARAM_CAPABILITY_DUPLEXMODE = "duplexMode";
26 static constexpr const char *PARAM_CAPABILITY_PAGESIZE = "pageSize";
27 static constexpr const char *PARAM_CAPABILITY_RESOLUTION = "resolution";
28 static constexpr const char *PARAM_CAPABILITY_MINMARGIN = "minMargin";
29 static constexpr const char *PARAM_CAPABILITY_OPTION = "option";
30
MakeJsObject(napi_env env,const PrinterCapability & cap)31 napi_value PrinterCapabilityHelper::MakeJsObject(napi_env env, const PrinterCapability &cap)
32 {
33 napi_value jsObj = nullptr;
34 PRINT_CALL(env, napi_create_object(env, &jsObj));
35
36 NapiPrintUtils::SetUint32Property(env, jsObj, PARAM_CAPABILITY_COLORMODE, cap.GetColorMode());
37 NapiPrintUtils::SetUint32Property(env, jsObj, PARAM_CAPABILITY_DUPLEXMODE, cap.GetDuplexMode());
38
39 CreatePageSizeList(env, jsObj, cap);
40 if (cap.HasResolution()) {
41 CreateResolutionList(env, jsObj, cap);
42 }
43
44 if (cap.HasMargin()) {
45 PrintMargin margin;
46 cap.GetMinMargin(margin);
47 napi_value jsMargin = PrintMarginHelper::MakeJsObject(env, margin);
48 PRINT_CALL(env, napi_set_named_property(env, jsObj, PARAM_CAPABILITY_MINMARGIN, jsMargin));
49 }
50 if (cap.HasOption()) {
51 NapiPrintUtils::SetStringPropertyUtf8(env, jsObj, PARAM_CAPABILITY_OPTION, cap.GetOption());
52 }
53 return jsObj;
54 }
55
BuildFromJs(napi_env env,napi_value jsValue)56 std::shared_ptr<PrinterCapability> PrinterCapabilityHelper::BuildFromJs(napi_env env, napi_value jsValue)
57 {
58 auto nativeObj = std::make_shared<PrinterCapability>();
59 if (nativeObj == nullptr) {
60 PRINT_HILOGE("Failed to create printer capability object");
61 return nullptr;
62 }
63
64 if (!ValidateProperty(env, jsValue)) {
65 PRINT_HILOGE("Invalid property of printer capability");
66 return nullptr;
67 }
68
69 uint32_t colorMode = NapiPrintUtils::GetUint32Property(env, jsValue, PARAM_CAPABILITY_COLORMODE);
70 uint32_t duplexMode = NapiPrintUtils::GetUint32Property(env, jsValue, PARAM_CAPABILITY_DUPLEXMODE);
71 nativeObj->SetColorMode(colorMode);
72 nativeObj->SetDuplexMode(duplexMode);
73
74 napi_value jsPageSizes = NapiPrintUtils::GetNamedProperty(env, jsValue, PARAM_CAPABILITY_PAGESIZE);
75 bool isArray = false;
76 napi_is_array(env, jsPageSizes, &isArray);
77 if (!isArray) {
78 PRINT_HILOGE("Invalid list of page size");
79 return nullptr;
80 }
81
82 std::vector<PrintPageSize> pageSizes;
83 uint32_t arrayLength = 0;
84 napi_get_array_length(env, jsPageSizes, &arrayLength);
85 for (uint32_t index = 0; index < arrayLength; index++) {
86 napi_value jsPageSize;
87 napi_get_element(env, jsPageSizes, index, &jsPageSize);
88 auto pageSizePtr = PrintPageSizeHelper::BuildFromJs(env, jsPageSize);
89 if (pageSizePtr == nullptr) {
90 PRINT_HILOGE("Failed to build printer capability object from js");
91 return nullptr;
92 }
93 pageSizes.emplace_back(*pageSizePtr);
94 }
95 nativeObj->SetPageSize(pageSizes);
96 auto jsOption = NapiPrintUtils::GetNamedProperty(env, jsValue, PARAM_CAPABILITY_OPTION);
97 if (jsOption != nullptr) {
98 nativeObj->SetOption(NapiPrintUtils::GetStringPropertyUtf8(env, jsValue, PARAM_CAPABILITY_OPTION));
99 }
100 PRINT_HILOGE("Build Print Capability succeed");
101 return BuildFromJsSecond(env, jsValue, jsPageSizes, nativeObj);
102 }
103
BuildFromJsSecond(napi_env env,napi_value jsValue,napi_value jsPageSizes,std::shared_ptr<PrinterCapability> nativeObj)104 std::shared_ptr<PrinterCapability> PrinterCapabilityHelper::BuildFromJsSecond(napi_env env, napi_value jsValue,
105 napi_value jsPageSizes, std::shared_ptr<PrinterCapability> nativeObj)
106 {
107 napi_value jsResolutionList = NapiPrintUtils::GetNamedProperty(env, jsValue, PARAM_CAPABILITY_RESOLUTION);
108 if (jsResolutionList != nullptr) {
109 bool isArray = false;
110 napi_is_array(env, jsResolutionList, &isArray);
111 if (!isArray) {
112 PRINT_HILOGE("Invalid list of print resolution");
113 return nullptr;
114 }
115 std::vector<PrintResolution> resolutionList;
116 uint32_t arrayLength = 0;
117 napi_get_array_length(env, jsPageSizes, &arrayLength);
118 for (uint32_t index = 0; index < arrayLength; index++) {
119 napi_value jsResolution;
120 napi_get_element(env, jsResolutionList, index, &jsResolution);
121 auto resolutionPtr = PrintResolutionHelper::BuildFromJs(env, jsResolution);
122 if (resolutionPtr == nullptr) {
123 PRINT_HILOGE("Failed to build printer capability object from js");
124 return nullptr;
125 }
126 resolutionList.emplace_back(*resolutionPtr);
127 }
128 nativeObj->SetResolution(resolutionList);
129 }
130
131 napi_value jsMargin = NapiPrintUtils::GetNamedProperty(env, jsValue, PARAM_CAPABILITY_MINMARGIN);
132 if (jsMargin != nullptr) {
133 auto marginPtr = PrintMarginHelper::BuildFromJs(env, jsMargin);
134 if (marginPtr == nullptr) {
135 PRINT_HILOGE("Failed to build printer capability object from js");
136 return nullptr;
137 }
138 nativeObj->SetMinMargin(*marginPtr);
139 }
140 return nativeObj;
141 }
142
CreatePageSizeList(napi_env env,napi_value & jsPrinterCap,const PrinterCapability & cap)143 bool PrinterCapabilityHelper::CreatePageSizeList(napi_env env, napi_value &jsPrinterCap, const PrinterCapability &cap)
144 {
145 napi_value jsPageSizes = nullptr;
146 PRINT_CALL_BASE(env, napi_create_array(env, &jsPageSizes), false);
147 std::vector<PrintPageSize> pageSizeList;
148 cap.GetPageSize(pageSizeList);
149 uint32_t arrLength = pageSizeList.size();
150
151 for (uint32_t index = 0; index < arrLength; index++) {
152 napi_value value = PrintPageSizeHelper::MakeJsObject(env, pageSizeList[index]);
153 PRINT_CALL_BASE(env, napi_set_element(env, jsPageSizes, index, value), false);
154 }
155 PRINT_CALL_BASE(env, napi_set_named_property(env, jsPrinterCap, PARAM_CAPABILITY_PAGESIZE, jsPageSizes), false);
156 return true;
157 }
158
CreateResolutionList(napi_env env,napi_value & jsPrinterCap,const PrinterCapability & cap)159 bool PrinterCapabilityHelper::CreateResolutionList(napi_env env, napi_value &jsPrinterCap, const PrinterCapability &cap)
160 {
161 napi_value jsResolutionList = nullptr;
162 PRINT_CALL_BASE(env, napi_create_array(env, &jsResolutionList), false);
163 std::vector<PrintResolution> resolutionList;
164 uint32_t arrLength = resolutionList.size();
165
166 for (uint32_t index = 0; index < arrLength; index++) {
167 napi_value value = PrintResolutionHelper::MakeJsObject(env, resolutionList[index]);
168 PRINT_CALL_BASE(env, napi_set_element(env, jsResolutionList, index, value), false);
169 }
170 PRINT_CALL_BASE(env,
171 napi_set_named_property(env, jsPrinterCap, PARAM_CAPABILITY_RESOLUTION, jsResolutionList), false);
172 return true;
173 }
174
ValidateProperty(napi_env env,napi_value object)175 bool PrinterCapabilityHelper::ValidateProperty(napi_env env, napi_value object)
176 {
177 std::map<std::string, PrintParamStatus> propertyList = {
178 {PARAM_CAPABILITY_COLORMODE, PRINT_PARAM_NOT_SET},
179 {PARAM_CAPABILITY_DUPLEXMODE, PRINT_PARAM_NOT_SET},
180 {PARAM_CAPABILITY_PAGESIZE, PRINT_PARAM_NOT_SET},
181 {PARAM_CAPABILITY_RESOLUTION, PRINT_PARAM_OPT},
182 {PARAM_CAPABILITY_MINMARGIN, PRINT_PARAM_OPT},
183 {PARAM_CAPABILITY_OPTION, PRINT_PARAM_OPT},
184 };
185
186 auto names = NapiPrintUtils::GetPropertyNames(env, object);
187 for (auto name : names) {
188 if (propertyList.find(name) == propertyList.end()) {
189 PRINT_HILOGE("Invalid property: %{public}s", name.c_str());
190 return false;
191 }
192 propertyList[name] = PRINT_PARAM_SET;
193 }
194
195 for (auto propertypItem : propertyList) {
196 if (propertypItem.second == PRINT_PARAM_NOT_SET) {
197 PRINT_HILOGE("Missing Property: %{public}s", propertypItem.first.c_str());
198 return false;
199 }
200 }
201 return true;
202 }
203 } // namespace OHOS::Print
204