如何通过系统API绘制无对应cmap映射、仅知glyphIndex的字符?
针对无cmap映射字形的系统API渲染方案
Windows平台:ExtTextOutW + ETO_GLYPH_INDEX
你推测的方案完全可行,ExtTextOutW配合ETO_GLYPH_INDEX标志正是Windows平台下直接通过字形索引(glyphIndex)渲染字形的标准方式,无需依赖cmap映射的代码点。
具体实现步骤:
- 将目标字体选入设备上下文(DC):通过
CreateFontW或CreateFontIndirectW创建字体对象,再用SelectObject选入DC。 - 准备字形索引数组:字形索引为16位无符号整数,需用
WORD类型数组存储目标索引。 - 调用
ExtTextOutW:指定ETO_GLYPH_INDEX标志,将字形索引数组作为文本参数传入,同时指定渲染坐标。
示例代码:
HDC hdc = GetDC(hWnd); // 创建并选入目标字体,参数按需调整字号、样式等 HFONT hFont = CreateFontW(24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"YourTargetFont"); HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); WORD targetGlyphIndex = 0x0105; // 替换为实际有效的字形索引 // 渲染到坐标(100, 100) ExtTextOutW(hdc, 100, 100, ETO_GLYPH_INDEX, NULL, (LPCWSTR)&targetGlyphIndex, 1, NULL); // 清理资源 SelectObject(hdc, hOldFont); DeleteObject(hFont); ReleaseDC(hWnd, hdc);
注意事项:
- 必须确保传入的字形索引在当前选入字体的有效范围内,否则系统会渲染默认的替换字形(通常是空心方框)。
- 如需调整字形颜色、旋转或缩放,可结合
SetTextColor、SetWorldTransform等API实现。
macOS平台:CoreText/CGContext API
macOS下可直接通过CoreGraphics或CoreText API渲染指定字形索引的字形:
- 使用
CGContextShowGlyphsAtPoint直接在图形上下文渲染; - 如需排版控制,可通过
CTLineCreateWithGlyphs创建排版行后渲染。
示例代码(Objective-C):
CGContextRef ctx = UIGraphicsGetCurrentContext(); // 创建目标字体对象,参数为字体名和字号 CTFontRef font = CTFontCreateWithName(CFSTR("YourTargetFont"), 24.0, NULL); CGGlyph targetGlyph = 0x0105; // 目标字形索引 CGPoint renderPoint = CGPointMake(100.0, 100.0); // 渲染字形 CGContextShowGlyphsAtPoint(ctx, renderPoint.x, renderPoint.y, &targetGlyph, 1); CFRelease(font);
Linux(X11)平台:Pango库
Linux下推荐使用Pango库实现字形索引渲染,Pango对字体处理的封装更完善:
- 创建Pango上下文和布局;
- 获取目标字体对应的
PangoFont; - 构造
PangoGlyphString并设置字形索引; - 将字形字符串绑定到布局后渲染到X11窗口。
示例代码片段:
PangoContext *ctx = pango_xft_get_context(display, screen); PangoLayout *layout = pango_layout_new(ctx); PangoFontDescription *desc = pango_font_description_from_string("YourTargetFont 24"); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); PangoGlyphString *glyphStr = pango_glyph_string_new(); // 设置字形索引和位置,x/y偏移按需调整 pango_glyph_string_set_size(glyphStr, 1); glyphStr->glyphs[0].glyph = 0x0105; glyphStr->glyphs[0].geometry.x_offset = 0; glyphStr->glyphs[0].geometry.y_offset = 0; glyphStr->log_clusters[0] = 0; pango_layout_set_glyphs(layout, glyphStr); // 渲染到窗口 pango_xft_render_layout(drawable, visual, colormap, layout, 100, 100); pango_glyph_string_free(glyphStr); g_object_unref(layout); g_object_unref(ctx);
内容的提问来源于stack exchange,提问作者Carson
相关产品推荐
相关产品推荐

