2022-01-18 19:29:53 +00:00
|
|
|
// Copyright (c) 2022 Sam Blenny
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
|
|
|
//
|
|
|
|
|
package lib
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"strings"
|
|
|
|
|
"text/template"
|
|
|
|
|
)
|
|
|
|
|
|
2022-01-22 19:23:06 +00:00
|
|
|
type FontSummary struct {
|
|
|
|
|
Name string
|
|
|
|
|
Len int
|
|
|
|
|
}
|
|
|
|
|
type FontMap struct {
|
|
|
|
|
Name string
|
|
|
|
|
Len string
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-18 19:29:53 +00:00
|
|
|
// 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 {
|
2022-01-22 19:23:06 +00:00
|
|
|
fname := strings.ToUpper(f.Name)
|
|
|
|
|
context := fontFileTemplateContext{f, gs, fname}
|
2022-01-18 19:29:53 +00:00
|
|
|
return renderTemplate(fontFileTemplate, "fontfile", context)
|
|
|
|
|
}
|
2022-01-22 19:23:06 +00:00
|
|
|
func RenderLoaderFileTemplate(f FontSpec, gs GlyphSet) string {
|
|
|
|
|
fname := strings.ToUpper(f.Name)
|
|
|
|
|
context := loaderFileTemplateContext{f, gs, fname}
|
|
|
|
|
return renderTemplate(loaderFileTemplate, "loaderfile", context)
|
|
|
|
|
}
|
2024-01-27 18:11:09 +00:00
|
|
|
func RenderFontmapTemplate(fd []FontMap, small_fd []FontMap) string {
|
|
|
|
|
context := fontmapTemplateContext{fd, small_fd}
|
2022-01-22 19:23:06 +00:00
|
|
|
return renderTemplate(fontmapTemplate, "fontmap", context)
|
|
|
|
|
}
|
2024-01-28 19:32:12 +00:00
|
|
|
func RenderLoadermodTemplate(fd []FontSummary, small_fd []FontSummary) string {
|
|
|
|
|
context := loadermodTemplateContext{fd, small_fd}
|
2022-01-22 19:23:06 +00:00
|
|
|
return renderTemplate(loadermodTemplate, "loadermod", context)
|
|
|
|
|
}
|
2022-01-18 19:29:53 +00:00
|
|
|
|
|
|
|
|
// Holds data for rendering usageTemplate
|
|
|
|
|
type usageTemplateContext struct {
|
|
|
|
|
Confirm string
|
|
|
|
|
Debug string
|
|
|
|
|
Fonts []FontSpec
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Holds data for rendering fontFileTemplate
|
|
|
|
|
type fontFileTemplateContext struct {
|
2022-01-22 19:23:06 +00:00
|
|
|
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 {
|
2024-01-27 18:11:09 +00:00
|
|
|
FontDir []FontMap
|
|
|
|
|
SmallFontDir []FontMap
|
2022-01-22 19:23:06 +00:00
|
|
|
}
|
|
|
|
|
type loadermodTemplateContext struct {
|
2024-01-28 19:32:12 +00:00
|
|
|
FontDir []FontSummary
|
|
|
|
|
SmallFontDir []FontSummary
|
2022-01-18 19:29:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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}}
|
2022-01-22 19:23:06 +00:00
|
|
|
{{$f.RustOut}}
|
|
|
|
|
{{$f.LoaderOut}}{{end}}
|
2022-01-18 19:29:53 +00:00
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
|
go run main.go {{.Confirm}}
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
// Template with rust source code for a outer structure of a font file
|
2024-01-14 15:12:52 +00:00
|
|
|
const fontFileTemplate = `#![cfg_attr(rustfmt, rustfmt_skip)]
|
2024-01-14 14:01:03 +00:00
|
|
|
// DO NOT MAKE EDITS HERE because this file is automatically generated.
|
2025-02-17 10:24:39 +00:00
|
|
|
// To make changes, see <xous_root>/libs/blitstr2/codegen/main.go
|
2022-01-18 19:29:53 +00:00
|
|
|
//
|
|
|
|
|
{{.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}}];
|
|
|
|
|
|
2025-09-25 08:07:31 +00:00
|
|
|
#[cfg(any(feature="precursor", feature="renode"))]
|
2025-02-17 10:24:39 +00:00
|
|
|
pub static GLYPH_LOCATION: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0);
|
|
|
|
|
pub const GLYPH_LEN: usize = {{.GS.GlyphsLen}};
|
2022-01-22 19:23:06 +00:00
|
|
|
|
2025-02-17 10:24:39 +00:00
|
|
|
pub fn glyphs() -> &'static [u32] {
|
2025-09-25 08:07:31 +00:00
|
|
|
#[cfg(any(feature="precursor", feature="renode"))]
|
2022-01-22 19:23:06 +00:00
|
|
|
unsafe {
|
2025-11-06 16:36:57 +00:00
|
|
|
let data: *const u32 = core::ptr::with_exposed_provenance::<u32>(GLYPH_LOCATION.load(core::sync::atomic::Ordering::SeqCst) as usize);
|
2022-01-22 19:23:06 +00:00
|
|
|
core::slice::from_raw_parts(data, GLYPH_LEN)
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-25 08:07:31 +00:00
|
|
|
#[cfg(any(not(target_os = "xous"), feature="bao1x"))]
|
2022-01-22 19:23:06 +00:00
|
|
|
&GLYPHS
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-25 08:07:31 +00:00
|
|
|
#[cfg(any(not(target_os = "xous"), feature = "bao1x"))]
|
2022-01-18 19:29:53 +00:00
|
|
|
/// 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}}];
|
2023-12-27 06:10:48 +00:00
|
|
|
{{end}}
|
|
|
|
|
`
|
2022-01-22 19:23:06 +00:00
|
|
|
|
2024-01-14 15:12:52 +00:00
|
|
|
const loaderFileTemplate = `#![cfg_attr(rustfmt, rustfmt_skip)]
|
2024-01-14 14:01:03 +00:00
|
|
|
// DO NOT MAKE EDITS HERE because this file is automatically generated.
|
2025-02-17 10:24:39 +00:00
|
|
|
// To make changes, see <xous_root>/libs/blitstr2/codegen/main.go
|
2022-01-22 19:23:06 +00:00
|
|
|
|
|
|
|
|
{{.Font.Legal}}
|
|
|
|
|
//! {{.Font.Name}} Font
|
|
|
|
|
#![allow(dead_code)]
|
2023-12-27 06:10:48 +00:00
|
|
|
#[link_section = ".fontdata"]
|
2022-01-22 19:23:06 +00:00
|
|
|
#[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}}] = [
|
2023-12-27 06:10:48 +00:00
|
|
|
{{.GS.Glyphs}}];{{if .GS.Widths}}{{end}}
|
|
|
|
|
`
|
2022-01-22 19:23:06 +00:00
|
|
|
|
2024-01-14 15:12:52 +00:00
|
|
|
const loadermodTemplate = `#![cfg_attr(rustfmt, rustfmt_skip)]
|
2024-01-14 14:01:03 +00:00
|
|
|
// DO NOT MAKE EDITS HERE because this file is automatically generated.
|
2022-01-22 19:23:06 +00:00
|
|
|
// The order of these modules affects the link order in the loader, which is referred to in the graphics engine.
|
2025-02-17 10:24:39 +00:00
|
|
|
// To make changes, see <xous_root>/libs/blitstr2/codegen/main.go
|
2025-11-17 16:18:55 +00:00
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
|
|
2023-12-27 06:10:48 +00:00
|
|
|
{{range $f := .FontDir}}
|
2025-09-25 08:07:31 +00:00
|
|
|
#[cfg(not(feature = "bao1x"))]
|
2024-01-28 19:32:12 +00:00
|
|
|
pub mod {{$f.Name}};{{end}}
|
|
|
|
|
`
|
2022-01-22 19:23:06 +00:00
|
|
|
|
2024-01-14 15:12:52 +00:00
|
|
|
const fontmapTemplate = `#![cfg_attr(rustfmt, rustfmt_skip)]
|
2024-01-14 14:01:03 +00:00
|
|
|
// DO NOT MAKE EDITS HERE because this file is automatically generated.
|
2022-01-22 19:23:06 +00:00
|
|
|
// The order of these modules affects the link order in the loader, which is referred to in the graphics engine.
|
2025-02-17 10:24:39 +00:00
|
|
|
// To make changes, see <xous_root>/libs/blitstr2/codegen/main.go
|
2022-01-22 19:23:06 +00:00
|
|
|
#![allow(dead_code)]
|
2025-09-25 08:07:31 +00:00
|
|
|
#[cfg(not(feature = "bao1x"))]
|
2024-01-27 18:11:09 +00:00
|
|
|
pub const FONT_BASE: usize = 0x2053_0000;
|
|
|
|
|
|
2025-11-17 16:18:55 +00:00
|
|
|
// 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.
|
2025-09-25 08:07:31 +00:00
|
|
|
{{range $f := .FontDir}}#[cfg(not(feature = "bao1x"))]
|
2024-01-27 18:11:09 +00:00
|
|
|
pub const {{$f.Name}}: usize = 0x{{$f.Len}};
|
|
|
|
|
{{end}}
|
|
|
|
|
`
|