首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过CTFontRef或CGFontRef对象中的字形索引获取unicode字符

通过CTFontRef或CGFontRef对象中的字形索引获取unicode字符
EN

Stack Overflow用户
提问于 2011-02-12 18:08:47
回答 2查看 3K关注 0票数 7

CTFontRef为将字符映射到字形提供了很好的方法,比如CTFontGetGlyphsForCharacters。我的问题是,有什么方法可以进行反向映射吗?也就是说,我可以通过给定字形来获取字符吗?因为我发现有一个CTFontCopyCharacterSet可以获取所有支持的字符,所以我想会有一些很好的解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-08 18:22:38

我认为你最终可能不得不自己解析字体的映射表。您可以使用CGFontCopyTableForTag()访问这些表;您需要的表是'cmap‘表,其格式如下所示:

http://www.microsoft.com/typography/otspec/cmap.htm

还有这里:

http://developer.apple.com/fonts/TTRefMan/RM06/Chap6cmap.html

不幸的是,通过阅读这些文档您会发现,将字符映射到字形绝对不是一件容易的事情,此外,任何给定的字体都可能有多个映射表(即,使用给定字形的字符集可能取决于您或渲染器选择的映射表格式)。

此外,诸如OpenType或AAT的高级字体技术可能导致字形的存在,对于这些字形,不存在来自字符的直接映射,但是作为智能字体技术所作的替换的结果,这些字形仍然存在于输出中。颠倒OpenType或AAT替换机制会很棘手,而且可能不会产生单一的Unicode代码点(甚至不会产生单一的字素集群)。

票数 3
EN

Stack Overflow用户

发布于 2015-04-15 01:42:52

字形TLDR: CTFont/CTFontRef/CTGlyph是不够的-- CTLine和CTRun需要参与进来;即使这样,也只有在你有权访问原始字符串->字形映射的情况下才有意义。

我晚了几年再来讨论这个问题,以防其他人最终遇到这个问题。正如alastair所指出的,没有任何方法可以将字形映射回字符。简单的例子-- 'space‘有多个unicode字符,通常映射到同一个字形。对于“micro”和希腊语“u”也是如此。

然而,它有时是(通常?)拥有原始字符串的情况下,您真正想要的是知道它是如何映射到字形的。换句话说,我得到了我的字符串,我得到了结果字形-对于每个字形索引,它在字符串中的字符索引是什么。我写这个示例是为了演示一种实现这一点的方法。(旁白:学到的教训- Swift在使用一些Core Foundation API时会变得有点粗糙)

代码语言:javascript
复制
import CoreText
import AppKit

func main(argc: Int, argv: [String])
{
    var stringAttributes: [String: AnyObject] = [:]
    var fontName = "Zapfino"
    var fUseLigatures = false

    var fontNameIndex = 0
    if argc > 1
    {
        if argv[1] == "/lig"
        {
            fUseLigatures = true;
            if (argc > 2) { fontNameIndex = 3 }
        }
        else { fontNameIndex = 2 }
    }

    if fontNameIndex > 0 { fontName = argv[fontNameIndex] }

    if let font = NSFont(name:fontName, size:24.0)
        { stringAttributes[NSFontAttributeName] = font }

    stringAttributes[NSLigatureAttributeName] = fUseLigatures ? 2 : 0

    let string = NSAttributedString(
    string:"This is \(fontName)!",
    attributes: stringAttributes)

    let line = CTLineCreateWithAttributedString(string) // CTLine

    let runs = CTLineGetGlyphRuns(line) // CTRun[]
    let nsRuns:Array<AnyObject> = runs as Array<AnyObject>
    assert(nsRuns.count == 1)

    let run = nsRuns[0] as! CTRun

    let glyphCount = CTRunGetGlyphCount(run)
    println("String: \(string.string)")
    println("\tStrLen: \(count(string.string)), Count Of Glyphs: \(glyphCount)");

    let clusters = UnsafeMutablePointer<CFIndex>.alloc(glyphCount)

    CTRunGetStringIndices(run, CFRange(location:0, length:glyphCount), clusters)

    for var idx = 0; idx < glyphCount; idx++
    {
        let idxString = clusters[idx];
        println("Glyph @ \(idx) maps to String @ \(idxString)")
    }
}

main(Process.arguments.count, Process.arguments)

如果在不使用参数的情况下运行此命令,然后在命令行中使用/lig,您将获得以下输出:

代码语言:javascript
复制
    String: This is Zapfino!
        StrLen: 16, Count Of Glyphs: 16
Glyph @ 0 maps to String @ 0
Glyph @ 1 maps to String @ 1
Glyph @ 2 maps to String @ 2
Glyph @ 3 maps to String @ 3
Glyph @ 4 maps to String @ 4
Glyph @ 5 maps to String @ 5
Glyph @ 6 maps to String @ 6
Glyph @ 7 maps to String @ 7
Glyph @ 8 maps to String @ 8
Glyph @ 9 maps to String @ 9
Glyph @ 10 maps to String @ 10
Glyph @ 11 maps to String @ 11
Glyph @ 12 maps to String @ 12
Glyph @ 13 maps to String @ 13
Glyph @ 14 maps to String @ 14
Glyph @ 15 maps to String @ 15
joes-mac: Tue Apr 14, 10:26:00
~/Source/FontGlyph/./main /lig
String: This is Zapfino!
        StrLen: 16, Count Of Glyphs: 7
Glyph @ 0 maps to String @ 0
Glyph @ 1 maps to String @ 2
Glyph @ 2 maps to String @ 4
Glyph @ 3 maps to String @ 5
Glyph @ 4 maps to String @ 7
Glyph @ 5 maps to String @ 8
Glyph @ 6 maps to String @ 15

我添加了Ligature选项来帮助可视化字形和字符很容易不是1比1。下面是这两个字符串的可视化表示:

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4977475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档