Compare commits

..

2 Commits

Author SHA1 Message Date
c384780028 Comments 2024-04-24 21:58:12 +04:00
9493b991d1 Comments and move stuff around 2024-04-24 21:54:35 +04:00
2 changed files with 77 additions and 72 deletions

View File

@ -17,9 +17,10 @@ import (
)
type FontAtlas struct {
Font *truetype.Font
Face font.Face
Img *image.RGBA
Font *truetype.Font
Face font.Face
Img *image.RGBA
// A map version of nset (https://github.com/bloeys/nset) would be amazing here
Glyphs map[rune]FontAtlasGlyph
//SpaceAdvance is the advance of a space char
@ -63,73 +64,7 @@ func NewFontAtlasFromFile(fontFile string, fontOptions *truetype.Options) (*Font
return NewFontAtlasFromFont(f, face, uint(fontOptions.Size))
}
func calcNeededAtlasSize(glyphs []rune, face font.Face, charPaddingXFixed, charPaddingYFixed fixed.Int26_6) (atlasSizeX, atlasSizeY int) {
//Calculate needed atlas size
atlasSizeX = 512
atlasSizeY = 512
largestLineDescent := fixed.I(0)
spaceAdv, _ := face.GlyphAdvance(' ')
lineHeight := face.Metrics().Height
foundAtlasSize := false
for !foundAtlasSize {
foundAtlasSize = true
dotX := spaceAdv + charPaddingXFixed
dotY := lineHeight
atlasSizeXFixed := fixed.I(atlasSizeX)
atlasSizeYFixed := fixed.I(atlasSizeY)
for i := 0; i < len(glyphs); i++ {
//Prepare all glyph metrics
g := glyphs[i]
gBounds, _, _ := face.GlyphBounds(g)
bearingXFixed := gBounds.Min.X
gWidthFixed := gBounds.Max.X - gBounds.Min.X
descentAbsFixed := absI26_6(gBounds.Max.Y)
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 we have no more space go to next line
if dotX+distToMoveX >= atlasSizeXFixed {
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+charPaddingYFixed >= atlasSizeYFixed {
atlasSizeX *= 2
atlasSizeY *= 2
foundAtlasSize = false
break
}
}
dotX += distToMoveX
}
}
return atlasSizeX, atlasSizeY
}
// NewFontAtlasFromFile uses the passed font to produce a font texture atlas containing
// NewFontAtlasFromFont uses the passed font to produce a font texture atlas containing
// all its characters using the specified options. The atlas uses equally sized tiles
// such that all characters use an equal horizontal/vertical on the atlas.
// If the character is smaller than the tile then the rest of the tile is empty.
@ -277,6 +212,72 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo
return atlas, nil
}
func calcNeededAtlasSize(glyphs []rune, face font.Face, charPaddingXFixed, charPaddingYFixed fixed.Int26_6) (atlasSizeX, atlasSizeY int) {
//Calculate needed atlas size
atlasSizeX = 512
atlasSizeY = 512
largestLineDescent := fixed.I(0)
spaceAdv, _ := face.GlyphAdvance(' ')
lineHeight := face.Metrics().Height
foundAtlasSize := false
for !foundAtlasSize {
foundAtlasSize = true
dotX := spaceAdv + charPaddingXFixed
dotY := lineHeight
atlasSizeXFixed := fixed.I(atlasSizeX)
atlasSizeYFixed := fixed.I(atlasSizeY)
for i := 0; i < len(glyphs); i++ {
//Prepare all glyph metrics
g := glyphs[i]
gBounds, _, _ := face.GlyphBounds(g)
bearingXFixed := gBounds.Min.X
gWidthFixed := gBounds.Max.X - gBounds.Min.X
descentAbsFixed := absI26_6(gBounds.Max.Y)
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 we have no more space go to next line
if dotX+distToMoveX >= atlasSizeXFixed {
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+charPaddingYFixed >= atlasSizeYFixed {
atlasSizeX *= 2
atlasSizeY *= 2
foundAtlasSize = false
break
}
}
dotX += distToMoveX
}
}
return atlasSizeX, atlasSizeY
}
func drawRectOutline(img *image.RGBA, rect image.Rectangle, color color.NRGBA) {
rowPixCount := img.Stride / 4

View File

@ -131,9 +131,13 @@ var (
yOff float32 = 0
)
// @TODO: Convert most operations to use glyphGrid instead of drawing directly to glyphRend
// @TODO: Implement SDF glyph rendering
/*
@TODO list:
- Must convert operations to use glyphGrid instead of drawing directly to glyphRend
- Since we are mid transition things like syntax highlighting and RTL are broken
- Syntax highlighting should now either use ANSI codes for colors or write to the grid with proper values
*/
func main() {
err := engine.Init()