From 9493b991d1d4ab17d6de6a7a6a6e5b577fbfc0bc Mon Sep 17 00:00:00 2001 From: bloeys Date: Wed, 24 Apr 2024 21:54:35 +0400 Subject: [PATCH] Comments and move stuff around --- glyphs/font_atlas.go | 141 ++++++++++++++++++++++--------------------- main.go | 2 - 2 files changed, 71 insertions(+), 72 deletions(-) diff --git a/glyphs/font_atlas.go b/glyphs/font_atlas.go index b47620a..1b0f5c4 100755 --- a/glyphs/font_atlas.go +++ b/glyphs/font_atlas.go @@ -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 diff --git a/main.go b/main.go index 75fb3ad..27b9c57 100755 --- a/main.go +++ b/main.go @@ -132,8 +132,6 @@ var ( ) // @TODO: Convert most operations to use glyphGrid instead of drawing directly to glyphRend -// @TODO: Implement SDF glyph rendering - func main() { err := engine.Init()