mirror of
https://github.com/bloeys/nterm.git
synced 2025-12-29 14:38:19 +00:00
Compare commits
2 Commits
2d3f89e290
...
c384780028
| Author | SHA1 | Date | |
|---|---|---|---|
| c384780028 | |||
| 9493b991d1 |
@ -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
|
||||
|
||||
8
main.go
8
main.go
@ -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()
|
||||
|
||||
Reference in New Issue
Block a user