stb_truetype.h处理Unicode

4

我正在尝试使用stb_truetype.h来渲染中文字符,但是中文字符被错误地渲染了。我尝试渲染英文字符如 'a' 没有问题。是否有人能够提供一些关于如何在ubuntu 13.04/gcc4.8.1上处理unicode的见解?

这是我的代码:

#include <stdio.h>
#include <math.h>
#define STB_TRUETYPE_IMPLEMENTATION  // force following include to generate implementation
#include "stb_truetype.h"

char ttf_buffer[1<<25];

int main(int argc, char **argv)
{
   stbtt_fontinfo font;
   unsigned char *bitmap;
   int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 0x4e00)/*choose character here*/, s = (argc > 2 ? atoi(argv[2]) : 20/*set font size*/);

   fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "mingliu.ttc", "rb"));
   //c:/windows/fonts/arialbd.ttf
   //also tried Dejavu font on ubuntu for the chinese character
   stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));

       bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);

       for (j=0; j < h; ++j) {
          for (i=0; i < w; ++i)
             putchar(" 1234567"[bitmap[j*w+i]>>5]);
          putchar('\n');
       }

   return 0;
}

使用 'a' 输出

  2342   
 52  61  
 7   32  
 1   43  
   2553  
  53 33  
 62  33  
26   43  
271 165  
 7763174 
  2   1 

使用'一'输出

466666666666666664
653333333333333356
63              36
63              36
63              36
63              36
63              36
63              36
63              36
63              36
63              36
63              36
63              36
63              36
63              36
63              36
664444444444444466
466666666666666664

应该长这样: 字符“一” 来自http://www.fileformat.info/info/unicode/char/4e00/index.htm


请提供命令行参数,因为从您的代码中不清楚您正在使用什么。它是否适用于普通Arial和较大的Unicode?文档提到“待办事项:非MS cmaps”。我现在不在电脑后面,但我可以检查mingliu.ttc是否可能是问题所在。 - Jongware
至少在c:/windows上,字体中没有的字形通常会被渲染成一个矩形。那肯定看起来像个矩形 :) 这段代码过于晦涩,将U+6211误认为是十进制6211,并且你得到了一个解释,但这不是MingLiU中的有效字形。 - Hans Passant
@Jongware 我应该像这样编译:gcc sample.c -lm,但我回家后会检查一下。 @HansPassant 据我所知,我应该使用正确的码点,即中文字符“一”。我怀疑 gcc 使用的不是 UTF-8? - metro
1个回答

4

如果您提供正确的Unicode符号键-问题很可能是您的字体不支持指定的字符。字体文件可能彼此不同,实际符号可能会丢失。我使用以下代码检查字符是否确实受支持,而不是被某些默认的框架符号替换:

// 11111 - code of some definitely unsupported char in my case
int replacer = stbtt_FindGlyphIndex(&font->font, 11111);     
int g = stbtt_FindGlyphIndex(&font->font, codepoint);
if (g == replacer)
    return NULL;

因此,您可以将字形索引与某些明确不支持的符号(您可以选择自己的符号)的字形索引进行比较,并检查该符号是否真正存在于字体文件中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接