【问题标题】:How to draw a special character of LaTeX fonts (cmr10.ttf) in iOS?如何在 iOS 中绘制 LaTeX 字体(cmr10.ttf)的特殊字符?
【发布时间】:2013-04-09 04:16:32
【问题描述】:

总结

我正在为 iPhone 开发一个计算器应用程序,并希望将数学表达式绘制到 UIView,就像 LaTeX 外观一样。
所以我使用 cmr10.ttf(LaTeX 默认)作为绘图字体,但有些字符没有显示出来。

测试代码及细节

这是我的测试代码:

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    const int len = 4;
    Byte cstr[len];
    cstr[0] = 0x30; // 0
    cstr[1] = 0x00; // Capital Gamma
    cstr[2] = 0x41; // A
    cstr[3] = 0x61; // a
    NSString *str = [[NSString alloc] initWithBytes:(const void*)cstr length:len encoding:NSASCIIStringEncoding];
    [str drawAtPoint:CGPointMake(10, 0) withFont:[UIFont fontWithName:@"cmr10" size:40]];
}

我原以为 UIView 会显示“0ΓAa”,但实际上显示的是“0Aa”,没有大写 gamma。
根据 CMR10 代码表(见下文),0x00 表示大写 gamma。但在 ASCII 表中,0x00 表示 NUL 控制字符。这可能是没有显示大写伽玛字符的原因。

这是 CMR10 的代码表。字母等一般字符与 ASCII 表的代码相同,其他的则不同。

(来自http://www.tug.org/texlive//devsrc/Master/texmf-dist/doc/latex/base/encguide.pdf的第18页)

问题

所以我想知道的是如何绘制一个字符代码与ASCII中的控制字符相同的字符。

其他信息

  • 我在 BaKoMa 字体包中使用了 cmr10.ttf。
  • 我正在 Xcode 4.6.1 和 iOS5 或更高版本的设备上开发这个计算器应用程序。

【问题讨论】:

    标签: iphone ios nsstring latex special-characters


    【解决方案1】:

    我找到了一种使用CGContextShowGlyphsAtPointCGFontGetGlyphWithGlyphName 来绘制具有控制字符代码的字符的方法。

    例子:

    CGContextRef context = UIGraphicsGetCurrentContext();
    
    if (context) {
    
        CGFontRef font = CGFontCreateWithFontName(CFSTR("cmr10"));
        CGContextSetFont(context, font);
        CGContextSetFontSize(context, 40);
        CGAffineTransform transform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
        CGContextSetTextMatrix(context, transform);
    
        const int len = 4;
        CGGlyph glyphs[len];
        glyphs[0] = CGFontGetGlyphWithGlyphName(font, CFSTR("Gamma"));
        glyphs[1] = CGFontGetGlyphWithGlyphName(font, CFSTR("Upsilon"));
        glyphs[2] = CGFontGetGlyphWithGlyphName(font, CFSTR("Theta"));
        glyphs[3] = CGFontGetGlyphWithGlyphName(font, CFSTR("fl"));
    
        CGContextShowGlyphsAtPoint(context, 0, 50, glyphs, len);
        CGFontRelease(font);
    }
    

    CGFontGetGlyphWithGlyphName 的第二个参数中的“Gamma”是名为“post”的字形名称(参见http://scripts.sil.org/cms/scripts/page.php?item_id=IWS-Chapter08#05931f9d)。在 cmr10.ttf 文件中定义。

    我使用 TTFEdit 来查找字形名称。

    1. 启动 TTFEdit。
    2. 文件 -> 打开。然后选择一个 TTF 文件并点击打开。
    3. 选择glyf标签。
    4. 找到一个字符,然后将鼠标悬停在它上面并按住几秒钟。
    5. 字形名称将显示为提示。

    【讨论】:

      【解决方案2】:

      drawAtPoint: 应该透明地处理所有编码内容,所以我希望 以下工作:

      NSString *str = @"0ΓAa";
      [str drawAtPoint:CGPointMake(10, 0) withFont:[UIFont fontWithName:@"cmr10" size:40]];
      

      更新:我现在已经下载了字体并测试了代码。真的很管用。

      更新 2: 它不起作用?。但我用“TTFdump”工具(来自Microsoft Typography tools页面)检查了“cmr10.ttf”字体,发现如下:

      字体包含一个平台 ID = 3 和编码 ID = 1 的“cmap”表。根据http://www.microsoft.com/typography/otspec/cmap.htm,这应该是从 Unicode 到字形 ID 的映射。但事实并非如此。例如,Unicode U+00A1 映射到字形 id 19,即“Gamma”字形。但“Gamma”的真正 Unicode 是 U+0393。

      所以这个

      // 00A1 = Gamma, 00A8 = Upsilon, 00A3 = Theta, 00B0 = fl.
      NSString *str = @"\u00A1\u00A8\u00A3\u00B0";
      [str drawAtPoint:CGPointMake(10, 10) withFont:[UIFont fontWithName:@"cmr10" size:40]];
      

      实际显示来自cmr10字体的字符!

      但是我没有发现这个奇怪的编码是从哪里来的。所以这更像是一个 理论兴趣,并使用CGFontGetGlyphWithGlyphName,如Daiki的回答 是更好的解决方案。

      【讨论】:

      • 感谢您的回答和测试 :) 我尝试了该代码,但大写 gamma 是用另一种字体(不是 cmr10)绘制的。用 cmr10 正确绘制了“0”、“A”和“a”。
      • @DaikiKomatsuda:你说得对,我没有注意到区别。稍后我会看看我是否能解决问题,否则你有你的工作解决方案。
      • @DaikiKomatsuda:我在回答中添加了一些信息。它没有解决问题,但解释了为什么通常的方法不起作用(TrueType字体中的cmap编码错误)。
      • 你的新方法很简单。我认为这对于几种特殊字符也更好。对于多种字符,我的解决方案可能很容易阅读。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2013-04-22
      • 2016-06-11
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-01
      相关资源
      最近更新 更多