政务网站信息化建设情况,正规网站建设定制,一个网站域名ip,电子商务平台内的自然人经营者hb-blob#xff1a; HarfBuzz Manual
harfbuzz 的用法
HarfBuzz 整形 API 的核心是函数。此函数采用一种字体#xff0c;即 包含一串 Unicode 代码点的缓冲区和 #xff08;可选#xff09;字体功能列表作为其输入。它取代了 缓冲区中的代码点#xff0c;其中包含来自 字…hb-blob HarfBuzz Manual
harfbuzz 的用法
HarfBuzz 整形 API 的核心是函数。此函数采用一种字体即 包含一串 Unicode 代码点的缓冲区和 可选字体功能列表作为其输入。它取代了 缓冲区中的代码点其中包含来自 字体正确排序和定位以及任何 应用的可选字体功能。hb_shape()
除了保存预整形输入Unicode 构成输入字符串的代码点和后整形 输出字形和位置HarfBuzz缓冲区有几个 影响成形的属性。最重要的是 文本流方向例如从左到右、从右到左、 从上到下或从下到上、脚本标记和 语言标记。
对于输入字符串缓冲区可以使用标志来表示何时 缓冲区表示段落的开头或结尾到 指示是否以可见方式呈现 Unicode 代码点以及修改群集合并 缓冲区的行为。对于整形输出缓冲区 每个字形的单个 X 和 Y 偏移量和逻辑尺寸为 访问。HarfBuzz 还会标记字形就好像在 该字形例如在换行或连字过程中 将需要重新塑造案文。Default IgnorableadvancesUNSAFE_TO_BREAK
HarfBuzz还提供了比较以下内容的方法 缓冲区、联接缓冲区、规范化缓冲区内容和句柄 无效的代码点以及确定状态 缓冲区例如输入代码点或输出字形。缓冲区 管理生命周期并对所有缓冲区进行引用计数。
虽然默认函数是 足以满足大多数用例还提供了变体 允许您指定在缓冲区上使用哪些 HarfBuzz 的整形器。hb_shape()
HarfBuzz可以读取TrueType字体TrueType集合OpenType 字体和 OpenType 集合。提供查询函数 有关指标、Unicode 覆盖率、可用表和 功能和变体选择器。单个字形也可以是 查询指标、变体和字形名称。开放类型 支持可变字体HarfBuzz 允许您设置 字体对象上的变体轴坐标。
HarfBuzz 提供胶水代码以与其他各种代码集成 库包括FreeTypeGObject和CoreText。支持 与Uniscribe和DirectWrite集成是实验性的 现在。
创建一个缓冲区并将文本放入其中。
#include hb.h
hb_buffer_t *buf;
buf hb_buffer_create();
hb_buffer_add_utf8(buf, text, -1, 0, -1);设置缓冲区的脚本、语言和方向。
hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
hb_buffer_set_language(buf, hb_language_from_string(en, -1));从字体文件创建字体和字体。
hb_blob_t *blob hb_blob_create_from_file(filename);
/* or hb_blob_create_from_file_or_fail() */
hb_face_t *face hb_face_create(blob, 0);
hb_font_t *font hb_font_create(face);形状
hb_shape(font, buf, NULL, 0);获取字形和位置信息。
unsigned int glyph_count;
hb_glyph_info_t *glyph_info hb_buffer_get_glyph_infos(buf, glyph_count);
hb_glyph_position_t *glyph_pos hb_buffer_get_glyph_positions(buf, glyph_count);遍历每个字形。
hb_position_t cursor_x 0;
hb_position_t cursor_y 0;
for (unsigned int i 0; i glyph_count; i)
{hb_codepoint_t glyphid glyph_info[i].codepoint;hb_position_t x_offset glyph_pos[i].x_offset;hb_position_t y_offset glyph_pos[i].y_offset;hb_position_t x_advance glyph_pos[i].x_advance;hb_position_t y_advance glyph_pos[i].y_advance;/* draw_glyph(glyphid, cursor_x x_offset, cursor_y y_offset); */cursor_x x_advance;cursor_y y_advance;
}整理。
hb_buffer_destroy(buf);
hb_font_destroy(font);
hb_face_destroy(face);
hb_blob_destroy(blob);HarfBuzz 中的数据类型概述
HarfBuzz 具有两种数据类型非不透明、 按值传递类型和不透明的堆分配类型。这种 的分离在必须提供 API/ABI 兼容性几乎无限期。
*值类型*不透明、按值传递 类型包括整数类型、枚举和小结构。暴露 公共 API 中的结构使得无法扩展 结构在未来。因此公开结构保留用于 否则效率极低的情况。
在 HarfBuzz 中几个结构比如 和 都属于效率敏感型。 类别并且是不透明的。hb_glyph_info_thb_glyph_position_t
对于未来扩展性可能为 包括必要的保留成员以保留空间 可能的未来成员。因此为此类结构提供 和方法非常重要允许 API 的用户 有效处理类型而无需 调整他们的代码以适应未来的变化。equal()hash()
HarfBuzz 提供的重要值类型包括结构 用于处理 Unicode 代码点、字形和字体标记 表和功能以及许多 Unicode 和 开放类型属性。
一个可用的例子
需要额外使用stb库该库可以在github上找到对应的只需要将stb_image_write 拷贝过来就可以了
//#include iostream
//#include QApplication
//#include turboopenglwidget.h
//
//int main(int argc, char **argv)
//{
// QApplication app(argc, argv);
// TurboOpenGLWidget tt;
// tt.show();
// return app.exec();
//}#include iostream
#include stdlib.h
#include stdio.h
#include assert.h
#include stdint.h
#include hb.h
#include hb-ft.h
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include stb_image_write.hstruct Pixel32
{uint8_t r, g, b, a;
};struct Image32
{size_t width;size_t height;Pixel32 *pixels;bool is_null() const{return pixels nullptr;}
};void save_image(Image32 image, const char *filePath)
{int ret stbi_write_png(filePath, image.width, image.height, 4, image.pixels, image.width * sizeof(Pixel32));if(!ret){fprintf(stderr, could not save file\n);}
}Pixel32 mix_pixels(Pixel32 dst, Pixel32 src)
{uint8_t rev_src_a 255 - src.a;Pixel32 result;result.r ((uint16_t) src.r * (uint16_t)src.a (uint16_t)dst.r * rev_src_a) 8;result.g ((uint16_t) src.g * (uint16_t)src.a (uint16_t)dst.g * rev_src_a) 8;result.b ((uint16_t) src.b * (uint16_t)src.a (uint16_t)dst.b * rev_src_a) 8;result.a dst.a;return result;
}void slap_ftbitmap_onto_image32(Image32 dest,FT_Bitmap *src,Pixel32 color,int x, int y)
{assert(src-pixel_mode FT_PIXEL_MODE_GRAY);assert(src-num_grays 256);for(size_t row 0; row src-rows; row){if(row y dest.height){for(size_t col 0; col src-width; col){if(col x dest.width){color.a src-buffer[row*src-pitch col];dest.pixels[(rowy)*dest.width col x] mix_pixels(dest.pixels[(rowy)*dest.widthcolx], color);}}}}
}void draw_glyph(Image32 surface, FT_Face face, hb_codepoint_t glyphId, double x, double y)
{// FT_UInt glyphIndex FT_Get_Char_Index(face, glyphId);FT_Error error FT_Load_Glyph(face, glyphId, FT_LOAD_DEFAULT);if(error){fprintf(stderr, could not load glyph %d, glyphId);return;}error FT_Render_Glyph(face-glyph, FT_RENDER_MODE_NORMAL);if(error){fprintf(stderr, could not render glyph %d, glyphId);return;}const Pixel32 FONT_COLOR{200, 200, 200, 255};slap_ftbitmap_onto_image32(surface, face-glyph-bitmap,FONT_COLOR,(int) floor(x) face-glyph-bitmap_left,(int) floor(y) face-glyph-bitmap_top);
}void destroy_or_whatever(void *userData)
{printf(destroy_or_whatever(%p)\n, userData);
}int main(int argc, char **argv)
{// 创建一个缓冲区并将文本放入其中。hb_buffer_t *buf hb_buffer_create();hb_buffer_add_utf8(buf, u8我是傻逼, -1, 0, -1);// 设置缓冲区的脚本、语言和方向。hb_buffer_set_direction(buf, HB_DIRECTION_LTR);hb_buffer_set_script(buf, HB_SCRIPT_HAN);hb_buffer_set_language(buf, hb_language_from_string(zh, -1));// 从字体文件创建字体和字体。FT_Library ftLib;FT_Error error FT_Init_FreeType(ftLib);if(error){fprintf(stderr, could not initialize Freetype\n);return -1;}FT_Face face;const char *fontPath E:\\QHarfbuzz3\\fonts\\NotoSerifSC-Regular.otf;size_t index 0;error FT_New_Face(ftLib, fontPath, index, face);if(error){fprintf(stderr, could not initialize load the font face %s\n, fontPath);return -1;}error FT_Set_Char_Size(face, 0, 5000, 0, 0);if(error){fprintf(stderr, could not set char size %s\n);return -1;}hb_font_t *font hb_ft_font_create(face, destroy_or_whatever);// 形状hb_shape(font, buf, NULL, 0);// 获取字形和位置信息。unsigned int glyph_count 0;printf(glyph_count initial %d\n, glyph_count);hb_glyph_info_t *glyph_info hb_buffer_get_glyph_infos(buf, glyph_count);printf(glyph_count infos %d\n, glyph_count);hb_glyph_position_t *glyph_pos hb_buffer_get_glyph_positions(buf, glyph_count);printf(glyph_count position %d\n, glyph_count);// 遍历每个字形。hb_position_t cursor_x 0;hb_position_t cursor_y 0;Image32 surface;surface.width 1000;surface.height 1000;surface.pixels (Pixel32 *)malloc(sizeof(Pixel32) * surface.width * surface.height);for(int i 0; i surface.height; i){for(int j 0; j surface.width; j){surface.pixels[i*surface.widthj] {30, 30, 30, 255};}}for (unsigned int i 0; i glyph_count; i){hb_codepoint_t glyph_id glyph_info[i].codepoint;hb_position_t x_offset glyph_pos[i].x_offset / 64.0;hb_position_t y_offset glyph_pos[i].y_offset / 64.0;hb_position_t x_advance glyph_pos[i].x_advance / 64.0;hb_position_t y_advance glyph_pos[i].y_advance / 64.0;draw_glyph(surface, face, glyph_id, cursor_x x_offset, cursor_y y_offset);cursor_x x_advance;cursor_y y_advance;}save_image(surface, out.png);hb_buffer_destroy(buf);hb_font_destroy(font);return 0;
}