参数解析

Dimension MeasureStringToDimensionWithUnit(const std::string& value, bool& useDefaultUnit,
    DimensionUnit defaultUnit = DimensionUnit::PX, float defaultValue = 0.0f, bool isCalc = false)
{
    errno = 0;
    if (std::strcmp(value.c_str(), "auto") == 0) {
        return Dimension(defaultValue, DimensionUnit::AUTO);
    }
    char* pEnd = nullptr;
    double result = std::strtod(value.c_str(), &pEnd);
    if (pEnd == value.c_str() || errno == ERANGE) {
        useDefaultUnit = true;
        return Dimension(defaultValue, defaultUnit);
    }
    if (pEnd != nullptr) {
        if (std::strcmp(pEnd, "%") == 0) {
            // Parse percent, transfer from [0, 100] to [0, 1]
            return Dimension(result / 100.0, DimensionUnit::PERCENT);
        }
        if (std::strcmp(pEnd, "px") == 0) {
            return Dimension(result, DimensionUnit::PX);
        }
        if (std::strcmp(pEnd, "vp") == 0) {
            return Dimension(result, DimensionUnit::VP);
        }
        if (std::strcmp(pEnd, "fp") == 0) {
            return Dimension(result, DimensionUnit::FP);
        }
        if (std::strcmp(pEnd, "lpx") == 0) {
            return Dimension(result, DimensionUnit::LPX);
        }
        if ((std::strcmp(pEnd, "\0") == 0) && isCalc) {
            return Dimension(result, DimensionUnit::NONE);
        }
        if (isCalc) {
            return Dimension(result, DimensionUnit::INVALID);
        }
    }
    useDefaultUnit = true;
    return Dimension(result, defaultUnit);
}

这个 C++ 函数 MeasureStringToDimensionWithUnit 解析一个字符串 value,将其转换为 Dimension 结构体,并确定它的单位 (DimensionUnit)。

参数解析
const std::string& value

需要解析的字符串,例如 "50px"、"20%"、"auto"。
bool& useDefaultUnit

如果解析失败,则设为 true,表示需要使用默认单位。
DimensionUnit defaultUnit = DimensionUnit::PX

默认单位,默认为 PX(像素)。
float defaultValue = 0.0f

如果解析失败,返回该默认值。
bool isCalc = false

处理 calc() 计算表达式的情况。
代码逻辑分析

  1. 处理 "auto" 值
if (std::strcmp(value.c_str(), "auto") == 0) {
    return Dimension(defaultValue, DimensionUnit::AUTO);
}

如果 value 是 "auto",返回 Dimension(defaultValue, AUTO)。
2. 将字符串转换为 double 类型

char* pEnd = nullptr;
double result = std::strtod(value.c_str(), &pEnd);
  • std::strtod 用于将字符串转换为 double,pEnd 指向转换结束后的位置。
  • 如果转换失败或数值超出范围:
if (pEnd == value.c_str() || errno == ERANGE) {
    useDefaultUnit = true;
    return Dimension(defaultValue, defaultUnit);
}
  • 解析失败时,返回默认值和默认单位。
  1. 解析单位
    如果 pEnd 不为空,则检查它是否是合法的单位:
if (pEnd != nullptr) {
    if (std::strcmp(pEnd, "%") == 0) {
        return Dimension(result / 100.0, DimensionUnit::PERCENT);
    }
    if (std::strcmp(pEnd, "px") == 0) {
        return Dimension(result, DimensionUnit::PX);
    }
    if (std::strcmp(pEnd, "vp") == 0) {
        return Dimension(result, DimensionUnit::VP);
    }
    if (std::strcmp(pEnd, "fp") == 0) {
        return Dimension(result, DimensionUnit::FP);
    }
    if (std::strcmp(pEnd, "lpx") == 0) {
        return Dimension(result, DimensionUnit::LPX);
    }
  • 支持的单位:
    • % -> 百分比(会除以 100)
    • px -> 像素
    • vp -> 视口单位
    • fp -> 可扩展单位
    • lpx -> 逻辑像素单位
  1. 处理 calc() 计算模式
if ((std::strcmp(pEnd, "\0") == 0) && isCalc) {
    return Dimension(result, DimensionUnit::NONE);
}
if (isCalc) {
    return Dimension(result, DimensionUnit::INVALID);
}

如果 isCalc 为 true:

  • 且没有单位(pEnd 是空字符串 "\0"),则返回 NONE。
  • 其他情况返回 INVALID。
  1. 解析失败,使用默认单位
useDefaultUnit = true;
return Dimension(result, defaultUnit);

如果所有条件都不符合,返回默认单位。
总结

  • "auto" 特殊处理。
  • 解析数值部分,失败则返回默认值。
  • 检查后缀单位(%、px、vp、fp、lpx)。
  • calc() 模式特殊处理。
  • 默认返回 defaultUnit(解析失败时)。
bool SetButtonDimension(
    const ArkUI_Float32* dimensionArray,  // 尺寸数据数组
    uint32_t offset,                      // 数组中的偏移量
    const size_t dataCount,                // 数组的总大小
    std::optional<CalcDimension>& optDimension // 输出:解析后的尺寸
)
dimensionArray:存储尺寸值的浮点型数组。
offset:当前 dimension 数据块的起始索引。
dataCount:数组的总大小(用于边界检查)。
optDimension:输出参数,存储解析出的 CalcDimension,如果解析失败则为空。
dimensionArray = { 1, 50.0, 2,  0, 0, 0,  1, 25.0, 1 }
                   └─┬──┘  └──┬┘  └──────────┬──────┘
                    标志    数值        单位

offset + 0:是否有值(1 表示有,0 表示无)。
offset + 1:尺寸的实际数值(50.0)。
offset + 2:尺寸单位(2 可能表示 PX)。

posted @ 2025-03-03 23:54  爱新觉罗LQ  阅读(23)  评论(0)    收藏  举报