xous-core/libs/blitstr2/codegen/lib/templates.go

197 lines
6.5 KiB
Go
Raw Normal View History

// Copyright (c) 2022 Sam Blenny
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
package lib
import (
"bytes"
"strings"
"text/template"
)
type FontSummary struct {
Name string
Len int
}
type FontMap struct {
Name string
Len string
}
// Render the command line usage message
func RenderUsageTemplate(confirm string, debug string, fonts []FontSpec) string {
context := usageTemplateContext{confirm, debug, fonts}
return renderTemplate(usageTemplate, "usage", context)
}
// Render rust source code for font file with index functions and static arrays
func RenderFontFileTemplate(f FontSpec, gs GlyphSet) string {
fname := strings.ToUpper(f.Name)
context := fontFileTemplateContext{f, gs, fname}
return renderTemplate(fontFileTemplate, "fontfile", context)
}
func RenderLoaderFileTemplate(f FontSpec, gs GlyphSet) string {
fname := strings.ToUpper(f.Name)
context := loaderFileTemplateContext{f, gs, fname}
return renderTemplate(loaderFileTemplate, "loaderfile", context)
}
func RenderFontmapTemplate(fd []FontMap, small_fd []FontMap) string {
context := fontmapTemplateContext{fd, small_fd}
return renderTemplate(fontmapTemplate, "fontmap", context)
}
func RenderLoadermodTemplate(fd []FontSummary, small_fd []FontSummary) string {
context := loadermodTemplateContext{fd, small_fd}
return renderTemplate(loadermodTemplate, "loadermod", context)
}
// Holds data for rendering usageTemplate
type usageTemplateContext struct {
Confirm string
Debug string
Fonts []FontSpec
}
// Holds data for rendering fontFileTemplate
type fontFileTemplateContext struct {
Font FontSpec
GS GlyphSet
FontName string
}
// Holds data for rendering loaderFileTemplate
type loaderFileTemplateContext struct {
Font FontSpec
GS GlyphSet
FontName string
}
// Holds data for rendering fontmapTemplate
type fontmapTemplateContext struct {
FontDir []FontMap
SmallFontDir []FontMap
}
type loadermodTemplateContext struct {
FontDir []FontSummary
SmallFontDir []FontSummary
}
// Return a string from rendering the given template and context data
func renderTemplate(templateString string, name string, context interface{}) string {
fmap := template.FuncMap{"ToLower": strings.ToLower}
t := template.Must(template.New(name).Funcs(fmap).Parse(templateString))
var buf bytes.Buffer
err := t.Execute(&buf, context)
if err != nil {
panic(err)
}
return buf.String()
}
// Template with usage instructions for the command line tool
const usageTemplate = `
This tool generates fonts in the form of rust source code.
To confirm that you want to write the files, use the {{.Confirm}} switch.
To show debug info, use the {{.Debug}} switch.
Font files that will be generated:{{range $f := .Fonts}}
{{$f.RustOut}}
{{$f.LoaderOut}}{{end}}
Usage:
go run main.go {{.Confirm}}
`
// Template with rust source code for a outer structure of a font file
const fontFileTemplate = `#![cfg_attr(rustfmt, rustfmt_skip)]
// DO NOT MAKE EDITS HERE because this file is automatically generated.
// To make changes, see <xous_root>/libs/blitstr2/codegen/main.go
//
{{.Font.Legal}}
//! {{.Font.Name}} Font
#![allow(dead_code)]
/// Maximum height of glyph patterns in this bitmap typeface.
pub const MAX_HEIGHT: u8 = {{.Font.Size}};
/// Unicode character codepoints corresponding to glyph sprites in GLYPHS array.
/// Indended use:
/// 1. Do binary search on CODEPOINTS to find index of the codepoint corresponding
/// to the glyph you want to locate
/// 2. Multiply resulting CODEPOINTS index by 8 (<<3) to get index into GLYPHS for
/// the corresponding glyph sprite (because 16*16px sprite size is 8*u32)
pub const CODEPOINTS: [u32; {{.GS.CodepointsLen}}] = [
{{.GS.Codepoints}}];
#[cfg(any(feature="precursor", feature="renode"))]
pub static GLYPH_LOCATION: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0);
pub const GLYPH_LEN: usize = {{.GS.GlyphsLen}};
pub fn glyphs() -> &'static [u32] {
#[cfg(any(feature="precursor", feature="renode"))]
unsafe {
let data: *const u32 = core::ptr::with_exposed_provenance::<u32>(GLYPH_LOCATION.load(core::sync::atomic::Ordering::SeqCst) as usize);
core::slice::from_raw_parts(data, GLYPH_LEN)
}
#[cfg(any(not(target_os = "xous"), feature="bao1x"))]
&GLYPHS
}
#[cfg(any(not(target_os = "xous"), feature = "bao1x"))]
/// Packed 16px * 16px glyph pattern data.
/// Pixels are packed in row-major order with LSB of first pixel word
/// containing the top left pixel. Bit of 0 means clear, 1 means set
pub const GLYPHS: [u32; {{.GS.GlyphsLen}}] = [
{{.GS.Glyphs}}];
{{if .GS.Widths}}
/// Widths for proportional glyphs
pub const WIDTHS: [u8; {{.GS.WidthsLen}}] = [
{{.GS.Widths}}];
{{end}}
`
const loaderFileTemplate = `#![cfg_attr(rustfmt, rustfmt_skip)]
// DO NOT MAKE EDITS HERE because this file is automatically generated.
// To make changes, see <xous_root>/libs/blitstr2/codegen/main.go
{{.Font.Legal}}
//! {{.Font.Name}} Font
#![allow(dead_code)]
#[link_section = ".fontdata"]
#[no_mangle]
#[used]
/// Packed 16px * 16px glyph pattern data.
/// Pixels are packed in row-major order with LSB of first pixel word
/// containing the top left pixel. Bit of 0 means clear, 1 means set
pub static {{.FontName}}_GLYPHS: [u32; {{.GS.GlyphsLen}}] = [
{{.GS.Glyphs}}];{{if .GS.Widths}}{{end}}
`
const loadermodTemplate = `#![cfg_attr(rustfmt, rustfmt_skip)]
// DO NOT MAKE EDITS HERE because this file is automatically generated.
// The order of these modules affects the link order in the loader, which is referred to in the graphics engine.
// To make changes, see <xous_root>/libs/blitstr2/codegen/main.go
// NOTE: this list must be in alphabetical order since Rust 1.91.0. If it is not alphabetized,
// the linker will re-order them into allphabetical order, messing up the offsets.
{{range $f := .FontDir}}
#[cfg(not(feature = "bao1x"))]
pub mod {{$f.Name}};{{end}}
`
const fontmapTemplate = `#![cfg_attr(rustfmt, rustfmt_skip)]
// DO NOT MAKE EDITS HERE because this file is automatically generated.
// The order of these modules affects the link order in the loader, which is referred to in the graphics engine.
// To make changes, see <xous_root>/libs/blitstr2/codegen/main.go
#![allow(dead_code)]
#[cfg(not(feature = "bao1x"))]
pub const FONT_BASE: usize = 0x2053_0000;
// NOTE: this list must be in alphabetical order since Rust 1.91.0. If it is not alphabetized,
// the linker will re-order them into allphabetical order, messing up the offsets.
{{range $f := .FontDir}}#[cfg(not(feature = "bao1x"))]
pub const {{$f.Name}}: usize = 0x{{$f.Len}};
{{end}}
`