登录
首页 >  Golang >  Go问答

如何从 golang 中的 .ttf 文件获取字体系列名称?

来源:stackoverflow

时间:2024-04-18 12:24:38 318浏览 收藏

Golang不知道大家是否熟悉?今天我将给大家介绍《如何从 golang 中的 .ttf 文件获取字体系列名称?》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希望大家都能积极评论指出,谢谢!希望我们能一起加油进步!

问题内容

众所周知,.ttf(或otf)字体文件的文件名并不总是与字体系列名称相同,例如,如果我将arial.ttf重命名为abcd.ttf,它的字体系列名称仍然是arial,那么golang中有没有一个包或库来解析.ttf并获取该名称?

我尝试过freetype,但似乎没有方法可以得到它

package main

import (
    "fmt"
    "io/ioutil"
    "os"

    "github.com/golang/freetype"
)

func main() {
    homedir, _ = os.userhomedir()
    fontfile := homedir + "/downloads/new folder with items 5/arial.ttf"
    fontbytes, err := ioutil.readfile(fontfile)
    font, err := freetype.parsefont(fontbytes)
    if err == nil {
        fmt.println(font)
    }
}

*truetype.font的方法很少

name 返回给定 nameid 的字体名称值

哪里可以找到 nameid

编辑:

原来nameid是一个go常量,代表truetype字体属性的一个field,我发现nameidpostscriptname字段的值会被用作字体唯一名称,例如一个.fcpxml文件就会使用这个值因为它的字体名称

以下代码片段可以获得.ttf文件的唯一字体名称

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "path/filepath"

    // the original freetype has a bug for utf8: https://github.com/golang/freetype/issues/66
    // "github.com/golang/freetype"

    // so we use this beta one
    "github.com/beta/freetype"
    "github.com/beta/freetype/truetype"
)

// getpostscriptname returns the postscriptname of a .ttf font file
func getpostscriptname(fontfilepath string) (postscriptname string, err error) {
    postscriptname = ""
    fontbytes, err := ioutil.readfile(fontfilepath)
    if err == nil {
        font, err := freetype.parsefont(fontbytes)
        if err == nil {
            postscriptname = font.name(truetype.nameidpostscriptname)
        }
    }
    return postscriptname, err
}

func main() {
    fontfilerelative := "downloads/new folder with items 5/arial.ttf"
    homedir, _ := os.userhomedir()
    fontfile := filepath.join(homedir, fontfilerelative)

    postscriptname, _ := getpostscriptname(fontfile)
    fmt.println(postscriptname)
}

编辑2:

freetype不支持otf文件,谷歌搜索后,我发现我们可以使用sfnt来获取.ttf.otf字体文件的所有元

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"

    "golang.org/x/image/font/sfnt"
)

func main() {
    fontfile := "/path/to/arial.ttf"
    nameids, err := getfntnameids(fontfile)
    if err == nil {
        fmt.println(nameids["nameidpostscript"])
        fmt.println("-------------------------")
        prettyprint(nameids)
    } else {
        fmt.println(err)
    }
}

// prettyprint print map or slice as formatted json
func prettyprint(v interface{}) (err error) {
    b, err := json.marshalindent(v, "", "  ")
    if err == nil {
        fmt.println(string(b))
    }
    return
}

// getfntnameids returns .ttf or .otf font nameids
// inspired by https://github.com/wayneashleyberry/sfnt
func getfntnameids(fontfile string) (nameidinfo map[string]string, err error) {

    b, err := ioutil.readfile(fontfile)
    if err != nil {
        return nameidinfo, err
    }

    f, err := sfnt.parse(b)
    if err != nil {
        return nameidinfo, err
    }

    nameids := []sfnt.nameid{
        sfnt.nameidcopyright,
        sfnt.nameidfamily,
        sfnt.nameidsubfamily,
        sfnt.nameiduniqueidentifier,
        sfnt.nameidfull,
        sfnt.nameidversion,
        sfnt.nameidpostscript,
        sfnt.nameidtrademark,
        sfnt.nameidmanufacturer,
        sfnt.nameiddesigner,
        sfnt.nameiddescription,
        sfnt.nameidvendorurl,
        sfnt.nameiddesignerurl,
        sfnt.nameidlicense,
        sfnt.nameidlicenseurl,
        sfnt.nameidtypographicfamily,
        sfnt.nameidtypographicsubfamily,
        sfnt.nameidcompatiblefull,
        sfnt.nameidsampletext,
        sfnt.nameidpostscriptcid,
        sfnt.nameidwwsfamily,
        sfnt.nameidwwssubfamily,
        sfnt.nameidlightbackgroundpalette,
        sfnt.nameiddarkbackgroundpalette,
        sfnt.nameidvariationspostscriptprefix,
    }

    labels := []string{
        "nameidcopyright",
        "nameidfamily",
        "nameidsubfamily",
        "nameiduniqueidentifier",
        "nameidfull",
        "nameidversion",
        "nameidpostscript",
        "nameidtrademark",
        "nameidmanufacturer",
        "nameiddesigner",
        "nameiddescription",
        "nameidvendorurl",
        "nameiddesignerurl",
        "nameidlicense",
        "nameidlicenseurl",
        "nameidtypographicfamily",
        "nameidtypographicsubfamily",
        "nameidcompatiblefull",
        "nameidsampletext",
        "nameidpostscriptcid",
        "nameidwwsfamily",
        "nameidwwssubfamily",
        "nameidlightbackgroundpalette",
        "nameiddarkbackgroundpalette",
        "nameidvariationspostscriptprefix",
    }

    nameidinfo = map[string]string{}
    for i, nameid := range nameids {
        label := labels[i]

        value, err := f.name(nil, nameid)
        if err != nil {
            nameidinfo[label] = ""
            continue
        }

        nameidinfo[label] = value
    }

    return nameidinfo, err
}

输出

ArialMT
-------------------------
{
  "NameIDCompatibleFull": "",
  "NameIDCopyright": "© 2006 The Monotype Corporation. All Rights Reserved.",
  "NameIDDarkBackgroundPalette": "",
  "NameIDDescription": "",
  "NameIDDesigner": "Monotype Type Drawing Office - Robin Nicholas, Patricia Saunders 1982",
  "NameIDDesignerURL": "",
  "NameIDFamily": "Arial",
  "NameIDFull": "Arial",
  "NameIDLicense": "You may use this font to display and print content as permitted by the license terms for the product in which this font is included. You may only (i) embed this font in content as permitted by the embedding restrictions included in this font; and (ii) temporarily download this font to a printer or other output device to help print content.",
  "NameIDLicenseURL": "",
  "NameIDLightBackgroundPalette": "",
  "NameIDManufacturer": "The Monotype Corporation",
  "NameIDPostScript": "ArialMT",
  "NameIDPostScriptCID": "",
  "NameIDSampleText": "",
  "NameIDSubfamily": "Regular",
  "NameIDTrademark": "Arial is a trademark of The Monotype Corporation in the United States and/or other countries.",
  "NameIDTypographicFamily": "",
  "NameIDTypographicSubfamily": "",
  "NameIDUniqueIdentifier": "Monotype:Arial Regular:Version 5.01 (Microsoft)",
  "NameIDVariationsPostScriptPrefix": "",
  "NameIDVendorURL": "",
  "NameIDVersion": "Version 5.01.2x",
  "NameIDWWSFamily": "",
  "NameIDWWSSubfamily": ""
}

实际上,软件将使用 nameidfamilynameidtypgraphicsubfamily 作为 font 属性,而不是 nameidpostscriptname


正确答案


使用这个go库freetype可以读取ttf文件的数据,你只需要提供字体数据,它就会解析所有数据。还有一篇关于使用 javascipt 手动读取 ttf 文件内容的文章 here

编辑:如果您使用 freetype 来获取姓氏或其他信息,您可以使用结构体的 name 接收器函数,它接受一个 nameid,它是 uint16 的别名。 (您可以在名称id代码部分找到有效值here的完整表格)

例如,您可以使用以下代码获取字体系列名称:

package main

import (
    "fmt"
    "io/ioutil"

    "github.com/golang/freetype"
)

func main() {
    fontFile := "./font.ttf"
    fontBytes, err := ioutil.ReadFile(fontFile)
    font, err := freetype.ParseFont(fontBytes)
    if err == nil {
        fmt.Println(font.Name(1))
    }
}

以上就是《如何从 golang 中的 .ttf 文件获取字体系列名称?》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>