jung-kurt / gofpdf

A PDF document generator with high level support for text, drawing and images
http://godoc.org/github.com/jung-kurt/gofpdf
MIT License
4.31k stars 777 forks source link

generateCIDFontMap panic on loading fonts with glyphs indexed at high numbers #255

Open ajstarks opened 5 years ago

ajstarks commented 5 years ago

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)
    }
}
jung-kurt commented 5 years ago

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 commented 5 years ago

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.

ajstarks commented 5 years ago

Any update on this issue?

jung-kurt commented 5 years ago

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

bohdanlisovskyi commented 5 years ago

When do you implement this issue?

jung-kurt commented 5 years ago

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.