Skip to content

Commit

Permalink
Improve LaTeX formula rendering e.g. inside a text box; allow differe…
Browse files Browse the repository at this point in the history
…nt fonts for LaTeX formulas
  • Loading branch information
tdewolff committed Nov 17, 2022
1 parent c189d09 commit dbbe106
Show file tree
Hide file tree
Showing 11 changed files with 288 additions and 96 deletions.
4 changes: 2 additions & 2 deletions font.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ func (family *FontFamily) Face(size float64, col color.Color, style FontStyle, v
type FontFace struct {
Font *Font

Size float64 // in pt
Size float64 // in mm
Style FontStyle
Variant FontVariant

Expand Down Expand Up @@ -508,7 +508,7 @@ func (face *FontFace) Metrics() FontMetrics {
// PPEM returns the pixels-per-EM for a given resolution of the font face.
func (face *FontFace) PPEM(resolution Resolution) uint16 {
// ppem is for hinting purposes only, this does not influence glyph advances
return uint16(resolution.DPMM() * face.Size)
return uint16(resolution.DPMM() * face.mmPerEm)
}

// LineHeight returns the height (ascent+descent) of a line.
Expand Down
65 changes: 65 additions & 0 deletions font/sfnt.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,71 @@ func (sfnt *SFNT) GlyphVerticalAdvance(glyphID uint16) uint16 {
return sfnt.Vmtx.Advance(glyphID)
}

type boundsPather struct {
xmin, ymin, xmax, ymax float64
}

func (p *boundsPather) MoveTo(x, y float64) {
p.xmin = math.Min(p.xmin, x)
p.ymin = math.Min(p.ymin, y)
p.xmax = math.Max(p.xmax, x)
p.ymax = math.Max(p.ymax, y)
}

func (p *boundsPather) LineTo(x, y float64) {
p.xmin = math.Min(p.xmin, x)
p.ymin = math.Min(p.ymin, y)
p.xmax = math.Max(p.xmax, x)
p.ymax = math.Max(p.ymax, y)
}

func (p *boundsPather) QuadTo(cpx, cpy, x, y float64) {
p.xmin = math.Min(p.xmin, cpx)
p.ymin = math.Min(p.ymin, cpy)
p.xmax = math.Max(p.xmax, cpx)
p.ymax = math.Max(p.ymax, cpy)
p.xmin = math.Min(p.xmin, x)
p.ymin = math.Min(p.ymin, y)
p.xmax = math.Max(p.xmax, x)
p.ymax = math.Max(p.ymax, y)
}

func (p *boundsPather) CubeTo(cp1x, cp1y, cp2x, cp2y, x, y float64) {
p.xmin = math.Min(p.xmin, cp1x)
p.ymin = math.Min(p.ymin, cp1y)
p.xmax = math.Max(p.xmax, cp1x)
p.ymax = math.Max(p.ymax, cp1y)
p.xmin = math.Min(p.xmin, cp2x)
p.ymin = math.Min(p.ymin, cp2y)
p.xmax = math.Max(p.xmax, cp2x)
p.ymax = math.Max(p.ymax, cp2y)
p.xmin = math.Min(p.xmin, x)
p.ymin = math.Min(p.ymin, y)
p.xmax = math.Max(p.xmax, x)
p.ymax = math.Max(p.ymax, y)
}

func (p *boundsPather) Close() {
}

// GlyphBounds returns the bounding rectangle (xmin,ymin,xmax,ymax) of the glyph.
func (sfnt *SFNT) GlyphBounds(glyphID uint16) (int16, int16, int16, int16, error) {
if sfnt.IsTrueType {
contour, err := sfnt.Glyf.Contour(glyphID, 0)
if err != nil {
return 0, 0, 0, 0, err
}
return contour.XMin, contour.YMin, contour.XMax, contour.YMax, nil
} else if sfnt.IsCFF {
p := &boundsPather{}
if err := sfnt.CFF.ToPath(p, glyphID, 0, 0, 0, 1.0, NoHinting); err != nil {
return 0, 0, 0, 0, err
}
return int16(p.xmin), int16(p.ymin), int16(math.Ceil(p.xmax)), int16(math.Ceil(p.ymax)), nil
}
return 0, 0, 0, 0, fmt.Errorf("only TrueType is supported")
}

// Kerning returns the kerning between two glyphs, i.e. the advance correction for glyph pairs.
func (sfnt *SFNT) Kerning(left, right uint16) int16 {
if sfnt.Kern == nil {
Expand Down
2 changes: 1 addition & 1 deletion font/sfnt_cff.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func (cff *cffTable) ToPath(p Pather, glyphID, ppem uint16, x, y int32, f float6
f /= float64(1 << 16) // correct back

hints := 0
stack := []int32{} // TODO: may overflow?t
stack := []int32{} // TODO: may overflow?
firstOperator := true
callStack := []*BinaryReader{}
r := NewBinaryReader(charString)
Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ require (
github.com/benoitkugler/textlayout v0.1.3
github.com/benoitkugler/textprocessing v0.0.2
github.com/dsnet/compress v0.0.1
github.com/go-fonts/dejavu v0.1.0
github.com/go-fonts/latin-modern v0.2.0
github.com/go-fonts/liberation v0.2.0
github.com/go-fonts/stix v0.1.0
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220622232848-a6c407ee30a0
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81
Expand All @@ -18,6 +22,7 @@ require (
github.com/paulmach/osm v0.5.0
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/tdewolff/argp v0.0.0-20221007181215-ebef9ed8a560
github.com/tdewolff/minify v2.3.6+incompatible
github.com/tdewolff/minify/v2 v2.12.4
github.com/tdewolff/parse/v2 v2.6.4
github.com/tdewolff/test v1.0.7
Expand All @@ -42,7 +47,6 @@ require (
github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 // indirect
github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
github.com/gioui/uax v0.2.1-0.20220325163150-e3d987515a12 // indirect
github.com/go-fonts/liberation v0.2.0 // indirect
github.com/go-pdf/fpdf v0.6.0 // indirect
github.com/go-text/typesetting v0.0.0-20220411150340-35994bc27a7b // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
Expand All @@ -53,7 +57,6 @@ require (
github.com/srwiley/oksvg v0.0.0-20220128195007-1f435e4c2b44 // indirect
github.com/srwiley/rasterx v0.0.0-20220615024203-67b7089efd25 // indirect
github.com/stretchr/testify v1.7.3 // indirect
github.com/tdewolff/minify v2.3.6+incompatible // indirect
github.com/tdewolff/parse v2.3.4+incompatible // indirect
github.com/tevino/abool v1.2.0 // indirect
github.com/yuin/goldmark v1.4.12 // indirect
Expand Down
13 changes: 1 addition & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ github.com/go-fonts/latin-modern v0.2.0 h1:5/Tv1Ek/QCr20C6ZOz15vw3g7GELYL98KWr8H
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
github.com/go-fonts/liberation v0.2.0 h1:jAkAWJP4S+OsrPLZM4/eC9iW7CtHy+HBXrEwZXWo5VM=
github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
github.com/go-fonts/stix v0.1.0 h1:UlZlgrvvmT/58o573ot7NFw0vZasZ5I6bcIft/oMdgg=
github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY=
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk=
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
Expand Down Expand Up @@ -367,24 +368,14 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F
github.com/stretchr/testify v1.7.3 h1:dAm0YRdRQlWojc3CrCRgPBzG5f941d0zvAKu7qY4e+I=
github.com/stretchr/testify v1.7.3/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tdewolff/argp v0.0.0-20220613210115-e74597c005ab h1:72GI+7FdJbl+zfj2ycchJRXZ4AXBjEkZEnWCD8WY/b4=
github.com/tdewolff/argp v0.0.0-20220613210115-e74597c005ab/go.mod h1:fF+gnKbmf3iMG+ErLiF+orMU/InyZIEnKVVigUjfriw=
github.com/tdewolff/argp v0.0.0-20221007181215-ebef9ed8a560 h1:Eq0xE0v77tO/J0pb1QiQ4o5zcETjz/IUAA/j++D/DHU=
github.com/tdewolff/argp v0.0.0-20221007181215-ebef9ed8a560/go.mod h1:fF+gnKbmf3iMG+ErLiF+orMU/InyZIEnKVVigUjfriw=
github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo=
github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs=
github.com/tdewolff/minify/v2 v2.11.10 h1:2tk9nuKfc8YOTD8glZ7JF/VtE8W5HOgmepWdjcPtRro=
github.com/tdewolff/minify/v2 v2.11.10/go.mod h1:dHOS3dk+nJ0M3q3uM3VlNzTb70cou+ov0ki7C4PAFgM=
github.com/tdewolff/minify/v2 v2.12.2 h1:AKIoVwJj/HgBm+d/fPqpEZ31EtCM5FJfJNGagdR9Ecg=
github.com/tdewolff/minify/v2 v2.12.2/go.mod h1:p5pwbvNs1ghbFED/ZW1towGsnnWwzvM8iz8l0eURi9g=
github.com/tdewolff/minify/v2 v2.12.4 h1:kejsHQMM17n6/gwdw53qsi6lg0TGddZADVyQOz1KMdE=
github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk=
github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
github.com/tdewolff/parse/v2 v2.6.0 h1:f2D7w32JtqjCv6SczWkfwK+m15et42qEtDnZXHoNY70=
github.com/tdewolff/parse/v2 v2.6.0/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/parse/v2 v2.6.3 h1:O5rshbkaRmpRtD7k2lG65bEJpcfUMNg5Cx2uRKWVsI8=
github.com/tdewolff/parse/v2 v2.6.3/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
github.com/tdewolff/parse/v2 v2.6.4 h1:KCkDvNUMof10e3QExio9OPZJT8SbdKojLBumw8YZycQ=
github.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
Expand Down Expand Up @@ -600,8 +591,6 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
Expand Down
Loading

0 comments on commit dbbe106

Please sign in to comment.