gofpdf icon indicating copy to clipboard operation
gofpdf copied to clipboard

generateCIDFontMap panic on loading fonts with glyphs indexed at high numbers

Open ajstarks opened this issue 5 years ago • 6 comments

Using the Symbola font (which contains 10744 glyphs -- see: http://users.teilar.gr/~g1951d/) when trying to index into the emoji range 0x1f600 - 0x1f64f, generateCIDFontMap crashes with index out of range. Using a smaller range with the same font works fine

$ utab Symbola.ttf 0x2600 0x2800
$ utab Symbola.ttf 0x1f600 0x1f64f
panic: runtime error: index out of range

goroutine 1 [running]:
github.com/jung-kurt/gofpdf.(*Fpdf).generateCIDFontMap(0xc0000d0000, 0xc000079c18, 0x1f64f)
	/home/ajstarks/gowork/src/github.com/jung-kurt/gofpdf/fpdf.go:3926 +0x14af
github.com/jung-kurt/gofpdf.(*Fpdf).putfonts(0xc0000d0000)
	/home/ajstarks/gowork/src/github.com/jung-kurt/gofpdf/fpdf.go:3849 +0xef4
github.com/jung-kurt/gofpdf.(*Fpdf).putresources(0xc0000d0000)
	/home/ajstarks/gowork/src/github.com/jung-kurt/gofpdf/fpdf.go:4284 +0x75
github.com/jung-kurt/gofpdf.(*Fpdf).enddoc(0xc0000d0000)
	/home/ajstarks/gowork/src/github.com/jung-kurt/gofpdf/fpdf.go:4468 +0x121
github.com/jung-kurt/gofpdf.(*Fpdf).Close(0xc0000d0000)
	/home/ajstarks/gowork/src/github.com/jung-kurt/gofpdf/fpdf.go:672 +0xa1
github.com/jung-kurt/gofpdf.(*Fpdf).Output(0xc0000d0000, 0x5defc0, 0xc00000e598, 0xc0000001b6, 0xc00000e598)
	/home/ajstarks/gowork/src/github.com/jung-kurt/gofpdf/fpdf.go:3231 +0xd7
github.com/jung-kurt/gofpdf.(*Fpdf).OutputFileAndClose(0xc0000d0000, 0x5a5241, 0x8, 0x7ffcfb565981, 0xb)
	/home/ajstarks/gowork/src/github.com/jung-kurt/gofpdf/fpdf.go:3212 +0xe6
main.main()
	/home/ajstarks/TTF/utab.go:53 +0x53a
// utab -- print a unicode font glyph table
package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/jung-kurt/gofpdf"
)

func main() {
	if len(os.Args) != 4 {
		fmt.Fprintf(os.Stderr, "specify fontfile begin end\n")
		os.Exit(1)
	}
	fontname := os.Args[1]
	begin, _ := strconv.ParseInt(os.Args[2], 0, 32)
	end, _ := strconv.ParseInt(os.Args[3], 0, 32)

	pdf := gofpdf.New("P", "mm", "Letter", "")
	pdf.AddUTF8Font("font", "", fontname)

	fontSize := 24.0
	left := 20.0
	top := 20.0
	right := 200.0
	bottom := 250.0
	footer := bottom + 20.0
	colsize := 18.0

	pdf.AddPage()
	x, y := left, top
	for i := begin; i <= end; i++ {
		pdf.SetTextColor(0, 0, 0)
		pdf.SetFont("font", "", fontSize)
		pdf.Text(x, y, string(i))
		pdf.SetTextColor(127, 0, 0)
		pdf.SetFont("courier", "", 10)
		pdf.Text(x, y+5, fmt.Sprintf("%05x", i))
		x += fontSize * 1.2
		if x > right {
			x = left
			y += colsize
		}
		if y > bottom {
			pdf.Text(left, footer, fontname)
			pdf.AddPage()
			x, y = left, top
		}
	}
	pdf.Text(left, footer, fontname)
	if err := pdf.OutputFileAndClose("utab.pdf"); err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
	}
}

ajstarks avatar May 14 '19 23:05 ajstarks

Thanks for the report, @ajstarks. At first glance, it looks like this line is the culprit -- the number of character widths is hard-coded to 65536. I think I'll need to dynamically extend this slice as needed.

jung-kurt avatar May 14 '19 23:05 jung-kurt

Unfortunately, the problem goes deeper than just the size of the character width slice. When I increased the allocated size for testing purposes, the glyph table program did not crash but the characters did not render properly.

jung-kurt avatar May 15 '19 11:05 jung-kurt

Any update on this issue?

ajstarks avatar Jun 13 '19 12:06 ajstarks

@DarkFreedman -- what would be involved in supporting more than 64K glyphs in a Unicode font?

jung-kurt avatar Jun 13 '19 13:06 jung-kurt

When do you implement this issue?

bohdanlisovskyi avatar Aug 06 '19 08:08 bohdanlisovskyi

There is a lot of utf-8 code that depends on two-byte runes. Fixing this will be a substantial undertaking. Any help in this regard will be appreciated.

jung-kurt avatar Aug 06 '19 12:08 jung-kurt