C++字体库开发之freetype vs harfbuzz sfnt表,字体名称,可变轴八

freetype
sfnt表
    FT_ULong tableCount = 0;
    FT_Error error;

    // When 'tag' is nullptr, returns number of tables in 'length'.
    error = FT_Sfnt_Table_Info(face, 0, nullptr, &tableCount);
    if (error)
        return false;

    for (FT_ULong tableIndex = 0; tableIndex < tableCount; ++tableIndex) {
        FT_ULong tableTag;
        FT_ULong tableLength;
        error = FT_Sfnt_Table_Info(face, tableIndex, &tableTag, &tableLength);
        if (error)
            return false;
        FontInfo::Table table{(uint32_t)tableTag, (uint32_t)tableLength};
        m_fontInfo.tables.emplace_back(table);
    }
字体名称
    const FT_UInt numNames = FT_Get_Sfnt_Name_Count(face);
    FT_SfntName   sfntName;
    for (FT_UInt i = 0; i < numNames; ++i) {
        if (FT_Get_Sfnt_Name(face, i, &sfntName))
            continue;

        auto name = sfntNameTranscodeUnicode(sfntName);
        if (name.empty())
            continue;
        if (sfntName.name_id > TT_NAME_ID_VARIATIONS_PREFIX)
            continue;
        FontInfo::Encode encoding{sfntName.language_id, sfntName.platform_id, sfntName.encoding_id};
        FontInfo::Name   nameStu{name, encoding};
        m_fontInfo.nameTables.at(sfntName.name_id).emplace_back(nameStu);
    }
可变轴
    FT_CharMap   *charMap = face->charmaps;
    std::set<int> encodingSet;

    for (int i = 0; i < face->num_charmaps; i++) {
        auto cur = charMap[i];
        if (encodingSet.count(cur->encoding))
            continue;
        encodingSet.insert(cur->encoding);
        FT_Select_Charmap(face, cur->encoding);
        unsigned short langID = FT_Get_CMap_Language_ID(cur);  // 0 - 表示失败,可用作默认

        auto             weight     = getWeight();
        auto             width      = getWidth();
        auto             slant      = getSlant();
        auto             variations = getSupportVariations();
        FontInfo::Encode anEncode{langID, cur->platform_id, cur->encoding_id};
        FontInfo::Axes   axes{weight, width, slant, variations, anEncode};
        m_fontInfo.axes.emplace_back(axes);
    }
harfbuzz
sfnt表
    // 文件中的所有表标签
    unsigned int num_tags = 0;
    hb_blob_t   *blob;

    // 获取表标签的数量
    num_tags = hb_face_get_table_tags(m_face, NULL, &num_tags, nullptr);
    if (0 == num_tags)
        return false;
    hb_tag_t *tags = new hb_tag_t[num_tags];
    hb_face_get_table_tags(m_face, NULL, &num_tags, tags);
    //    // 打印所有表标签
    //    char buf[5] = {
    //        0,
    //    };
    for (unsigned int i = 0; i < num_tags; i++) {
        blob = hb_face_reference_table(m_face, tags[i]);
        // 获取表的长度
        auto tabLen = hb_blob_get_length(blob);
        //        hb_tag_to_string(tags[i], buf);
        FontInfo::Table table{(uint32_t)tags[i], (uint32_t)tabLen};
        m_fontInfo.tables.emplace_back(table);
    }
    delete[] tags;
字体名称
    const auto                             &allLanguages = FontLanguage::getAllLanguages();
    std::map<unsigned short, hb_language_t> languages;
    for (const auto &lang : allLanguages) {
        languages.emplace(lang.first, hb_language_from_string(lang.second.code.c_str(), lang.second.code.size()));
    }

    char buf[1024] = {
        0,
    };
    for (int i = HB_OT_NAME_ID_COPYRIGHT; i <= HB_OT_NAME_ID_VARIATIONS_PS_PREFIX; ++i) {
        for (const auto &lang : languages) {
            unsigned int size = 1024;
            if (hb_ot_name_get_utf8(m_face, i, lang.second, &size, buf) > 0) {
                FontInfo::Encode encoding{lang.first, 2, 0};
                FontInfo::Name   nameStu{buf, encoding};
                m_fontInfo.nameTables.at(i).emplace_back(nameStu);
            }
        }
    }
可变轴
   auto         font = hb_font_create(m_face);
    unsigned int length;
    const int   *coords = hb_font_get_var_coords_normalized(font, &length);
    if (!coords)
        return;
    auto denorm_coord = [](hb_ot_var_axis_info_t *axis, int coord) -> float {
        float r = coord / 16384.0;
        if (coord < 0)
            return axis->default_value + r * (axis->default_value - axis->min_value);
        else
            return axis->default_value + r * (axis->max_value - axis->default_value);
    };
    unsigned int           n_axes;
    hb_ot_var_axis_info_t *axes = new hb_ot_var_axis_info_t[length];
    FONTVIEW_CLASS(ShareData<hb_ot_var_axis_info_t>) axisInfo(axes, length);
    n_axes = length;
    hb_ot_var_get_axis_infos(m_face, 0, &n_axes, axes);

    auto weight = getWeight();
    auto width  = getWidth();
    auto slant  = getSlant();

    FontInfo::Encode anEncode{2057, 2, 0};
    for (unsigned int i = 0; i < length; ++i) {
        char         name[20];
        unsigned int namelen = 20;

        hb_ot_name_get_utf8(m_face, axes[i].name_id, hb_language_from_string("en", 2), &namelen, name);
        FontVariation fontVariation(FontVariation::toUInt32((const char *)name));
        fontVariation.cur = denorm_coord(&axes[i], coords[i]);
        fontVariation.min = axes[i].min_value;
        fontVariation.max = axes[i].max_value;
        fontVariation.def = axes[i].default_value;
        //        printf("    %s: %g (%g - %g, %g)\n",
        //               name,
        //               denorm_coord(&axes[i], coords[i]),
        //               axes[i].min_value,
        //               axes[i].max_value,
        //               axes[i].default_value);

        FontInfo::Axes axes{(size_t)weight, width, slant, {std::move(fontVariation)}, anEncode};
        m_fontInfo.axes.emplace_back(axes);
    }
    hb_font_destroy(font);
参考

C++字体库开发之字体列表设计七-CSDN博客 


创作不易,小小的支持一下吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码力码力我爱你

创作不易,小小的支持一下吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值