* Copyright (c) 2025 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 OHOS_ANI_ACE_SHAPE_UTIL_H
#define OHOS_ANI_ACE_SHAPE_UTIL_H
#include <ani.h>
#include <array>
#include <cmath>
#include <iostream>
#include <regex>
#include <string>
#include <vector>
#include "core/common/container.h"
#include "core/common/resource/resource_manager.h"
#include "core/components/theme/resource_adapter.h"
#include "core/components/common/properties/color.h"
#include "core/components/theme/shadow_theme.h"
#include "base/geometry/shape.h"
#include "frameworks/base/log/log_wrapper.h"
enum RADIUS { TOP_LEFT_RADIUS = 0, TOP_RIGHT_RADIUS = 1, BOTTOM_RIGHT_RADIUS = 2, BOTTOM_LEFT_RADIUS = 3 };
enum ResColor {
RES_COLOR_WHITE,
RES_COLOR_BLACK,
RES_COLOR_BLUE,
RES_COLOR_BROWN,
RES_COLOR_GRAY,
RES_COLOR_GREEN,
RES_COLOR_GREY,
RES_COLOR_ORANGE,
RES_COLOR_PINK,
RES_COLOR_RED,
RES_COLOR_YELLOW,
RES_COLOR_TRANSPARENT
};
enum class ResourceType : uint32_t {
COLOR = 10001,
FLOAT,
STRING,
PLURAL,
BOOLEAN,
INTARRAY,
INTEGER,
PATTERN,
STRARRAY,
MEDIA = 20000,
RAWFILE = 30000
};
struct ResourceInfo {
int32_t resId = 0;
int32_t type = 0;
std::vector<std::string> params;
std::optional<std::string> bundleName = std::nullopt;
std::optional<std::string> moduleName = std::nullopt;
};
enum class ResourceStruct { CONSTANT, DYNAMIC_V1, DYNAMIC_V2 };
const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
constexpr int32_t UNKNOWN_RESOURCE_ID = -1;
const std::vector<std::string> RESOURCE_HEADS = { "app", "sys" };
const int32_t NUMBER_ZERO = 0;
const int32_t NUMBER_ONE = 1;
const int32_t NUMBER_TWO = 2;
const int32_t NUMBER_THREE = 3;
bool GetIsStringObject(ani_env* env, ani_ref object_ref);
bool GetIsNumberObject(ani_env* env, ani_ref object_ref);
bool GetIsUndefinedObject(ani_env* env, ani_ref object_ref);
bool GetIsResourceObject(ani_env* env, ani_ref object_ref);
bool GetIsArrayObject(ani_env* env, ani_ref object_ref);
ResourceStruct CheckResourceStruct(ani_env* env, ani_object value);
bool ParseResourceParamId(ani_env* env, ani_object objects, ResourceInfo& info);
bool ParseResourceParamBundleName(ani_env* env, ani_object objects, ResourceInfo& info);
bool ParseResourceParamModuleName(ani_env* env, ani_object objects, ResourceInfo& info);
bool ParseResourceParamType(ani_env* env, ani_object objects, ResourceInfo& info);
bool ParseResourceParamName(ani_env* env, ani_object objects, ResourceInfo& info);
bool ParseResourceParam(ani_env* env, ani_object options, ResourceInfo& info);
bool ParseStringNumberUndefinedOption(ani_env* env, ani_object options,
std::optional<OHOS::Ace::CalcDimension>& result, const char* property, const char* className);
bool IsInstanceOfCls(ani_env* env, [[maybe_unused]] ani_object object, const char* className);
bool ParseLengthToDimension(
ani_env* env, ani_ref source_ref, OHOS::Ace::DimensionUnit defaultUnit, OHOS::Ace::CalcDimension& result);
bool ParseLength(ani_env* env, [[maybe_unused]] ani_object object, [[maybe_unused]] ani_ref aniOption,
OHOS::Ace::CalcDimension& lengthInput);
void PreFixEmptyBundleName(ani_env* env, ani_object value);
void processResourceType(ani_env* env, ani_object value, ani_ref params_ref, size_t length);
void ModifyResourceParam(ani_env* env, ani_object value, const ResourceType& resType, const std::string& resName);
void CompleteResourceParamV1(ani_env* env, ani_object value);
void CompleteResourceParamV2(ani_env* env, ani_object value);
bool ParseDollarResource(
ani_env* env, ani_object params_ref, ResourceType& resType, std::string& resName, std::string& moduleName);
bool ConvertResourceType(const std::string& typeName, ResourceType& resType);
ResourceStruct CheckResourceStruct(ani_env* env, ani_object value);
std::string ANIUtils_ANIStringToStdString(ani_env* env, ani_string ani_str);
void ReplaceHolder(std::string& originStr, const std::vector<std::string>& params, uint32_t containCount);
bool ParseString(const ResourceInfo& info, std::string& result);
OHOS::Ace::RefPtr<OHOS::Ace::ResourceAdapter> CreateResourceAdapter(const ResourceInfo& info);
std::string DimensionToString(OHOS::Ace::Dimension dimension);
void ModifyResourceParam(ani_env* env, ani_object value, const ResourceType& resType, const std::string& resName);
void processResourceType(ani_env* env, ani_object value, ani_ref params_ref, size_t length, std::string resName);
bool ParseAniColor(ani_env* env, ani_ref resourceColor_ref, OHOS::Ace::Color& resourceColor);
bool ParseResourceColor(ani_env* env, ani_ref resourceColor_ref, OHOS::Ace::Color& resourceColor);
bool ParseColorMapToColor(ResColor colorenum, OHOS::Ace::Color& Color);
bool GetIsColorEnum(ani_env* env, ani_ref object_ref);
bool ParseOption(
ani_env* env, ani_object options, OHOS::Ace::CalcDimension& input, const char* property, const char* className);
std::string ParseCommands(ani_env* env, ani_object aniOption);
void ParseArray([[maybe_unused]] ani_env* env,
const OHOS::Ace::RefPtr<OHOS::Ace::ShapeRect>& shapeRect, ani_object options);
void SetRadiusValue(const OHOS::Ace::RefPtr<OHOS::Ace::ShapeRect>& shapeRect,
const OHOS::Ace::CalcDimension& radius, int32_t index);
bool ParseStringNumberUndefinedObject(ani_env* env, ani_ref property_ref, OHOS::Ace::DimensionUnit defaultUnit,
std::optional<OHOS::Ace::CalcDimension>& result);
template <typename T>
ani_object ANIShapeFromPtr(ani_env* env, ani_long ptr, const char* className, const char* propertyName)
{
ani_status status;
ani_method ctor = nullptr;
ani_class myClass;
if ((status = env->FindClass(className, &myClass)) != ANI_OK) {
LOGW("ANIShapeFromPtr find class error, status:%{public}d", status);
return nullptr;
}
if ((status = env->Class_FindMethod(myClass, "<ctor>", ":", &ctor)) != ANI_OK) {
LOGW("ANIShapeFromPtr find constructor error, status:%{public}d", status);
return nullptr;
}
ani_object result;
if ((status = env->Object_New(myClass, ctor, &result)) != ANI_OK) {
LOGW("ANIShapeFromPtr Object_New error, status:%{public}d", status);
return nullptr;
}
ani_long addr = 0L;
if ((status = env->Object_GetPropertyByName_Long(result, propertyName, &addr)) != ANI_OK) {
LOGW("ANIShapeFromPtr getProperty error, status:%{public}d", status);
return nullptr;
}
auto peer = reinterpret_cast<T*>(addr);
delete peer;
if ((status = env->Object_SetPropertyByName_Long(result, propertyName, reinterpret_cast<ani_long>(ptr))) !=
ANI_OK) {
LOGW("ANIShapeFromPtr setProperty error, status:%{public}d", status);
return nullptr;
}
return result;
}
#endif