diff --git a/.github/workflows/rebuild-index.yml b/.github/workflows/rebuild-index.yml index 8242762..08f9dcc 100644 --- a/.github/workflows/rebuild-index.yml +++ b/.github/workflows/rebuild-index.yml @@ -37,4 +37,25 @@ jobs: git -C ~/gh-pages commit -qm "CI index rebuild." || echo "Nothing to commit." git -C ~/gh-pages push -q origin gh-pages env: - FILES: LICENSE.txt README.md index.html index.css glyphs.json chars.txt promptfont.ttf promptfont.otf promptfont.css atlas-android.png atlas-gamepad.png atlas-icons.png atlas-keyboard.png atlas-mouse.png + FILES: | + LICENSE.txt + README.md + index.html + index.css + glyphs.json + promptfont.ttf + promptfont.otf + promptfont.css + promptfont.txt + promptfont.h + promptfont.cs + promptfont.py + promptfont.lisp + promptfont.lua + promptfont.rs + promptfont.gd + atlas-android.png + atlas-gamepad.png + atlas-icons.png + atlas-keyboard.png + atlas-mouse.png diff --git a/.gitignore b/.gitignore index 51cd93f..445465a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,13 @@ promptfont.css promptfont.ttf promptfont.otf promptfont.afm +promptfont.txt +promptfont.h +promptfont.cs +promptfont.py +promptfont.lisp +promptfont.lua +promptfont.rs +promptfont.gd *.png *.zip \ No newline at end of file diff --git a/README.md b/README.md index a0322c6..b34f749 100644 --- a/README.md +++ b/README.md @@ -30,12 +30,14 @@ The [PromptFont release](https://github.com/Shinmera/promptfont/archive/refs/hea - ``nintendo`` Applies to Nintendo style gamepads - ``playstation`` Applies to Playstation style gamepads - ``generic`` Applies to any gamepad -- ``chars.txt`` +- ``promptfont.txt`` A plaintext UTF-8 file that contains all the characters that the font provides. - ``promptfont.ttf`` and ``promptfont.otf`` TrueType and OpenType versions of the font, which you should be able to use directly in-engine or other programs. - ``promptfont.css`` A CSS file that includes CSS classes for every special glyph, so you can easily embed it in HTML pages and JS games. +- ``promptfont.h`` ``promptfont.cs`` ``promptfont.py`` ``promptfont.lua`` ``promptfont.lisp`` ``promptfont.rs`` ``promptfont.gd`` + Source files that define constants for the special glyphs to allow easier embedding in C, C++, C#, Python, Lua, Lisp, Rust, and GDScript. - ``atlas-*.png`` Texture atlases of the various glyphs. Each glyph is 64x64 pixels and has a 1 pixel margin around itself. They are ordered left to right top to bottom according to their filename in the ``glyphs/`` directory of this repository. Since these rasterised versions don't scale well we heavily recommend you to use the fonts directly. diff --git a/compile.lisp b/compile.lisp index ebf0543..d17f5f0 100755 --- a/compile.lisp +++ b/compile.lisp @@ -69,22 +69,101 @@ exec sbcl \ (with-open-file (stream output :direction :output :if-exists :supersede) (plump:serialize (clip:process input :sections sections) stream)))) -(defun txt (&optional (file (file "glyphs" "json")) (output (file "chars" "txt"))) - (with-open-file (stream output :direction :output :if-exists :supersede) - (loop for glyph across (with-open-file (stream file) - (shasht:read-json stream)) - do (write-string (gethash "character" glyph) stream)))) +(defmacro define-processor (type (stream &rest args) &body body) + (let ((glyph (gensym "GLYPH"))) + `(defun ,type (&optional (file (file "glyphs" "json")) (output (file "promptfont" ,(string-downcase type)))) + (with-open-file (,stream output :direction :output :if-exists :supersede) + ,(first body) + (loop for ,glyph across (with-open-file (stream file) + (shasht:read-json stream)) + do (let ,(loop for arg in args + collect `(,arg (gethash ,(string-downcase arg) ,glyph))) + ,@(butlast (rest body)))) + ,@(last body))))) -(defun css (&optional (file (file "glyphs" "json")) (output (file "promptfont" "css"))) - (with-open-file (stream output :direction :output :if-exists :supersede) - (format stream "~&@font-face{font-family:'promptfont'; src:url('promptfont.ttf');}~%") - (format stream "~&.pf{font-family:promptfont;font-style:normal;}~%") - (loop for entry across (with-open-file (stream file) - (shasht:read-json stream)) - unless (string= "alphabet" (gethash "category" entry)) - do (format stream "~&.pf-~a:before{content:\"\\~x\"}~%" - (gethash "code-name" entry) - (gethash "codepoint" entry))))) +(define-processor txt (stream character) + () + (write-string character stream) + ()) + +(define-processor css (stream category code-name codepoint) + (format stream "~ +// PromptFont by Yukari \"Shinmera\" Hafner, accessible at https://shinmera.com/promptfont +@font-face{font-family:'promptfont'; src:url('promptfont.ttf');} +.pf{font-family:promptfont;font-style:normal;}") + (unless (string= "alphabet" category) + (format stream "~&.pf-~a:before{content:\"\\~x\"}~%" code-name codepoint)) + ()) + +(defun to-c-name (name &key (upcase T)) + (with-output-to-string (out) + (loop for c across name + do (case c + (#\- (write-char #\_ out)) + (T (write-char (if upcase (char-upcase c) c) out)))))) + +(define-processor h (stream code-name character codepoint) + (format stream "~ +// PromptFont by Yukari \"Shinmera\" Hafner, accessible at https://shinmera.com/promptfont +#ifndef __PROMPTFONT_H__ +#define __PROMPTFONT_H__~%") + (format stream "~&#define PF_~a ~s~%" (to-c-name code-name) character) + (format stream "~&#define PF_~a_INT 0x~5,'0x~%" (to-c-name code-name) codepoint) + (format stream "~&#endif~%")) + +(define-processor cs (stream code-name character codepoint) + (format stream "~ +// PromptFont by Yukari \"Shinmera\" Hafner, accessible at https://shinmera.com/promptfont +public static class PromptFont {~%") + (format stream "~& public const string ~a = ~s;~%" (to-c-name code-name) character) + (format stream "~& public const int ~a_INT = 0x~5,'0x;~%" (to-c-name code-name) codepoint) + (format stream "~&~ + string Get(string name){ + return (string)(typeof(PromptFont).GetProperty(name).GetValue(null)); + } + int GetInt(string name){ + return (int)(typeof(PromptFont).GetProperty(name+\"_INT\").GetValue(null)); + } +}~%")) + +(define-processor py (stream code-name character) + (format stream "~ +# PromptFont by Yukari \"Shinmera\" Hafner, accessible at https://shinmera.com/promptfont~%") + (format stream "~&~a = ~s~%" (to-c-name code-name) character) + ()) + +(define-processor lisp (stream code-name character) + (format stream "~ +;;;; PromptFont by Yukari \"Shinmera\" Hafner, accessible at https://shinmera.com/promptfont +\(defpackage #:org.shirakumo.fraf.promptfont (:use)) +\(in-package #:org.shirakumo.fraf.promptfont)~%~%") + (format stream "~&(cl:define-symbol-macro ~a ~s)~%" code-name character) + (format stream "~&~%~ +(cl:do-symbols (cl:symbol cl:*package*) + (cl:export cl:symbol))~%")) + +(define-processor lua (stream code-name character) + (format stream "~ +-- PromptFont by Yukari \"Shinmera\" Hafner, accessible at https://shinmera.com/promptfont +local GLYPHS = {}~%") + (format stream "~&GLYPHS.~a = ~s~%" (to-c-name code-name) character) + (format stream "~&return GLYPHS~%")) + +(define-processor rs (stream code-name character codepoint) + (format stream "~ +// PromptFont by Yukari \"Shinmera\" Hafner, accessible at https://shinmera.com/promptfont~%") + (format stream "~&pub const ~a: &'static str = ~s;~%" (to-c-name code-name) character) + (format stream "~&pub const ~a_INT: u64 = ~a;~%" (to-c-name code-name) codepoint) + ()) + +(define-processor gd (stream code-name character codepoint) + (format stream "~ +# PromptFont by Yukari \"Shinmera\" Hafner, accessible at https://shinmera.com/promptfont +class_name PromptFont +extends Resource~%") + (format stream "~&const ~a: StringName = &~s;~%" (to-c-name code-name) character) + (format stream "~&const ~a_INT: int = ~a;~%" (to-c-name code-name) codepoint) + ()) (defun fixup (&optional (file (file "glyphs" "json"))) (let ((data (with-open-file (stream file) @@ -146,17 +225,24 @@ for file in argv[2:]: (file "index" "html") (file "index" "css") (file "glyphs" "json") - (file "chars" "txt") + (file "promptfont" "txt") (file "promptfont" "ttf") (file "promptfont" "otf") (file "promptfont" "css") + (file "promptfont" "h") + (file "promptfont" "cs") + (file "promptfont" "py") + (file "promptfont" "lisp") + (file "promptfont" "lua") + (file "promptfont" "rs") + (file "promptfont" "gd") (directory (file :wild "png")))) (defun run-command (command &rest args) (apply (intern (format NIL "~:@(~a~)" command) #.*package*) args)) (defun all (&rest commands) - (dolist (command (or commands '(fixup fonts txt css web atlas release))) + (dolist (command (or commands '(fixup fonts txt css h cs py lisp lua rs gd web atlas release))) (run-command command))) (defun help ()