mirror of https://github.com/liamg/aminal.git
Fixed render issues with cached rectangles and fixed powerline font rendering
This commit is contained in:
parent
067966e3dc
commit
3e6b7e4f14
|
@ -203,6 +203,21 @@ func (f *Font) Size(text string) (float32, float32) {
|
||||||
return width, height
|
return width, height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func(f *Font) MaxSize() (float32, float32){
|
||||||
|
b:= f.ttf.Bounds(fixed.Int26_6(f.scale))
|
||||||
|
return float32(b.Max.X - b.Min.X),float32(b.Max.Y - b.Min.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(f *Font) MinY() float32 {
|
||||||
|
b:= f.ttf.Bounds(fixed.Int26_6(f.scale))
|
||||||
|
return float32(b.Min.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func(f *Font) MaxY() float32 {
|
||||||
|
b:= f.ttf.Bounds(fixed.Int26_6(f.scale))
|
||||||
|
return float32(b.Max.Y)
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Font) GetRune(r rune) (*character, error) {
|
func (f *Font) GetRune(r rune) (*character, error) {
|
||||||
|
|
||||||
cc, ok := f.characters[r]
|
cc, ok := f.characters[r]
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
|
|
||||||
"github.com/go-gl/gl/all-core/gl"
|
"github.com/go-gl/gl/all-core/gl"
|
||||||
"github.com/golang/freetype/truetype"
|
"github.com/golang/freetype/truetype"
|
||||||
"golang.org/x/image/font"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type character struct {
|
type character struct {
|
||||||
|
@ -37,16 +36,7 @@ func LoadTrueTypeFont(program uint32, r io.Reader, scale float32) (*Font, error)
|
||||||
}
|
}
|
||||||
f.SetColor(1.0, 1.0, 1.0, 1.0) //set default white
|
f.SetColor(1.0, 1.0, 1.0, 1.0) //set default white
|
||||||
|
|
||||||
sample := "abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ█"
|
_, h := f.MaxSize()
|
||||||
|
|
||||||
ttfFace := truetype.NewFace(f.ttf, &truetype.Options{
|
|
||||||
Size: float64(f.scale),
|
|
||||||
DPI: DPI,
|
|
||||||
Hinting: font.HintingFull,
|
|
||||||
})
|
|
||||||
|
|
||||||
_, h := f.Size(sample)
|
|
||||||
f.linePadding = h - float32(ttfFace.Metrics().Height>>6)
|
|
||||||
f.lineHeight = h
|
f.lineHeight = h
|
||||||
|
|
||||||
gl.BindTexture(gl.TEXTURE_2D, 0)
|
gl.BindTexture(gl.TEXTURE_2D, 0)
|
||||||
|
|
23
gui/fonts.go
23
gui/fonts.go
|
@ -12,12 +12,12 @@ func (gui *GUI) getPackedFont(name string) (*glfont.Font, error) {
|
||||||
box := packr.NewBox("./packed-fonts")
|
box := packr.NewBox("./packed-fonts")
|
||||||
fontBytes, err := box.MustBytes(name)
|
fontBytes, err := box.MustBytes(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Packaged font '%s' could not be read: %s", name, err)
|
return nil, fmt.Errorf("packaged font '%s' could not be read: %s", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
font, err := glfont.LoadFont(bytes.NewReader(fontBytes), gui.fontScale, gui.width, gui.height)
|
font, err := glfont.LoadFont(bytes.NewReader(fontBytes), gui.fontScale, gui.width, gui.height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Font '%s' failed to load: %v", name, err)
|
return nil, fmt.Errorf("font '%s' failed to load: %v", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return font, nil
|
return font, nil
|
||||||
|
@ -25,30 +25,21 @@ func (gui *GUI) getPackedFont(name string) (*glfont.Font, error) {
|
||||||
|
|
||||||
func (gui *GUI) loadFonts() error {
|
func (gui *GUI) loadFonts() error {
|
||||||
|
|
||||||
defaultFont, err := gui.getPackedFont("Hack-Regular.ttf")
|
// from https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/Hack
|
||||||
|
|
||||||
|
defaultFont, err := gui.getPackedFont("Hack Regular Nerd Font Complete.ttf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
boldFont, err := gui.getPackedFont("Hack-Bold.ttf")
|
boldFont, err := gui.getPackedFont("Hack Bold Nerd Font Complete.ttf")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.fontMap = NewFontMap(defaultFont, boldFont)
|
gui.fontMap = NewFontMap(defaultFont, boldFont)
|
||||||
|
|
||||||
// add special font usage here
|
// add special non-ascii fonts here
|
||||||
|
|
||||||
noto, err := gui.getPackedFont("NotoEmoji-Regular.ttf")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// misc symbols, lightning bolt etc.
|
|
||||||
gui.fontMap.setOverrideRange(0x2600, 0x26FF, noto)
|
|
||||||
|
|
||||||
// emoji
|
|
||||||
gui.fontMap.setOverrideRange(0x1F600, 0x1F64F, noto)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
26
gui/gui.go
26
gui/gui.go
|
@ -203,15 +203,11 @@ func (gui *GUI) Render() error {
|
||||||
for x := 0; x < colCount; x++ {
|
for x := 0; x < colCount; x++ {
|
||||||
|
|
||||||
cell := defaultCell
|
cell := defaultCell
|
||||||
hasText := false
|
|
||||||
|
|
||||||
if y < len(lines) {
|
if y < len(lines) {
|
||||||
cells := lines[y].Cells()
|
cells := lines[y].Cells()
|
||||||
if x < len(cells) {
|
if x < len(cells) {
|
||||||
cell = cells[x]
|
cell = cells[x]
|
||||||
if cell.Rune() != 0 && cell.Rune() != 32 {
|
|
||||||
hasText = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,12 +226,28 @@ func (gui *GUI) Render() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.renderer.DrawCellBg(cell, uint(x), uint(y), cursor, colour, false)
|
gui.renderer.DrawCellBg(cell, uint(x), uint(y), cursor, colour, false)
|
||||||
|
gui.renderer.DrawCellImage(cell, uint(x), uint(y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for y := 0; y < lineCount; y++ {
|
||||||
|
for x := 0; x < colCount; x++ {
|
||||||
|
|
||||||
|
cell := defaultCell
|
||||||
|
hasText := false
|
||||||
|
|
||||||
|
if y < len(lines) {
|
||||||
|
cells := lines[y].Cells()
|
||||||
|
if x < len(cells) {
|
||||||
|
cell = cells[x]
|
||||||
|
if cell.Rune() != 0 && cell.Rune() != 32 {
|
||||||
|
hasText = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if hasText {
|
if hasText {
|
||||||
gui.renderer.DrawCellText(cell, uint(x), uint(y), 1.0, nil)
|
gui.renderer.DrawCellText(cell, uint(x), uint(y), 1.0, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.renderer.DrawCellImage(cell, uint(x), uint(y))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -48,15 +48,20 @@ func (r *OpenGLRenderer) CellHeight() float32 {
|
||||||
return r.cellHeight
|
return r.cellHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *OpenGLRenderer) Clean() {
|
||||||
|
r.rectangles = map[[2]uint]*rectangle{}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *OpenGLRenderer) newRectangle(x float32, y float32, colourAttr uint32) *rectangle {
|
func (r *OpenGLRenderer) newRectangle(x float32, y float32, colourAttr uint32) *rectangle {
|
||||||
|
|
||||||
halfAreaWidth := float32(r.areaWidth / 2)
|
halfAreaWidth := float32(r.areaWidth / 2)
|
||||||
halfAreaHeight := float32(r.areaHeight / 2)
|
halfAreaHeight := float32(r.areaHeight / 2)
|
||||||
|
|
||||||
|
|
||||||
x = (x - halfAreaWidth) / halfAreaWidth
|
x = (x - halfAreaWidth) / halfAreaWidth
|
||||||
y = -(y - halfAreaHeight) / halfAreaHeight
|
y = -(y - ( halfAreaHeight)) / halfAreaHeight
|
||||||
w := r.cellWidth / halfAreaWidth
|
w := r.cellWidth / halfAreaWidth
|
||||||
h := r.cellHeight / halfAreaHeight
|
h := (r.cellHeight ) / halfAreaHeight
|
||||||
|
|
||||||
rect := &rectangle{
|
rect := &rectangle{
|
||||||
points: []float32{
|
points: []float32{
|
||||||
|
@ -158,32 +163,26 @@ func (r *OpenGLRenderer) SetArea(areaX int, areaY int, areaWidth int, areaHeight
|
||||||
r.areaX = areaX
|
r.areaX = areaX
|
||||||
r.areaY = areaY
|
r.areaY = areaY
|
||||||
f := r.fontMap.GetFont('X')
|
f := r.fontMap.GetFont('X')
|
||||||
|
_, r.cellHeight = f.MaxSize()
|
||||||
r.cellWidth, _ = f.Size("X")
|
r.cellWidth, _ = f.Size("X")
|
||||||
r.cellHeight = f.LineHeight() // vertical padding
|
//= f.LineHeight() // includes vertical padding
|
||||||
r.termCols = uint(math.Floor(float64(float32(r.areaWidth) / r.cellWidth)))
|
r.termCols = uint(math.Floor(float64(float32(r.areaWidth) / r.cellWidth)))
|
||||||
r.termRows = uint(math.Floor(float64(float32(r.areaHeight) / r.cellHeight)))
|
r.termRows = uint(math.Floor(float64(float32(r.areaHeight) / r.cellHeight)))
|
||||||
r.rectangles = map[[2]uint]*rectangle{}
|
r.rectangles = map[[2]uint]*rectangle{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *OpenGLRenderer) getRectangle(col uint, row uint) *rectangle {
|
func (r *OpenGLRenderer) getRectangle(col uint, row uint) *rectangle {
|
||||||
if rect, ok := r.rectangles[[2]uint{col, row}]; ok {
|
|
||||||
return rect
|
|
||||||
}
|
|
||||||
return r.generateRectangle(col, row)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *OpenGLRenderer) generateRectangle(col uint, line uint) *rectangle {
|
rect, ok := r.rectangles[[2]uint{col, row}]
|
||||||
|
|
||||||
rect, ok := r.rectangles[[2]uint{col, line}]
|
|
||||||
if ok {
|
if ok {
|
||||||
rect.Free()
|
rect.Free()
|
||||||
}
|
}
|
||||||
|
|
||||||
// rounding to whole pixels makes everything nice
|
|
||||||
x := float32(float32(col) * r.cellWidth)
|
x := float32(float32(col) * r.cellWidth)
|
||||||
y := float32((float32(line) * r.cellHeight)) + r.cellHeight
|
y := float32(float32(row) * r.cellHeight) + r.cellHeight
|
||||||
r.rectangles[[2]uint{col, line}] = r.newRectangle(x, y, r.colourAttr)
|
|
||||||
return r.rectangles[[2]uint{col, line}]
|
r.rectangles[[2]uint{col, row}] = r.newRectangle(x, y, r.colourAttr)
|
||||||
|
return r.rectangles[[2]uint{col, row}]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *OpenGLRenderer) DrawCursor(col uint, row uint, colour config.Colour) {
|
func (r *OpenGLRenderer) DrawCursor(col uint, row uint, colour config.Colour) {
|
||||||
|
@ -240,7 +239,7 @@ func (r *OpenGLRenderer) DrawCellText(cell buffer.Cell, col uint, row uint, alph
|
||||||
f.SetColor(fg[0], fg[1], fg[2], alpha)
|
f.SetColor(fg[0], fg[1], fg[2], alpha)
|
||||||
|
|
||||||
x := float32(r.areaX) + float32(col)*r.cellWidth
|
x := float32(r.areaX) + float32(col)*r.cellWidth
|
||||||
y := float32(r.areaY) + (float32(row+1) * r.cellHeight) - (f.LinePadding())
|
y := float32(r.areaY) + (float32(row+1) * r.cellHeight) + f.MinY()
|
||||||
|
|
||||||
f.Print(x, y, string(cell.Rune()))
|
f.Print(x, y, string(cell.Rune()))
|
||||||
}
|
}
|
||||||
|
@ -289,8 +288,8 @@ func (r *OpenGLRenderer) DrawCellImage(cell buffer.Cell, col uint, row uint) {
|
||||||
r.textureMap[img] = tex
|
r.textureMap[img] = tex
|
||||||
}
|
}
|
||||||
|
|
||||||
var w float32 = float32(img.Bounds().Size().X)
|
var w = float32(img.Bounds().Size().X)
|
||||||
var h float32 = float32(img.Bounds().Size().Y)
|
var h = float32(img.Bounds().Size().Y)
|
||||||
|
|
||||||
var readFboId uint32
|
var readFboId uint32
|
||||||
gl.GenFramebuffers(1, &readFboId)
|
gl.GenFramebuffers(1, &readFboId)
|
||||||
|
|
|
@ -79,20 +79,23 @@ DONE:
|
||||||
addLine()
|
addLine()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gui.renderer.Clean()
|
||||||
|
|
||||||
|
bg := [3]float32{0, 0, 0}
|
||||||
|
|
||||||
for hx := col; hx < col+uint16(longestLine)+2; hx++ {
|
for hx := col; hx < col+uint16(longestLine)+2; hx++ {
|
||||||
for hy := row - 1; hy < row+uint16(len(lines))+1; hy++ {
|
for hy := row - 1; hy < row+uint16(len(lines))+1; hy++ {
|
||||||
gui.renderer.DrawCellBg(buffer.NewBackgroundCell([3]float32{0, 0, 0}), uint(hx), uint(hy), false, nil, true)
|
gui.renderer.DrawCellBg(buffer.NewBackgroundCell(bg), uint(hx), uint(hy), false, nil , true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x := (float32(col) * gui.renderer.cellWidth)
|
x := float32(col) * gui.renderer.cellWidth
|
||||||
|
|
||||||
f := gui.fontMap.GetFont('X')
|
f := gui.fontMap.GetFont('X')
|
||||||
|
|
||||||
f.SetColor(0.2, 1, 0.2, 1)
|
f.SetColor(0.2, 1, 0.2, 1)
|
||||||
|
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
y := (float32(row+1+uint16(i)) * gui.renderer.cellHeight) - (f.LinePadding())
|
y := float32(row+1+uint16(i)) * gui.renderer.cellHeight
|
||||||
f.Print(x, y, fmt.Sprintf(" %s", line))
|
f.Print(x, y, fmt.Sprintf(" %s", line))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue