Nimbin[12]?SDL & Graphics / sdl_runtime_compiler / commits / 646a74e

sdl_runtime_compiler git · main

SDL3 game for running and compiling code at runtime

sdl3 c++ compiler dlopen cmake · first commit 2026-04-19 · last commit 2026-07-03 (3 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-runtime-compiler

C++ 72.3% C 26.2%
git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gz

Add dejavu font And rename some stuff

Christian Immanuel · 2026-06-27 09:47 · 646a74e0792e9a85c744da13b233d3d8de7b592f

 assets/fonts/DejaVuSansMono.ttf   | Bin 0 -> 340712 bytes
 assets/fonts/LICENSE_dejavu-fonts | 187 ++++++++++++++++++++++++++++++++++++++
 assets/sandbox.c                  |   2 +-
 assets/sandbox.c.last_ok          |   2 +-
 src/entities/pult.cpp             |   2 +-
 src/states/game_state.cpp         |  10 +-
 src/systems/hint_system.cpp       |   2 +-
 src/systems/wall_connection.cpp   |   2 +-
 src/text/handler.cpp              |  90 +++++++++---------
 src/text/handler.hpp              |  36 ++++----
 src/text/text.hpp                 |   2 +-
 src/text/token.hpp                |   3 +-
 src/wall/label.cpp                |   4 +-
 src/wall/label.hpp                |   2 +-
 14 files changed, 265 insertions(+), 79 deletions(-)

diff --git a/assets/fonts/DejaVuSansMono.ttf b/assets/fonts/DejaVuSansMono.ttf
new file mode 100644
index 0000000..f578602
Binary files /dev/null and b/assets/fonts/DejaVuSansMono.ttf differ
diff --git a/assets/fonts/LICENSE_dejavu-fonts b/assets/fonts/LICENSE_dejavu-fonts
new file mode 100644
index 0000000..df52c17
--- /dev/null
+++ b/assets/fonts/LICENSE_dejavu-fonts
@@ -0,0 +1,187 @@
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
+
+
+Bitstream Vera Fonts Copyright
+------------------------------
+
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
+a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license ("Fonts") and associated
+documentation files (the "Font Software"), to reproduce and distribute the
+Font Software, including without limitation the rights to use, copy, merge,
+publish, distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright and trademark notices and this permission notice shall
+be included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and
+additional glyphs or characters may be added to the Fonts, only if the fonts
+are renamed to names not containing either the words "Bitstream" or the word
+"Vera".
+
+This License becomes null and void to the extent applicable to Fonts or Font
+Software that has been modified and is distributed under the "Bitstream
+Vera" names.
+
+The Font Software may be sold as part of a larger software package but no
+copy of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
+ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
+FONT SOFTWARE.
+
+Except as contained in this notice, the names of Gnome, the Gnome
+Foundation, and Bitstream Inc., shall not be used in advertising or
+otherwise to promote the sale, use or other dealings in this Font Software
+without prior written authorization from the Gnome Foundation or Bitstream
+Inc., respectively. For further information, contact: fonts at gnome dot
+org.
+
+Arev Fonts Copyright
+------------------------------
+
+Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the fonts accompanying this license ("Fonts") and
+associated documentation files (the "Font Software"), to reproduce
+and distribute the modifications to the Bitstream Vera Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute, and/or sell copies of the Font Software, and to permit
+persons to whom the Font Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright and trademark notices and this permission notice
+shall be included in all copies of one or more of the Font Software
+typefaces.
+
+The Font Software may be modified, altered, or added to, and in
+particular the designs of glyphs or characters in the Fonts may be
+modified and additional glyphs or characters may be added to the
+Fonts, only if the fonts are renamed to names not containing either
+the words "Tavmjong Bah" or the word "Arev".
+
+This License becomes null and void to the extent applicable to Fonts
+or Font Software that has been modified and is distributed under the 
+"Tavmjong Bah Arev" names.
+
+The Font Software may be sold as part of a larger software package but
+no copy of one or more of the Font Software typefaces may be sold by
+itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
+TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the name of Tavmjong Bah shall not
+be used in advertising or otherwise to promote the sale, use or other
+dealings in this Font Software without prior written authorization
+from Tavmjong Bah. For further information, contact: tavmjong @ free
+. fr.
+
+TeX Gyre DJV Math
+-----------------
+Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
+
+Math extensions done by B. Jackowski, P. Strzelczyk and P. Pianowski
+(on behalf of TeX users groups) are in public domain.
+
+Letters imported from Euler Fraktur from AMSfonts are (c) American
+Mathematical Society (see below).
+Bitstream Vera Fonts Copyright
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera
+is a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license (“Fonts”) and associated
+documentation
+files (the “Font Software”), to reproduce and distribute the Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute,
+and/or sell copies of the Font Software, and to permit persons  to whom
+the Font Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright and trademark notices and this permission notice
+shall be
+included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may be modified and
+additional
+glyphs or characters may be added to the Fonts, only if the fonts are
+renamed
+to names not containing either the words “Bitstream” or the word “Vera”.
+
+This License becomes null and void to the extent applicable to Fonts or
+Font Software
+that has been modified and is distributed under the “Bitstream Vera”
+names.
+
+The Font Software may be sold as part of a larger software package but
+no copy
+of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
+FOUNDATION
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL,
+SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN
+ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR
+INABILITY TO USE
+THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+Except as contained in this notice, the names of GNOME, the GNOME
+Foundation,
+and Bitstream Inc., shall not be used in advertising or otherwise to promote
+the sale, use or other dealings in this Font Software without prior written
+authorization from the GNOME Foundation or Bitstream Inc., respectively.
+For further information, contact: fonts at gnome dot org.
+
+AMSFonts (v. 2.2) copyright
+
+The PostScript Type 1 implementation of the AMSFonts produced by and
+previously distributed by Blue Sky Research and Y&Y, Inc. are now freely
+available for general use. This has been accomplished through the
+cooperation
+of a consortium of scientific publishers with Blue Sky Research and Y&Y.
+Members of this consortium include:
+
+Elsevier Science IBM Corporation Society for Industrial and Applied
+Mathematics (SIAM) Springer-Verlag American Mathematical Society (AMS)
+
+In order to assure the authenticity of these fonts, copyright will be
+held by
+the American Mathematical Society. This is not meant to restrict in any way
+the legitimate use of the fonts, such as (but not limited to) electronic
+distribution of documents containing these fonts, inclusion of these fonts
+into other public domain or commercial font collections or computer
+applications, use of the outline data to create derivative fonts and/or
+faces, etc. However, the AMS does require that the AMS copyright notice be
+removed from any derivative versions of the fonts which have been altered in
+any way. In addition, to ensure the fidelity of TeX documents using Computer
+Modern fonts, Professor Donald Knuth, creator of the Computer Modern faces,
+has requested that any alterations which yield different font metrics be
+given a different name.
+
+$Id$
diff --git a/assets/sandbox.c b/assets/sandbox.c
index 1c62ace..6c2c3ec 100644
--- a/assets/sandbox.c
+++ b/assets/sandbox.c
@@ -46,7 +46,7 @@ int game_build(DynObject *out, int max)
     text(0, -15, 5, "hi");
     box(0, -16, 5, 2, 1, 2, 0);
 
-    for (int i = 0; i < 100; i++)
+    for (int i = 0; i < 200 ; i++)
         box(0 + i, -16, 5 + i % 4, 1, 1 + i * 0.5, 1, 0);
 
     return n;
diff --git a/assets/sandbox.c.last_ok b/assets/sandbox.c.last_ok
index 1c62ace..6c2c3ec 100644
--- a/assets/sandbox.c.last_ok
+++ b/assets/sandbox.c.last_ok
@@ -46,7 +46,7 @@ int game_build(DynObject *out, int max)
     text(0, -15, 5, "hi");
     box(0, -16, 5, 2, 1, 2, 0);
 
-    for (int i = 0; i < 100; i++)
+    for (int i = 0; i < 200 ; i++)
         box(0 + i, -16, 5 + i % 4, 1, 1 + i * 0.5, 1, 0);
 
     return n;
diff --git a/src/entities/pult.cpp b/src/entities/pult.cpp
index 826af67..68a60e1 100644
--- a/src/entities/pult.cpp
+++ b/src/entities/pult.cpp
@@ -67,7 +67,7 @@ Pult::Pult(const std::string& n, Vec3 world_pos,
            false)
      , name(n), half_w(half_width), half_d(half_depth)
 {
-    label.set_Billboard (true);
+    label.set_FaceCamera (true);
     label.set_Style     (Config::Color::teal, Text::Token::depth_wall, 0.0025f);
     label.set_Collidable(true);
     label.attach_To     (&pos, Vec3{ 0.0, Config::Pult::label_height, 0.0 });
diff --git a/src/states/game_state.cpp b/src/states/game_state.cpp
index b96ea91..ee44773 100644
--- a/src/states/game_state.cpp
+++ b/src/states/game_state.cpp
@@ -52,13 +52,13 @@ GameState::GameState(size_t starting_level)
     _wall_labels     = Wall::Label::generate_All(World::get_BoxScale());
 
     _wall_editor     = Text::Handler(Wall::Role::Editor, World::get_BoxScale(),
-                                     Text::LayoutMode::Mono);
+                                     Text::LayoutMode::Editing);
     _wall_editor.set_ShowNumbers(true, true);
 
     _text_walls = { &_wall_editor };
 
     _wall_program = Text::Handler(Wall::Role::Program, World::get_BoxScale(),
-                                  Text::LayoutMode::Snapped);
+                                  Text::LayoutMode::Display);
     _wall_program.set_Lexing      (false);
     _wall_program.set_ShowNumbers (false, false);
     _wall_program.set_DefaultStyle(Text::Token::depth_wall, 0.003f,
@@ -68,7 +68,7 @@ GameState::GameState(size_t starting_level)
     _wall_program.set_FaceMode      (Text::FaceMode::Pitch);
 
     _wall_compiler = Text::Handler(Wall::Role::Compiler, World::get_BoxScale(),
-                              Text::LayoutMode::Snapped);
+                              Text::LayoutMode::Display);
     _wall_compiler.set_Lexing      (false);
     _wall_compiler.set_ShowNumbers (false, false);
     _wall_compiler.set_DefaultStyle(Text::Token::depth_compiler, 0.003f,
@@ -79,7 +79,7 @@ GameState::GameState(size_t starting_level)
     _wall_compiler.set_FaceMode(Text::FaceMode::Pitch);
 
     _wall_info = Text::Handler(Wall::Role::Info, World::get_BoxScale(),
-                               Text::LayoutMode::Snapped);
+                               Text::LayoutMode::Display);
     _wall_info.set_Lexing      (false);
     _wall_info.set_ShowNumbers (false, false);
     _wall_info.set_DefaultStyle(Text::Token::depth_wall, 0.003f,
@@ -618,7 +618,7 @@ GameState::projectile_LandOnWallText(ProjectileResult& result)
                  && token_idx < lines[line_idx].tokens.size()
                  && lines[line_idx].tokens[token_idx]) {
 
-                if (handler->is_Mono()) {
+                if (handler->is_Editing()) {
                     Vec3 impact = lines[line_idx].tokens[token_idx]->pos;
                     for (const Text::TokenPtr& word : result.words)
                         if (word) { impact = word->pos; break; }
diff --git a/src/systems/hint_system.cpp b/src/systems/hint_system.cpp
index 9a802d0..8ecd21e 100644
--- a/src/systems/hint_system.cpp
+++ b/src/systems/hint_system.cpp
@@ -9,7 +9,7 @@ Nimbin
 HintSystem::HintSystem()
 {
     _label.set_Centre    (Vec3{ 0.0, World::get_FloorY<double>() + 2.5, 0.0 });
-    _label.set_Billboard (true);
+    _label.set_FaceCamera (true);
     _label.set_Style     (Config::Color::yellow, Text::Token::depth_wall, 0.003f);
     _label.set_Collidable(true);
 }
diff --git a/src/systems/wall_connection.cpp b/src/systems/wall_connection.cpp
index ef0c6f1..388badb 100644
--- a/src/systems/wall_connection.cpp
+++ b/src/systems/wall_connection.cpp
@@ -193,7 +193,7 @@ Connection::draw_EditorCursor(GlRenderer& gl, const Camera& cam, const Light& li
     if (!_editor) return;
     if (SDL_fmod(_blink, 0.8) > 0.4) return;
 
-    const Text::Handler::MonoMetrics m = _editor->mono_Metrics();
+    const Text::Handler::EditingMetrics m = _editor->editing_Metrics();
     if (m.char_w <= 0.0) return;                 
 
     const int    row   = _editor->cursor_Row();
diff --git a/src/text/handler.cpp b/src/text/handler.cpp
index 8b18312..de0e562 100644
--- a/src/text/handler.cpp
+++ b/src/text/handler.cpp
@@ -23,7 +23,7 @@ namespace
 {
 
 double
-mono_CharWidth()
+editing_CharWidth()
 {
     static double w = 0.0;
     if (w == 0.0) {
@@ -35,7 +35,7 @@ mono_CharWidth()
 }
 
 double
-mono_HalfExtentY()
+editing_HalfExtentY()
 {
     static double h = 0.0;
     if (h == 0.0) {
@@ -77,13 +77,13 @@ Handler::Handler(Wall::Role role, float world_scale, LayoutMode mode)
     _word_spacing = Config::Wall::free_space_dist;
     _append_color = Config::Color::dark_gray;
 
-    // The editor is always-Mono: it keeps a persistent buffer (its source of
-    // truth) even when not connected, and lays out on the mono grid at rest.
+    // The editor is always-Editing: it keeps a persistent buffer (its source of
+    // truth) even when not connected, and lays out on the editing grid at rest.
     // One relayout here establishes _char_w before the first thrown word.
-    if (_layout == LayoutMode::Mono) {
+    if (_layout == LayoutMode::Editing) {
         _vim   = cpputils::make_unique<VimBuffer>();
         _eye_y = World::get_FloorY<double>() + 2.0;
-        relayout_Mono();              // establishes _char_w; _face keeps its Pitch default (tilt at rest)
+        relayout_Editing();              // establishes _char_w; _face keeps its Pitch default (tilt at rest)
     }
 }
 
@@ -154,7 +154,7 @@ Handler::set_Lines(const DynArray<std::string>& lines)
         _lines.push_back(std::move(ln));
     }
 
-    // Editor (persistent buffer): make the buffer the authority for the mono
+    // Editor (persistent buffer): make the buffer the authority for the editing
     // relayout, so loaded content shows as columned code and round-trips.
     if (_vim) {
         std::vector<std::string> v;
@@ -249,7 +249,7 @@ Handler::detach(Token::Data* t)
                 if (l.tokens.empty())
                     _lines.erase(_lines.begin() + static_cast<std::ptrdiff_t>(line_idx));
                 mark_Dirty();
-                if (_vim) { sync_VimFromLines(); relayout_Mono(); }   // keep buffer in step
+                if (_vim) { sync_VimFromLines(); relayout_Editing(); }   // keep buffer in step
                 return out;
             }
         }
@@ -262,9 +262,9 @@ void
 Handler::attach(DynArray<TokenPtr> tokens, const Vec3& impact)
 {
     if (tokens.empty()) return;
-    if (_layout == LayoutMode::Mono)
-         attach_Mono   (tokens, impact);
-    else attach_Snapped(tokens, impact);
+    if (_layout == LayoutMode::Editing)
+         attach_Editing   (tokens, impact);
+    else attach_Display(tokens, impact);
 
     mark_Dirty();
 }
@@ -396,7 +396,7 @@ Handler::apply_Target(const Target& t)
 // Materialise whitespace tokens between adjacent words so the line round-trips
 // through as_Lines (raw concat) without merging. Space tokens are invisible on
 // the wall (Handler::render skips whitespace), so only array ORDER matters here
-// — their wall position is irrelevant; relayout_Mono repositions them on edit.
+// — their wall position is irrelevant; relayout_Editing repositions them on edit.
 void
 Handler::ensure_WordSeparators(Line& l)
 {
@@ -420,7 +420,7 @@ Handler::ensure_WordSeparators(Line& l)
 
 
 void
-Handler::attach_Snapped(DynArray<TokenPtr>& block, const Vec3& impact)
+Handler::attach_Display(DynArray<TokenPtr>& block, const Vec3& impact)
 {
     std::sort(block.begin(), block.end(),
         [](const TokenPtr& a, const TokenPtr& b){
@@ -584,7 +584,7 @@ Handler::classify_Impact(const Vec3& impact) const
 
     int vcol = 0; size_t b = 0; size_t k = 0;
 
-    // Split exactly like relayout_Mono: each space/tab is one cell, and a
+    // Split exactly like relayout_Editing: each space/tab is one cell, and a
     // non-whitespace run is lexically split into word / operator-group /
     // single-punctuation sub-tokens. This keeps `k` in lock-step with
     // line.tokens, so a DropToken's token_idx points at the token actually
@@ -635,7 +635,7 @@ Handler::classify_Impact(const Vec3& impact) const
 
 
 void
-Handler::attach_Mono(DynArray<TokenPtr>& block, const Vec3& impact)
+Handler::attach_Editing(DynArray<TokenPtr>& block, const Vec3& impact)
 {
     if (!_vim) { block.clear(); return; }
 
@@ -657,7 +657,7 @@ Handler::attach_Mono(DynArray<TokenPtr>& block, const Vec3& impact)
     _vim->insert_Word_At(hit.row, hit.col, word, /*new_line=*/hit.kind == HitKind::NewLine);
 
     _vim_seen_version = _vim->get_Version();
-    relayout_Mono();
+    relayout_Editing();
 }
 
 
@@ -744,14 +744,14 @@ Handler::as_Lines() const
 void
 Handler::relayout()
 {
-    if      (_layout == LayoutMode::Mono)      relayout_Mono();
-    else if (_layout == LayoutMode::Billboard) relayout_Billboard();
-    else                                       relayout_Snapped();
+    if      (_layout == LayoutMode::Editing)      relayout_Editing();
+    else if (_layout == LayoutMode::FaceCamera) relayout_FaceCamera();
+    else                                       relayout_Display();
 }
 
 
 void
-Handler::relayout_Snapped()
+Handler::relayout_Display()
 {
     const double x_wall = _transform.position.x;
     const double lh     = _line_height;
@@ -794,7 +794,7 @@ Handler::relayout_Snapped()
 
 
 void
-Handler::relayout_Mono()
+Handler::relayout_Editing()
 {
     if (!_vim) return;
 
@@ -823,8 +823,8 @@ Handler::relayout_Mono()
         _row0_y = anchor_bottom;       // at rest: whole file bottom-aligned to the floor
     }
 
-    _char_w = mono_CharWidth();
-    _he_y   = mono_HalfExtentY();
+    _char_w = editing_CharWidth();
+    _he_y   = editing_HalfExtentY();
 
     // Salvage old rows so unchanged lines keep their meshes (reuse only when the
     // line COUNT is unchanged — matches the original per-keystroke fast path).
@@ -962,11 +962,11 @@ Handler::relayout_Mono()
             bt.t->pos   = _transform.position;
             bt.t->pos.y = row_y;
             bt.t->pos.z = left_z - tok_w * 0.5;
-            // Uniform monospace cell for collision/aim: EVERY token (not just
+            // Uniform editingspace cell for collision/aim: EVERY token (not just
             // whitespace) gets a cell-width × cap-height box. The projectile
             // intercept tests shape.half_extents (via aabb_Min/Max), so any token
             // keeping its ink extents ("," tiny, "M" wide, "g" tall with descender)
-            // made the aim AABBs drift off the visible monospace columns and rows.
+            // made the aim AABBs drift off the visible editingspace columns and rows.
             // Width = one cell; height = the cap height of an 'A'/'M' (_he_y), the
             // same metric classify_Impact uses for its vertical row ownership.
             bt.t->half_extent          = (float)(tok_w * 0.5);
@@ -1058,7 +1058,7 @@ Handler::apply_Tilt(const Camera& cam)
     if (_face == FaceMode::None) return;
 
     // Phase 1 implements the wall case (Pitch toward eye). Yaw/Both (carried,
-    // billboard labels) arrive with the TextLabel fold-in.
+    // facecam labels) arrive with the TextLabel fold-in.
     if (_face != FaceMode::Pitch) return;
 
     auto tilt = [&](Token::Data* t) {
@@ -1075,8 +1075,8 @@ Handler::apply_Tilt(const Camera& cam)
 void
 Handler::update(double dt, const Camera& cam)
 {
-    if (_layout == LayoutMode::Billboard) { billboard_Update(dt, cam); return; }
-    if (_layout == LayoutMode::Snapped && _show_numbers)
+    if (_layout == LayoutMode::FaceCamera) { facecam_Update(dt, cam); return; }
+    if (_layout == LayoutMode::Display && _show_numbers)
         maintain_Numbers(dt, cam);
     apply_Tilt(cam);
 }
@@ -1153,8 +1153,8 @@ Handler::bounce(size_t line_idx)
 }
 
 
-Handler::MonoMetrics
-Handler::mono_Metrics() const
+Handler::EditingMetrics
+Handler::editing_Metrics() const
 {
     return { _char_w, _he_y, _code_left_z, _row0_y };
 }
@@ -1180,8 +1180,8 @@ Handler::begin_Edit(double eye_y)
     _capturing = true;
     _eye_y     = eye_y;
     _status.clear();
-    _layout = LayoutMode::Mono;
-    relayout_Mono();
+    _layout = LayoutMode::Editing;
+    relayout_Editing();
     mark_Dirty();
 }
 
@@ -1192,13 +1192,13 @@ Handler::end_Edit()
     _capturing = false;
     _face      = FaceMode::Pitch;     // tilt toward the eye again at rest (flat only while editing)
 
-    // Stay on the mono grid; the buffer persists as the source of truth. Recolor
+    // Stay on the editing grid; the buffer persists as the source of truth. Recolor
     // to the lexed scheme (the connected view may have shown edit-time colours).
     for (Line& l : _lines)
         for (TokenPtr& t : l.tokens)
             if (t) t->set_ColorSource(ColorSource::Lexed);
 
-    relayout_Mono();
+    relayout_Editing();
     mark_Dirty();
 }
 
@@ -1253,7 +1253,7 @@ Handler::feed_Keys(DynArray<int>& keys, double eye_y)
     const bool moved  = (_vim->get_Row()     != row_before);
     if (edited || moved) {
         _vim_seen_version = _vim->get_Version();
-        relayout_Mono();                 // re-anchor for scrolloff (motion) or rebuild (edit)
+        relayout_Editing();                 // re-anchor for scrolloff (motion) or rebuild (edit)
         if (edited) mark_Dirty();         // re-highlight only when text actually changed
     }
     return req;
@@ -1304,7 +1304,7 @@ Handler::cursor_ToToken(Token::Data* t)
             if (toks[token_idx].get() == t) {
                 _vim->set_Cursor((int)line_idx, (int)col);
                 _vim_seen_version = _vim->get_Version();
-                relayout_Mono();                          // cursor moved → re-anchor the view
+                relayout_Editing();                          // cursor moved → re-anchor the view
                 return true;
             }
             if (toks[token_idx]) col += toks[token_idx]->text.size();    // raw byte length (space/tab = 1)
@@ -1340,7 +1340,7 @@ Handler::cursor_AtImpact(const Vec3& impact)
 
     _vim->set_Cursor(row, byte);
     _vim_seen_version = _vim->get_Version();
-    relayout_Mono();
+    relayout_Editing();
     return true;
 }
 
@@ -1379,7 +1379,7 @@ Handler::place_CursorInsert(const CursorHit& hit)
     _vim->enter_Insert();              // insert mode so the cursor can sit at end-of-line
     _vim->set_Cursor(hit.row, hit.byte);
     _vim_seen_version = _vim->get_Version();
-    relayout_Mono();                   // re-anchor: scrolls this cursor into the player's view
+    relayout_Editing();                   // re-anchor: scrolls this cursor into the player's view
 }
 
 
@@ -1425,7 +1425,7 @@ Handler::set_Style(SDL_FColor color, float depth, float scale)
 void
 Handler::set_Centre(const Vec3& p)
 {
-    _layout     = LayoutMode::Billboard;
+    _layout     = LayoutMode::FaceCamera;
     _pos_mode   = PositionMode::Absolute;
     _centre     = p;
     _anchor_ptr = nullptr;
@@ -1435,7 +1435,7 @@ Handler::set_Centre(const Vec3& p)
 void
 Handler::attach_To(const Vec3* anchor, const Vec3& offset)
 {
-    _layout        = LayoutMode::Billboard;
+    _layout        = LayoutMode::FaceCamera;
     _pos_mode      = PositionMode::Anchor;
     _anchor_ptr    = anchor;
     _attach_offset = offset;
@@ -1455,8 +1455,8 @@ Handler::set_Text(const std::string& text)
 {
     if (text == _label_text && !_lines.empty()) return;
     _label_text = text;
-    _layout     = LayoutMode::Billboard;
-    relayout_Billboard();
+    _layout     = LayoutMode::FaceCamera;
+    relayout_FaceCamera();
 }
 
 
@@ -1504,7 +1504,7 @@ Handler::label_Centre() const
 
 
 void
-Handler::relayout_Billboard()
+Handler::relayout_FaceCamera()
 {
     _lines.clear();
     _label_off.clear();
@@ -1549,7 +1549,7 @@ Handler::relayout_Billboard()
 
 
 void
-Handler::billboard_Update(double dt, const Camera& cam)
+Handler::facecam_Update(double dt, const Camera& cam)
 {
     if (_lines.empty()) return;
     DynArray<TokenPtr>& words = _lines[0].tokens;
@@ -1559,7 +1559,7 @@ Handler::billboard_Update(double dt, const Camera& cam)
     float yaw_g   { 0.0f };
     float pitch_g { 0.0f };
 
-    if (_billboard) {
+    if (_facecam) {
         Vec3   fwd  = cam.pos - centre;
         double flen = Math::length(fwd);
         if (flen < 0.0001) return;
diff --git a/src/text/handler.hpp b/src/text/handler.hpp
index dca5292..1d3798e 100644
--- a/src/text/handler.hpp
+++ b/src/text/handler.hpp
@@ -29,7 +29,7 @@ public:
 
     struct NumberHit { size_t index; Vec3 aabb_Min; Vec3 aabb_Max; };
 
-    struct MonoMetrics {
+    struct EditingMetrics {
         double char_w;
         double he_y;
         double left_z;
@@ -68,7 +68,7 @@ public:
     TokenPtr     detach       (Token::Data* t);
     void         attach       (DynArray<TokenPtr> tokens, const Vec3& impact);
 
-    // Spatial classifier for thrown words on the always-mono editor grid.
+    // Spatial classifier for thrown words on the always-editing editor grid.
     // 80/20 rule: a non-whitespace token's central 80% (of its column span) is a
     // hit → DropToken; the outer 20% inserts beside it; whitespace cells always
     // insert; vertical gaps between rows create a new line (row may be negative
@@ -76,7 +76,7 @@ public:
     enum class HitKind : uint8_t { Insert, NewLine, DropToken };
     struct EditorHit { HitKind kind; int row; int col; size_t line_idx; size_t token_idx; };
     EditorHit classify_Impact(const Vec3& impact) const;
-    bool      is_Mono() const { return _layout == LayoutMode::Mono; }
+    bool      is_Editing() const { return _layout == LayoutMode::Editing; }
     void         clear_ToFloor(DynArray<TokenPtr>& out);
     double       scroll_DeltaToEye (size_t line_idx, double eye_y) const;
 
@@ -94,11 +94,11 @@ public:
     void scroll (double delta);
 
 
-    // ── vim cursor support (Mono) ──────────────────────────────────────────
-    MonoMetrics mono_Metrics() const;
+    // ── vim cursor support (Editing) ──────────────────────────────────────────
+    EditingMetrics editing_Metrics() const;
     double      row_Y       (int row) const;
 
-    // ── live editing (Mono) ───────────────────────────────────────────────
+    // ── live editing (Editing) ───────────────────────────────────────────────
     enum class EditReq : uint8_t { None, Write, WriteQuit, Exit, Discard };
 
     void    begin_Edit (double eye_y);
@@ -122,13 +122,13 @@ public:
     const DynArray<std::string>&
                        status_Lines() const;
 
-    // ── billboard label ───────────────────────────────────────────────────
+    // ── facecam label ───────────────────────────────────────────────────
     void set_Text      (const std::string& text);
     void set_Text      (const std::string& text, SDL_FColor color, float depth, float scale);
     void set_Centre    (const Vec3& p);
     void attach_To     (const Vec3* anchor, const Vec3& offset = {});
     void detach        ();
-    void set_Billboard (bool on) { _billboard = on; }
+    void set_FaceCamera (bool on) { _facecam = on; }
     void set_FaceYaw   (float y) { _face_yaw  = y;  }
     void set_Style     (SDL_FColor color, float depth, float scale);
     void set_Collidable(bool on);
@@ -147,7 +147,7 @@ private:
 
     Wall::Role      _role     { Wall::Role::Editor };
     Wall::Transform _transform{};
-    LayoutMode      _layout   { LayoutMode::Snapped };
+    LayoutMode      _layout   { LayoutMode::Display };
     FaceMode        _face     { FaceMode::Pitch };
 
     float  _depth        { Token::depth_wall };
@@ -173,7 +173,7 @@ private:
     uint64_t    _gen   { 0 };
     std::string _last_src;
 
-    // Mono grid cache (vim layout + cursor)
+    // Editing grid cache (vim layout + cursor)
     double _char_w     { 0.0 };
     double _he_y       { 0.0 };
     double _code_left_z{ 0.0 };
@@ -187,7 +187,7 @@ private:
 
     enum class PositionMode : uint8_t { Absolute, Anchor };
     const Vec3*  _anchor_ptr    { nullptr };
-    bool         _billboard     { true };
+    bool         _facecam     { true };
     bool         _collidable    { true };
     float        _face_yaw      { 0.0f };
     Vec3         _attach_offset {};
@@ -197,17 +197,17 @@ private:
     PositionMode _pos_mode      { PositionMode::Absolute };
     DynArray<double> _label_off;
 
-    void   relayout_Billboard();
-    void   billboard_Update  (double dt, const Camera& cam);
+    void   relayout_FaceCamera();
+    void   facecam_Update  (double dt, const Camera& cam);
     Vec3   label_Centre      () const;
 
     // layout
     void   relayout       ();
-    void   relayout_Snapped();
-    void   relayout_Mono   ();
+    void   relayout_Display();
+    void   relayout_Editing   ();
     void   sync_VimFromLines();   // editor: push _lines content back into the persistent buffer
 
-    // Snapped placement internals
+    // Display placement internals
     struct Target {
         enum   Kind { Merge, Insert } kind;
         size_t line_index;
@@ -217,9 +217,9 @@ private:
 
     Target resolve_Target  (double y) const;
     Line&  apply_Target    (const Target& t);
-    void   attach_Snapped  (DynArray<TokenPtr>& block, const Vec3& impact);
+    void   attach_Display  (DynArray<TokenPtr>& block, const Vec3& impact);
     void   ensure_WordSeparators(Line& l);
-    void   attach_Mono     (DynArray<TokenPtr>& block, const Vec3& impact);
+    void   attach_Editing     (DynArray<TokenPtr>& block, const Vec3& impact);
     void   maintain_Numbers(double dt, const Camera& cam);
     void   apply_Tilt      (const Camera& cam);
     bool   impact_To_RowCol(const Vec3& impact, int& row, int& col) const;
diff --git a/src/text/text.hpp b/src/text/text.hpp
index 350b04e..75e83e4 100644
--- a/src/text/text.hpp
+++ b/src/text/text.hpp
@@ -25,7 +25,7 @@ Text
 
     enum class ColorSource : uint8_t { Lexed, Lint, Static };
     enum class FaceMode    : uint8_t { None, Yaw, Pitch, Both };
-    enum class LayoutMode  : uint8_t { Snapped, Mono, Billboard };
+    enum class LayoutMode  : uint8_t { Display, Editing, FaceCamera };
 
 
     DynArray<std::string>
diff --git a/src/text/token.hpp b/src/text/token.hpp
index c2aa691..2ec3010 100644
--- a/src/text/token.hpp
+++ b/src/text/token.hpp
@@ -49,8 +49,7 @@ Token
     };
 
     // token_db.cpp START
-    inline const std::string font_path =
-     "/usr/share/fonts/dejavu/DejaVuSansMono.ttf";
+    inline const std::string font_path    = "assets/fonts/DejaVuSansMono.ttf";
 
     inline constexpr float depth_wall     = 0.06f;
     inline constexpr float depth_floor    = 0.14f;
diff --git a/src/wall/label.cpp b/src/wall/label.cpp
index 967f738..4bd2684 100644
--- a/src/wall/label.cpp
+++ b/src/wall/label.cpp
@@ -77,7 +77,7 @@ Wall::Label::generate_All(float world_scale)
         wl.face_yaw = tf.yaw;
 
         wl.label.set_Style      (label_Color(role), label_depth, label_scale);
-        wl.label.set_Billboard  (false);
+        wl.label.set_FaceCamera  (false);
         wl.label.set_FaceYaw    (tf.yaw);
         wl.label.set_Collidable (true);
         wl.label.set_Centre     (anch);
@@ -105,7 +105,7 @@ Wall::Label::on_Hit(size_t word_index, const Vec3& projectile_vel)
 void
 Wall::Label::update(double dt, const Camera& camera)
 {
-    // Positions + jiggle spring first. In non-billboard mode Text::Handler::update
+    // Positions + jiggle spring first. In non-facecam mode Text::Handler::update
     // forces every word's pitch to 0, so we must apply our eye-tilt AFTER it,
     // not before — otherwise the tilt gets clobbered. Pitch doesn't affect the
     // positions update() computes, so ordering it last is safe.
diff --git a/src/wall/label.hpp b/src/wall/label.hpp
index 20e80e5..28e0a74 100644
--- a/src/wall/label.hpp
+++ b/src/wall/label.hpp
@@ -1,6 +1,6 @@
 #pragma once
 //
-// Wall::Label — a per-wall billboard name tag. Lives in its own header (not
+// Wall::Label — a per-wall facecam name tag. Lives in its own header (not
 // wall.hpp) because it now owns a Text::Handler by value, and handler.hpp
 // includes wall.hpp; keeping Label here avoids the include cycle.