// Copyright (c) 2022 Sam Blenny // SPDX-License-Identifier: Apache-2.0 OR MIT // package main import ( "blitstr2/codegen/lib" . "blitstr2/codegen/lib" "fmt" "image" "image/png" "io/ioutil" "os" "strings" ) // Command line switch to confirm intent of writing output files const confirm = "--write" // Command line switch to enable debug output const debug = "--debug" // Change this to control the visibility of debug messages var enableDebug = false // Main: check for confirmation switch before writing files func main() { if len(os.Args) == 2 && os.Args[1] == confirm { codegen() } else if len(os.Args) == 3 && os.Args[1] == confirm && os.Args[2] == debug { enableDebug = true codegen() } else if len(os.Args) == 3 && os.Args[1] == debug && os.Args[2] == confirm { enableDebug = true codegen() } else { usage() } } // Generate rust source code files for fonts func codegen() { conf := NewConfig("config.json") fsList := conf.Fonts() var fdir []FontSummary var small_fdir []FontSummary var offsets []FontMap var small_offsets []FontMap var cur_address int = 0 var small_cur_address int = 0 for _, f := range fsList { // Find all the glyphs and pack them into a list of blit pattern objects pl := patternListFromSpriteSheet(f) // Make rust code for the blit pattern DATA array, plus an index list gs := NewGlyphSetFrom(pl, f) // Generate rust source code and write it to a file code := RenderFontFileTemplate(f, gs) fmt.Println("Writing to", f.RustOut) ioutil.WriteFile(f.RustOut, []byte(code), 0644) loader := RenderLoaderFileTemplate(f, gs) fmt.Println("Writing to", f.LoaderOut) ioutil.WriteFile(f.LoaderOut, []byte(loader), 0644) summary := lib.FontSummary{ Name: strings.ToLower(f.Name), Len: gs.GlyphsLen, } fdir = append(fdir, summary) if f.Small { small_fdir = append(small_fdir, summary) } offset := lib.FontMap{ Name: strings.ToUpper(f.Name) + "_OFFSET", Len: fmt.Sprintf("%x", cur_address), } offsets = append(offsets, offset) if f.Small { offset := lib.FontMap{ Name: strings.ToUpper(f.Name) + "_OFFSET", Len: fmt.Sprintf("%x", small_cur_address), } small_offsets = append(small_offsets, offset) } length := lib.FontMap{ Name: strings.ToUpper(f.Name) + "_LEN", Len: fmt.Sprintf("%x", gs.GlyphsLen*4), } offsets = append(offsets, length) if f.Small { small_offsets = append(small_offsets, length) } cur_address = cur_address + gs.GlyphsLen*4 if f.Small { small_cur_address = small_cur_address + gs.GlyphsLen*4 } } total := lib.FontMap{ Name: "FONT_TOTAL_LEN", Len: fmt.Sprintf("%x", cur_address), } offsets = append(offsets, total) small_total := lib.FontMap{ Name: "FONT_TOTAL_LEN", Len: fmt.Sprintf("%x", small_cur_address), } small_offsets = append(small_offsets, small_total) for _, fs := range fdir { fmt.Println(fs) } loadermod := RenderLoadermodTemplate(fdir, small_fdir) fmt.Println("Writing to", conf.GetLoaderMod()) ioutil.WriteFile(conf.GetLoaderMod(), []byte(loadermod), 0644) fontmap := RenderFontmapTemplate(offsets, small_offsets) fmt.Println("Writing to", conf.GetFontMap()) ioutil.WriteFile(conf.GetFontMap(), []byte(fontmap), 0644) } // Extract glyph sprites from a PNG grid and pack them into a list of blit pattern objects func patternListFromSpriteSheet(fs FontSpec) []BlitPattern { // Read glyphs from png file img := readPNGFile(fs.Sprites) var patternList []BlitPattern for _, cs := range fs.CSList { blitPattern := NewBlitPattern(img, fs, cs, enableDebug) patternList = append(patternList, blitPattern) } return patternList } // Read the specified PNG file and convert its data into an image object func readPNGFile(name string) image.Image { pngFile, err := os.Open(name) if err != nil { panic("unable to open png file") } img, err := png.Decode(pngFile) if err != nil { panic("unable to decode png file") } pngFile.Close() return img } // Print usage message func usage() { conf := NewConfig("config.json") fsList := conf.Fonts() u := RenderUsageTemplate(confirm, debug, fsList) fmt.Println(u) fmt.Println("Metafile: ", conf.GetLoaderMod()) fmt.Println("Metafile: ", conf.GetFontMap()) }