mirror of
https://github.com/bloeys/nterm.git
synced 2025-12-29 06:28:20 +00:00
Fix calcNeededAtlasSize
This commit is contained in:
@ -22,9 +22,10 @@ type FontAtlas struct {
|
||||
Img *image.RGBA
|
||||
Glyphs map[rune]FontAtlasGlyph
|
||||
|
||||
//SpaceAdvance is global to the atlas because we only support monospaced fonts
|
||||
//SpaceAdvance is the advance of a space char
|
||||
SpaceAdvance float32
|
||||
LineHeight float32
|
||||
//LineHeight is the height of metrics.Height
|
||||
LineHeight float32
|
||||
}
|
||||
|
||||
type FontAtlasGlyph struct {
|
||||
@ -68,12 +69,13 @@ func calcNeededAtlasSize(glyphs []rune, face font.Face, charPaddingXFixed, charP
|
||||
atlasSizeX = 512
|
||||
atlasSizeY = 512
|
||||
largestLineDescent := fixed.I(0)
|
||||
spaceAdv, _ := face.GlyphAdvance(' ')
|
||||
lineHeight := face.Metrics().Height
|
||||
foundAtlasSize := false
|
||||
for !foundAtlasSize {
|
||||
|
||||
foundAtlasSize = true
|
||||
dotX := charPaddingXFixed
|
||||
dotX := spaceAdv + charPaddingXFixed
|
||||
dotY := lineHeight
|
||||
atlasSizeXFixed := fixed.I(atlasSizeX)
|
||||
atlasSizeYFixed := fixed.I(atlasSizeY)
|
||||
@ -84,39 +86,43 @@ func calcNeededAtlasSize(glyphs []rune, face font.Face, charPaddingXFixed, charP
|
||||
gBounds, _, _ := face.GlyphBounds(g)
|
||||
bearingXFixed := gBounds.Min.X
|
||||
gWidthFixed := gBounds.Max.X - gBounds.Min.X
|
||||
descent := gBounds.Max.Y
|
||||
descentAbsFixed := absI26_6(gBounds.Max.Y)
|
||||
|
||||
if descent > largestLineDescent {
|
||||
largestLineDescent = descent
|
||||
if descentAbsFixed > largestLineDescent {
|
||||
largestLineDescent = descentAbsFixed
|
||||
}
|
||||
|
||||
//If bearing is negative this char might overlap with the previous one.
|
||||
//So we need to move the dot so the drawer won't overlap even after a negative offset
|
||||
if bearingXFixed < 0 {
|
||||
dotX += absI26_6(bearingXFixed)
|
||||
}
|
||||
|
||||
// Calculate distance dot will move after drawing. Advance normally if line has space,
|
||||
// otherwise go to next line and reset X position.
|
||||
distToMoveX := bearingXFixed + gWidthFixed + charPaddingXFixed
|
||||
|
||||
//If bearing is negative this char might overlap with the previous one.
|
||||
//So we need to move the dot so the drawer won't overlap even after a negative offset
|
||||
if bearingXFixed < 0 {
|
||||
distToMoveX += absI26_6(bearingXFixed)
|
||||
}
|
||||
|
||||
//If we hav eno more space go to next line
|
||||
//If we have no more space go to next line
|
||||
if dotX+distToMoveX >= atlasSizeXFixed {
|
||||
|
||||
dotX = distToMoveX
|
||||
dotX = charPaddingXFixed
|
||||
if bearingXFixed < 0 {
|
||||
dotX += absI26_6(bearingXFixed)
|
||||
}
|
||||
|
||||
dotY += lineHeight + fixed.I(largestLineDescent.Ceil()) + charPaddingYFixed
|
||||
largestLineDescent = 0
|
||||
|
||||
//If we have only one more empty line then resize to be safe against descents being clipped
|
||||
if dotY+lineHeight >= atlasSizeYFixed {
|
||||
if dotY+lineHeight+charPaddingYFixed >= atlasSizeYFixed {
|
||||
atlasSizeX *= 2
|
||||
atlasSizeY *= 2
|
||||
foundAtlasSize = false
|
||||
break
|
||||
}
|
||||
} else {
|
||||
dotX += distToMoveX
|
||||
}
|
||||
|
||||
dotX += distToMoveX
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +159,7 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo
|
||||
Glyphs: make(map[rune]FontAtlasGlyph, len(glyphs)),
|
||||
|
||||
SpaceAdvance: I26_6ToF32(spaceAdv),
|
||||
LineHeight: float32(lineHeight.Ceil()),
|
||||
LineHeight: I26_6ToF32(lineHeight),
|
||||
}
|
||||
|
||||
//Clear background to black
|
||||
|
||||
@ -188,9 +188,9 @@ func (gr *GlyphRend) drawRune(run *TextRun, i int, prevRune rune, screenPos, pos
|
||||
}
|
||||
}
|
||||
|
||||
func roundF32(x float32) float32 {
|
||||
return float32(math.Round(float64(x)))
|
||||
}
|
||||
// func roundF32(x float32) float32 {
|
||||
// return float32(math.Round(float64(x)))
|
||||
// }
|
||||
|
||||
// func ceilF32(x float32) float32 {
|
||||
// return float32(math.Ceil(float64(x)))
|
||||
|
||||
10
main.go
10
main.go
@ -15,6 +15,7 @@ import (
|
||||
"github.com/bloeys/nmage/renderer/rend3dgl"
|
||||
"github.com/bloeys/nmage/timing"
|
||||
nmageimgui "github.com/bloeys/nmage/ui/imgui"
|
||||
"github.com/bloeys/nterm/consts"
|
||||
"github.com/bloeys/nterm/glyphs"
|
||||
"github.com/golang/freetype/truetype"
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
@ -94,12 +95,15 @@ func (p *program) Init() {
|
||||
fmt.Printf("DPI: %f, font size: %d\n", dpi, p.FontSize)
|
||||
|
||||
w, h := p.win.SDLWin.GetSize()
|
||||
p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/alm-fixed.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h)
|
||||
p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/tajawal-regular-var.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h)
|
||||
// p.GlyphRend, err = glyphs.NewGlyphRend("./res/fonts/alm-fixed.ttf", &truetype.Options{Size: float64(p.FontSize), DPI: p.Dpi, SubPixelsX: subPixelX, SubPixelsY: subPixelY, Hinting: hinting}, w, h)
|
||||
if err != nil {
|
||||
panic("Failed to create atlas from font file. Err: " + err.Error())
|
||||
}
|
||||
|
||||
glyphs.SaveImgToPNG(p.GlyphRend.Atlas.Img, "./debug-atlas.png")
|
||||
if consts.Mode_Debug {
|
||||
glyphs.SaveImgToPNG(p.GlyphRend.Atlas.Img, "./debug-atlas.png")
|
||||
}
|
||||
|
||||
//Load resources
|
||||
p.gridMesh, err = meshes.NewMesh("grid", "./res/models/quad.obj", 0)
|
||||
@ -190,7 +194,7 @@ func (p *program) Update() {
|
||||
|
||||
var isDrawingBounds = false
|
||||
var drawManyLines = false
|
||||
var textToShow = "Hello there يا friend. اسمي عمر wow!"
|
||||
var textToShow = "Hello there يا friend. اسميعمر wow!"
|
||||
|
||||
var xOff float32 = 0
|
||||
var yOff float32 = 0
|
||||
|
||||
BIN
res/fonts/tajawal-regular-var.ttf
Executable file
BIN
res/fonts/tajawal-regular-var.ttf
Executable file
Binary file not shown.
Reference in New Issue
Block a user