mirror of
				https://github.com/KevinMidboe/motdGO.git
				synced 2025-10-29 17:50:24 +00:00 
			
		
		
		
	cleaning and improving
This commit is contained in:
		
							
								
								
									
										166
									
								
								font.go
									
									
									
									
									
								
							
							
						
						
									
										166
									
								
								font.go
									
									
									
									
									
								
							| @@ -1,151 +1,35 @@ | |||||||
|  | // Explanation of the .flf file header | ||||||
|  | // THE HEADER LINE | ||||||
|  | //  | ||||||
|  | // The header line gives information about the FIGfont.  Here is an example | ||||||
|  | // showing the names of all parameters: | ||||||
|  | //  | ||||||
|  | //           flf2a$ 6 5 20 15 3 0 143 229    NOTE: The first five characters in | ||||||
|  | //             |  | | | |  |  | |  |   |     the entire file must be "flf2a". | ||||||
|  | //            /  /  | | |  |  | |  |   \ | ||||||
|  | //   Signature  /  /  | |  |  | |   \   Codetag_Count | ||||||
|  | //     Hardblank  /  /  |  |  |  \   Full_Layout* | ||||||
|  | //          Height  /   |  |   \  Print_Direction | ||||||
|  | //          Baseline   /    \   Comment_Lines | ||||||
|  | //           Max_Length      Old_Layout* | ||||||
|  | //  | ||||||
|  | //   * The two layout parameters are closely related and fairly complex. | ||||||
|  | //       (See "INTERPRETATION OF LAYOUT PARAMETERS".) | ||||||
|  | // | ||||||
| package figlet4go | package figlet4go | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"errors" |  | ||||||
| 	"io/ioutil" |  | ||||||
| 	"os" |  | ||||||
| 	"path/filepath" |  | ||||||
| 	"strconv" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| const defaultFontName string = "standard" |  | ||||||
|  |  | ||||||
| // Represents a single font | // Represents a single font | ||||||
| type font struct { | type font struct { | ||||||
|  | 	// Hardblank symbol | ||||||
| 	hardblank string | 	hardblank string | ||||||
|  | 	// Height of one char | ||||||
| 	height    int | 	height    int | ||||||
|  | 	// | ||||||
| 	fontSlice []string | 	fontSlice []string | ||||||
| } | } | ||||||
|  |  | ||||||
| // Holds the fonts | func (f *font) getCharSlice() []string { | ||||||
| type fontManager struct { | 	// TODO here will be the logic of NewAsciiChar | ||||||
| 	// Font libraries | 	return []string{}  | ||||||
| 	fontLib map[string]*font | } | ||||||
| 	// Font name to path |  | ||||||
| 	fontList map[string]string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Create new fontmanager |  | ||||||
| func newFontManager() *fontManager { |  | ||||||
| 	this := &fontManager{} |  | ||||||
|  |  | ||||||
| 	this.fontLib = make(map[string]*font) |  | ||||||
| 	this.fontList = make(map[string]string) |  | ||||||
| 	this.loadBuildInFont() |  | ||||||
|  |  | ||||||
| 	return this |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Load all font *.flf files in the fontPath recursivly |  | ||||||
| func (this *fontManager) loadFont(fontPath string) error { |  | ||||||
|  |  | ||||||
| 	return filepath.Walk(fontPath, func(path string, info os.FileInfo, err error) error { |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if info.IsDir() || !strings.HasSuffix(info.Name(), ".flf") { |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		fontName := strings.TrimSuffix(info.Name(), ".flf") |  | ||||||
| 		this.fontList[fontName] = path |  | ||||||
| 		return nil |  | ||||||
| 	}) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Load the default font |  | ||||||
| func (this *fontManager) loadBuildInFont() error { |  | ||||||
|  |  | ||||||
| 	// Default fonts to load |  | ||||||
| 	defaultFonts := []string{ |  | ||||||
| 		"standard", |  | ||||||
| 		"larry3d", |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Load each default font |  | ||||||
| 	for _, name := range defaultFonts { |  | ||||||
| 		fontStr, err := Asset(name + ".flf") |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		font, err := this.parseFontContent(string(fontStr)) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
| 		this.fontLib[name] = font |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Load a font from disk |  | ||||||
| func (this *fontManager) loadDiskFont(fontName string) error { |  | ||||||
|  |  | ||||||
| 	fontFilePath, ok := this.fontList[fontName] |  | ||||||
| 	if !ok { |  | ||||||
| 		return errors.New("FontName Not Found.") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// read full file content |  | ||||||
| 	fileBuf, err := ioutil.ReadFile(fontFilePath) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	font, err := this.parseFontContent(string(fileBuf)) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	this.fontLib[fontName] = font |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Parse a font from a content string |  | ||||||
| func (this *fontManager) parseFontContent(cont string) (*font, error) { |  | ||||||
| 	lines := strings.Split(cont, "\n") |  | ||||||
| 	if len(lines) < 1 { |  | ||||||
| 		return nil, errors.New("font content error") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// flf2a$ 7 5 16 -1 12 |  | ||||||
| 	// Fender by Scooter 8/94 (jkratten@law.georgetown.edu) |  | ||||||
| 	// |  | ||||||
| 	// Explanation of first line: |  | ||||||
| 	// flf2 - "magic number" for file identification |  | ||||||
| 	// a    - should always be `a', for now |  | ||||||
| 	// $    - the "hardblank" -- prints as a blank, but can't be smushed |  | ||||||
| 	// 7    - height of a character |  | ||||||
| 	// 5    - height of a character, not including descenders |  | ||||||
| 	// 10   - max line length (excluding comment lines) + a fudge factor |  | ||||||
| 	// -1   - default smushmode for this font (like "-m 15" on command line) |  | ||||||
| 	// 12   - number of comment lines |  | ||||||
|  |  | ||||||
| 	header := strings.Split(lines[0], " ") |  | ||||||
|  |  | ||||||
| 	font := &font{} |  | ||||||
| 	font.hardblank = header[0][len(header[0])-1:] |  | ||||||
| 	font.height, _ = strconv.Atoi(header[1]) |  | ||||||
|  |  | ||||||
| 	commentEndLine, _ := strconv.Atoi(header[5]) |  | ||||||
| 	font.fontSlice = lines[commentEndLine+1:] |  | ||||||
|  |  | ||||||
| 	return font, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get a font by name |  | ||||||
| // Better error handling. Why is there one in the return if not used? |  | ||||||
| func (this *fontManager) getFont(fontName string) (*font, error) { |  | ||||||
| 	font, ok := this.fontLib[fontName] |  | ||||||
| 	if !ok { |  | ||||||
| 		err := this.loadDiskFont(fontName) |  | ||||||
| 		if err != nil { |  | ||||||
| 			font, _ := this.fontLib[defaultFontName] |  | ||||||
| 			return font, nil |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	font, _ = this.fontLib[fontName] |  | ||||||
| 	return font, nil |  | ||||||
| } |  | ||||||
							
								
								
									
										165
									
								
								fontmanager.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								fontmanager.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | |||||||
|  | package figlet4go | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"errors" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Default font if no other valid given | ||||||
|  | const defaultFont string = "standard" | ||||||
|  |  | ||||||
|  | // Extension of a font file | ||||||
|  | const extension string = "flf" | ||||||
|  |  | ||||||
|  | // Builtin fonts to load | ||||||
|  | var defaultFonts []string = []string{ | ||||||
|  | 	"standard", | ||||||
|  | 	"larry3d", | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Holds the available fonts | ||||||
|  | type fontManager struct { | ||||||
|  | 	// The already read fonts | ||||||
|  | 	fontLib map[string]*font | ||||||
|  | 	// The in given pathes found fonts | ||||||
|  | 	fontList map[string]string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Create a new fontmanagerM | ||||||
|  | func newFontManager() *fontManager { | ||||||
|  | 	fm := &fontManager{} | ||||||
|  | 	fm.fontLib = make(map[string]*font) | ||||||
|  | 	fm.fontList = make(map[string]string) | ||||||
|  | 	fm.loadBuildInFont() | ||||||
|  | 	return fm | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get a font by name | ||||||
|  | // Default font if no other font could be loaded | ||||||
|  | func (fm *fontManager) getFont(fontName string) *font { | ||||||
|  | 	// Get the font from the fontLib | ||||||
|  | 	_, ok := fm.fontLib[fontName] | ||||||
|  | 	// Font not found | ||||||
|  | 	if !ok { | ||||||
|  | 		// Try to load it from loaded fontList | ||||||
|  | 		err := fm.loadDiskFont(fontName) | ||||||
|  | 		// Font also not found here, use the default font | ||||||
|  | 		if err != nil { | ||||||
|  | 			fontName = defaultFont | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	return fm.fontLib[fontName] | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Loads all .flf files recursively in the fontPath path | ||||||
|  | // Saves the found font files in a map with the name as the key | ||||||
|  | // and the path as the value. Doesn't load them at this point | ||||||
|  | // for performance. Called in the AsciiRenderer | ||||||
|  | func (fm *fontManager) loadFontList(fontPath string) error { | ||||||
|  | 	// Walk through the path | ||||||
|  | 	return filepath.Walk(fontPath, func(path string, info os.FileInfo, err error) error { | ||||||
|  | 		// Return an error if occured | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		// If the current item is a directory or has not the correct suffix | ||||||
|  | 		if info.IsDir() || !strings.HasSuffix(info.Name(), "." + extension) { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 		// Extract the font name | ||||||
|  | 		fontName := strings.TrimSuffix(info.Name(), "." + extension) | ||||||
|  | 		// Save the font to the list | ||||||
|  | 		fm.fontList[fontName] = path | ||||||
|  |  | ||||||
|  | 		return nil | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Load a font from disk | ||||||
|  | // The font must be registered in the fontList | ||||||
|  | func (this *fontManager) loadDiskFont(fontName string) error { | ||||||
|  | 	// Get the fontpath | ||||||
|  | 	path, ok := this.fontList[fontName] | ||||||
|  | 	// Font is not registered | ||||||
|  | 	if !ok { | ||||||
|  | 		return errors.New("Font Not Found: " + fontName) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Read file contents | ||||||
|  | 	fontStr, err := ioutil.ReadFile(path) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Parse the file contents | ||||||
|  | 	font, err := parseFontContent(string(fontStr)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Register the font object in the fontLib | ||||||
|  | 	this.fontLib[fontName] = font | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Load the builtin fonts from the bindata.go file | ||||||
|  | // Load all fonts specified on top (defaultFonts) | ||||||
|  | func (fm *fontManager) loadBuildInFont() error { | ||||||
|  |  | ||||||
|  | 	// Load each default font | ||||||
|  | 	for _, name := range defaultFonts { | ||||||
|  | 		// Get Contents | ||||||
|  | 		fontStr, err := Asset(name + "." + extension) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		// Get the font | ||||||
|  | 		font, err := parseFontContent(string(fontStr)) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		// Register the font object in the fontLib | ||||||
|  | 		fm.fontLib[name] = font | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Parse a font from a content string | ||||||
|  | // Used to load fonts from disk and the builtin fonts | ||||||
|  | func parseFontContent(cont string) (*font, error) { | ||||||
|  | 	// Get all lines | ||||||
|  | 	lines := strings.Split(cont, "\n") | ||||||
|  |  | ||||||
|  | 	if len(lines) < 1 { | ||||||
|  | 		return nil, errors.New("Font content error") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Get the header metadata | ||||||
|  | 	header := strings.Split(lines[0], " ") | ||||||
|  |  | ||||||
|  | 	// Line end of the comment | ||||||
|  | 	commentEndLine, _ := strconv.Atoi(header[5]) | ||||||
|  |  | ||||||
|  | 	// Char height | ||||||
|  | 	height, _ := strconv.Atoi(header[1]) | ||||||
|  |  | ||||||
|  | 	// Initialize the font | ||||||
|  | 	font := &font{ | ||||||
|  | 		hardblank: header[0][len(header[0])-1:], | ||||||
|  | 		height: height, | ||||||
|  | 		fontSlice: lines[commentEndLine+1:], | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return font, nil | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								render.go
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								render.go
									
									
									
									
									
								
							| @@ -17,7 +17,7 @@ type RenderOptions struct { | |||||||
| // Sets the default font name | // Sets the default font name | ||||||
| func NewRenderOptions() *RenderOptions { | func NewRenderOptions() *RenderOptions { | ||||||
| 	return &RenderOptions{ | 	return &RenderOptions{ | ||||||
| 		FontName: defaultFontName, | 		FontName: defaultFont, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -36,7 +36,7 @@ func NewAsciiRender() *AsciiRender { | |||||||
|  |  | ||||||
| // Loading all *.flf font files recursively in a path | // Loading all *.flf font files recursively in a path | ||||||
| func (ar *AsciiRender) LoadFont(fontPath string) error { | func (ar *AsciiRender) LoadFont(fontPath string) error { | ||||||
| 	return ar.fontMgr.loadFont(fontPath) | 	return ar.fontMgr.loadFontList(fontPath) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Render a string with the default options | // Render a string with the default options | ||||||
| @@ -53,11 +53,8 @@ func (ar *AsciiRender) RenderOpts(str string, opt *RenderOptions) (string, error | |||||||
| 	colored := len(opt.FontColor) > 0 | 	colored := len(opt.FontColor) > 0 | ||||||
|  |  | ||||||
| 	// Load the font | 	// Load the font | ||||||
| 	font, err := ar.fontMgr.getFont(opt.FontName) | 	font := ar.fontMgr.getFont(opt.FontName) | ||||||
| 	if err != nil { | 	 | ||||||
| 		return "", err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Slice holding the chars | 	// Slice holding the chars | ||||||
| 	chars := []*AsciiChar{} | 	chars := []*AsciiChar{} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user