tdewolff / canvas

Cairo in Go: vector to raster, SVG, PDF, EPS, WASM, OpenGL, Gio, etc.
MIT License
1.51k stars 103 forks source link

ParseLaTeX() function doesn't work #288

Closed RobinCoffee closed 7 months ago

RobinCoffee commented 7 months ago

I am trying to render Latex math expressions for an application I am making. While troubleshooting I switched to just trying to render png images like this:

package main

import (
    "github.com/tdewolff/canvas"
    "github.com/tdewolff/canvas/renderers"
)

func main() {
    // Create new canvas of dimension 100x100 mm
    c := canvas.New(100, 100)

    // Create a canvas context used to keep drawing state
    ctx := canvas.NewContext(c)

    // Create a triangle path from an SVG path and draw it to the canvas
    triangle, err := canvas.ParseLaTeX(`(5^2)^{1/2}=\,{25}^{1/2}`)
    if err != nil {
        panic(err)
    }
    ctx.SetFillColor(canvas.Mediumseagreen)
    ctx.DrawPath(20, 20, triangle)

    // Rasterize the canvas and write to a PNG file with 3.2 dots-per-mm (320x320 px)
    if err := renderers.Write("getting-started.png", c, canvas.DPMM(3.2)); err != nil {
        panic(err)
    }
}

I stole most of the code from here. I just replaced the SVG with the latex expression. (I have tested the original code as well and get the triangle as expected) The code I wrote compiles but I get these errors:

panic: runtime error: index out of range [-1]

goroutine 1 [running]:
github.com/tdewolff/font.(*cffTable).ToPath(0x140001df280, {0x104991100, 0x140001a6648}, 0x52, 0x47e?, 0x402a3a90beb746f4, 0xc001e9d627092cab, 0x3f643acce41a0849, 0x1400035d0c0?)
    /Users/RobinCoffee/go/pkg/mod/github.com/tdewolff/font@v0.0.0-20240404204409-be214eafe484/sfnt_cff.go:644 +0x22d8
github.com/tdewolff/font.(*SFNT).GlyphPath(0x104938da0?, {0x104991100?, 0x140001a6648?}, 0xc464?, 0x47e?, 0x140000299a8?, 0x1047ec42c?, 0x140000299a8?, 0x1047ec7b4?)
    /Users/RobinCoffee/go/pkg/mod/github.com/tdewolff/font@v0.0.0-20240404204409-be214eafe484/sfnt.go:141 +0x38
github.com/tdewolff/canvas.(*dviFont).Draw(0x1400035d0e0, {0x104991100, 0x140001a6648}, 0x402a3a90beb746f4, 0xc001e9d627092cab, 0x43?)
    /Users/RobinCoffee/go/pkg/mod/github.com/tdewolff/canvas@v0.0.0-20240407210806-e89965a0c7c9/latex.go:309 +0xf8
github.com/tdewolff/canvas.DVI2Path({0x1400035a000, 0x154, 0x200}, {0x10498ef28, 0x140001ae528})
    /Users/RobinCoffee/go/pkg/mod/github.com/tdewolff/canvas@v0.0.0-20240407210806-e89965a0c7c9/latex_dvi.go:73 +0x1298
github.com/tdewolff/canvas.ParseLaTeX({0x1048501be, 0x16})
    /Users/RobinCoffee/go/pkg/mod/github.com/tdewolff/canvas@v0.0.0-20240407210806-e89965a0c7c9/latex.go:85 +0x45c
main.main()
    /Users/RobinCoffee/GOSTUDY-Shared/gui-playground/fyne/image/tri.go:16 +0x154
exit status 2

I have tested this expression before and I have also tried other expressions but nothing has worked thus far

I am using MacOS Sonoma 14.4 and my Go version is go1.22.2 darwin/arm64

RobinCoffee commented 7 months ago

Doing more testing I made a simple program that attempts to parse the Latex and then just prints out the path:

package main

import (
    "github.com/tdewolff/canvas"
    "fmt"
)

func main() {
    formula, _ := canvas.ParseLaTeX("x")
    fmt.Println(formula)
}

Running it with "x" as the formula gives this:

M1.5314972273198375 0.5044722222222222C1.5314972273198375 0.5397500000000002 1.503275005097617 0.5397500000000002 1.478580560653171 0.5397500000000002C1.4362472273198392 0.5397500000000002 1.432719449542061 0.5362222222222224 1.4150805606531716 0.47977777777777764C1.3198305606531715 0.17638888888888893 1.1434416717642826 0.03880555555555576 0.995275005097616 0.03880555555555576C0.924719449542061 0.03880555555555576 0.8294694495420609 0.08113888888888887 0.8294694495420609 0.2645833333333334C0.8294694495420609 0.34925000000000006 0.8682750050976162 0.5009444444444444 0.8964972273198386 0.620888888888889L1.016441671764282 1.1041944444444445C1.065830560653172 1.287638888888889 1.161080560653172 1.481666666666667 1.326886116208728 1.481666666666667C1.337469449542061 1.481666666666667 1.4256638939865045 1.481666666666667 1.4821083384309492 1.4322777777777778C1.3409972273198392 1.3970000000000002 1.3409972273198392 1.2629444444444444 1.3409972273198392 1.2629444444444444C1.3409972273198392 1.2170833333333335 1.372747227319838 1.1500555555555558 1.4644694495420598 1.1500555555555558C1.527969449542061 1.1500555555555558 1.6373305606531723 1.1994444444444445 1.6373305606531723 1.3370277777777777C1.6373305606531723 1.5169444444444447 1.432719449542061 1.559277777777778 1.3304138939865044 1.559277777777778C1.1363861162087279 1.559277777777778 1.0199694495420601 1.3864166666666669 0.9846916717642831 1.3193888888888892C0.9070805606531716 1.5310555555555556 0.7342194495420609 1.559277777777778 0.6460250050976164 1.559277777777778C0.29324722731983854 1.559277777777778 0.10274722731983843 1.0971388888888889 0.10274722731983843 1.016C0.10274722731983843 0.9807222222222225 0.1380250050976164 0.9807222222222225 0.15566389398650493 0.9807222222222225C0.20152500509761584 0.9807222222222225 0.20152500509761584 0.9842500000000003 0.21916389398650526 1.0406944444444446C0.3144138939865053 1.3440833333333333 0.49785833843094984 1.481666666666667 0.6389694495420608 1.481666666666667C0.7412750050976165 1.481666666666667 0.8083027828753941 1.400527777777778 0.8083027828753941 1.2594166666666666C0.8083027828753941 1.17475 0.7659694495420606 1.0018888888888888 0.7342194495420609 0.8713611111111113L0.653080560653172 0.5503333333333336C0.5966361162087273 0.3210277777777777 0.522552782875394 0.03880555555555576 0.3108861162087271 0.03880555555555576C0.30030278287539414 0.03880555555555576 0.21563611620872702 0.03880555555555576 0.15566389398650493 0.08819444444444446C0.26149722731983793 0.11641666666666683 0.29324722731983854 0.2046111111111113 0.29324722731983854 0.2575277777777778C0.29324722731983854 0.34925000000000006 0.21916389398650526 0.37041666666666684 0.17330278287539347 0.37041666666666684C0.085108338430949 0.37041666666666684 -0.00308610601349546 0.29633333333333356 -0.00308610601349546 0.17991666666666672C-0.00308610601349546 0.042333333333333556 0.14508056065317199 -0.03880555555555576 0.30735833843094973 -0.03880555555555576C0.47669167176428306 -0.03880555555555576 0.593108338430949 0.09525000000000006 0.653080560653172 0.2010833333333335C0.723636116208727 0 0.8964972273198386 -0.03880555555555576 0.9882194495420613 -0.03880555555555576C1.3515805606531721 -0.03880555555555576 1.5314972273198375 0.43391666666666673 1.5314972273198375 0.5044722222222222z

idk if that is helpful. Everything else I've tested yields the same error as before.

tdewolff commented 7 months ago

Thanks for bringing this to the attention. This looks likely to be a bug in the CFF (OpenType) font parser, specifically with stem hints, a relatively uncommon operator.

tdewolff commented 7 months ago

This was the fastest bug fix I've ever done! There was call stack related code for stem hints probably as a left-over of copying code from the subroutine operators. Can you please confirm that it works now?

RobinCoffee commented 7 months ago

Thanks! No errors now. Your library is awesome and looks like the best solution for client side LaTeX rendering. Really glad it works so well. I am a new programmer but I am happy I was able to contribute.