golang/freetype

truetype: parse TTF failed with "bad TTF version"

sbinet opened this issue · 9 comments

the following program:

package main

import (
	"log"

	"github.com/go-fonts/latin-modern/lmroman12regular"
	"github.com/golang/freetype/truetype"
)

func main() {
	_, err := truetype.Parse(lmroman12regular.TTF)
	if err != nil {
		log.Fatalf("could not parse TTF data: %+v", err)
	}
}

fails with:

$> go run ./main.go
2020/05/23 20:34:03 could not parse TTF data: freetype: invalid TrueType format: bad TTF version
exit status 1

the equivalent program, using x/image/font/sfnt yields:

2020/05/23 21:10:19 num-glyphs: 821
package main

import (
	"log"

	"github.com/go-fonts/latin-modern/lmroman12regular"
	"golang.org/x/image/font/sfnt"
)

func main() {
	fnt, err := sfnt.Parse(lmroman12regular.TTF)
	if err != nil {
		log.Fatalf("could not parse TTF data: %+v", err)
	}
	log.Printf("num-glyphs: %d", fnt.NumGlyphs())
}

did you find a good solution for this? I have to use free-type library to draw text onto image, but I failed loading ttf file with exception“invalid TrueType format: bad TTF version”

I've migrated to using golang.org/x/image/font/opentype now.
(the latest version of x/image/font/opentype implements the x/image/font.Face interface so I am good.)

I've migrated to using golang.org/x/image/font/opentype now.
(the latest version of x/image/font/opentype implements the x/image/font.Face interface so I am good.)

.ttc is not supported by opentype. Is there a good solution for this?

.ttc is not supported by opentype. Is there a good solution for this?

hum... last time I tried, opentype was able to parse .ttc collections. (one needs to use opentype.ParseCollection though).

.ttc is not supported by opentype. Is there a good solution for this?

hum... last time I tried, opentype was able to parse .ttc collections. (one needs to use opentype.ParseCollection though).

How to convert a collection to a font face?

something like that should work:

package main

import (
	"fmt"
	"log"

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

func main() {
	fmt.Println("Hello, playground")
	var raw []byte // = ... some TTC collection
	ttc, err := opentype.ParseCollection(raw)
	if err != nil {
		log.Fatalf("could not parse collection: %+v", err)
	}
	fmt.Printf("# of fonts in collection: %d\n", ttc.NumFonts())

	fnt, err := ttc.Font(0) // get first font.
	if err != nil {
		log.Fatalf("could not open font #0: %+v", err)
	}

	face, err := opentype.NewFace(fnt, &opentype.FaceOptions{
		Size:    32,
		DPI:     72,
		Hinting: font.HintingNone,
	})
	if err != nil {
		log.Fatalf("could not open face #0: %+v", err)
	}
	defer face.Close()
	fmt.Printf("face: %+v\n", face)
}

https://play.golang.org/p/8YxgSHnS-qa

something like that should work:

package main

import (
	"fmt"
	"log"

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

func main() {
	fmt.Println("Hello, playground")
	var raw []byte // = ... some TTC collection
	ttc, err := opentype.ParseCollection(raw)
	if err != nil {
		log.Fatalf("could not parse collection: %+v", err)
	}
	fmt.Printf("# of fonts in collection: %d\n", ttc.NumFonts())

	fnt, err := ttc.Font(0) // get first font.
	if err != nil {
		log.Fatalf("could not open font #0: %+v", err)
	}

	face, err := opentype.NewFace(fnt, &opentype.FaceOptions{
		Size:    32,
		DPI:     72,
		Hinting: font.HintingNone,
	})
	if err != nil {
		log.Fatalf("could not open face #0: %+v", err)
	}
	defer face.Close()
	fmt.Printf("face: %+v\n", face)
}

https://play.golang.org/p/8YxgSHnS-qa

Is it possible to use all fonts?
There are several language in the collection (Chinese, Japanese and Korean)

of course.
one font.Face (with a matching font.Face.Close() when finished) per font you want to use.
(as much as physical memory can serve)