Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mgsfontgen-dx (Python port)

A Python port of the original C#/SharpDX mgsfontgen-dx — a tool for generating bitmap font atlases (and matching width tables) for MAGES-engine (SC3) games, as consumed by LanguageBarrier.

It reproduces the original tool's layout, metrics, outline and width-table semantics using Pillow + numpy instead of DirectWrite/SharpDX, so output is not byte-identical to the original rasteriser but the behaviour is preserved.


Features

  • Bitmap font atlas generation in a 64-column grid (configurable).
  • Normal cells 48×48 / 32×32, outline cells 57×57 (the original +9 room for the outline stroke). A separate outline atlas is produced by stroking the glyph outlines in 7 passes with decreasing alpha.
  • Per-character widths measured with the game's 1.5× width multiplier, written one byte per character to widths.bin.
  • Compound characters: Private-Use-Area code points mapped to replacement strings (optionally horizontally stretched to fit a single cell).
  • Two spacing controls per line: a coarse cell spacing (may be negative for a condensed look) and a fine glyph spacing (free range — no upper/lower limit — for precise tightness). The effective pitch is cell + cell_spacing + glyph_spacing (clamped to ≥ 1 px).
  • Multi-line charsets: if the charset contains line breaks (CR U+000D, LF U+000A, or CRLF), it is split into separate line blocks that never flow into one another. Each line keeps its own cell/glyph spacing, independently editable.
  • PNG or DDS output (DDS is uncompressed BGRA8, matching the game's expected format). Optional alpha premultiplication.
  • A PySide6 GUI with a live preview, zoom controls, grid overlay and per-line spacing.
  • Forced column count: the column count is normally derived from the output width and the current pitch, but it can be forced (CLI --columns, or the GUI Columns spinner in Layout & Format). Forcing it overrides the output-width derivation for both the preview and the generated atlas.
  • True pair kerning: when enabled, each glyph is shifted by its real pair-kerning value with the preceding glyph (read from the font's kern / GPOS tables via fontTools). Applied visually — the width table is unchanged.
  • Per-character position adjustment: click any glyph in the GUI preview to select it, then nudge it with the X/Y spinners (applied on top of the shared baseline). Overrides are keyed by code point and affect every occurrence; the GUI can import/export them to a [0xXXXX]=dx,dy file, and the CLI takes the same file via --adjustments.
  • Session save / load: the GUI can export the entire configuration (font, size, baseline, cell/spacing, per-line spacing, columns, kerning, outline, charset/compound/output paths, and per-character adjustments) to a JSON session file, and re-import it later to replicate a past output. See below.

Requirements

  • Python 3.10+
  • Pillow
  • numpy
  • PySide6 (GUI only; the CLI works without it)
  • fontTools — used for true pair kerning (reads the font's kern / GPOS tables). Optional in the sense that the tool still runs without it; --kerning simply becomes a no-op.
  • A font resolvable by fontconfig (fc-match) when passing a family name, or an explicit .ttf/.ttc/.otf path.

Install the dependencies:

pip install Pillow numpy PySide6

Command-line usage

python3 fontgen.py generate --charset charset.utf8 \
    --font-family "Noto Sans CJK JP" --font-size 38 \
    --baseline-originx 1 --baseline-originy -7 \
    --charset-size 5440 --image-format png --output-dir out

generate flags

Flag Default Description
--charset (required) Charset text file (UTF-8).
--font-family Noto Sans CJK JP Font family name or a path to a font file.
--compound-characters Compound-character table (see below).
--adjustments Per-character position table, [0xXXXX]=dx,dy (dx/dy are pixel nudges).
--font-size 38 Font size in px.
--baseline-originx 1 Glyph baseline X offset within the cell.
--baseline-originy -7 Glyph baseline Y offset within the cell.
--charset-size 5440 Max glyphs per output "page" (batch). Lines are never split across pages.
--image-format png png or dds.
--cell-width 48 Normal cell width.
--cell-height 48 Normal cell height.
--cell-spacing 0 Coarse gap between cells (px); negative condenses.
--glyph-spacing 4 Fine gap between glyphs (px); free range.
--output-width 3072 Target atlas width; columns derived from it.
--columns Force a column count (overrides --output-width). Default: derive from --output-width and pitch.
--output-dir . Output directory.
--no-premultiply Disable alpha premultiplication.
--no-outline Skip the outline atlas.

Output

For each batch (page) a letter is appended: FONT_A.png, font-outline_A.png, FONT_B.png, font-outline_B.png, … plus a single widths.bin containing all widths concatenated (one byte per glyph, in flattened line order).


Compound characters

Use Private-Use-Area code points for compound glyphs and list their expansions in a table file passed via --compound-characters (GUI: Compound table). Each non-empty line is either:

[0xXXXX]=value
[0xAAAA-0xBBBB]=value

The mapped value string is rendered into one cell and, when its measured width exceeds the normal cell divided by 1.5, it is horizontally stretched to fit (matching the original mgsfontgen behaviour).


Multi-line charsets & per-line spacing

When the charset file contains line breaks, it is treated as multiple lines:

  • Lines are split on CR U+000D, LF U+000A, or CRLF. The break characters are not rendered.
  • Each line is laid out as a separate block — a line never flows into the next one.
  • Each line stores its own cell_spacing / glyph_spacing. Changing the spacing controls only affects the line currently being edited.

In the CLI, the same --cell-spacing / --glyph-spacing are applied uniformly to every line. In the GUI, use the Line selector (in the Layout & Format group) to pick which line's spacing you are editing; the preview shows the active line.

Example: a charset edited with "shift+Enter" line breaks stores each line as a separate block, and different dialogue lines can be tightened or loosened independently.


GUI

Launch with:

python3 mgsfontgen_gui.py

The .ui layout is defined in mgsfontgen_gui.ui. If you edit the .ui, regenerate the Python binding:

pyside6-uic mgsfontgen_gui.ui -o ui_mgsfontgen_gui.py

(Do not hand-edit ui_mgsfontgen_gui.py; it is generated.)

See USAGE.md for a walkthrough of every control.


Project layout

File Purpose
fontgen.py Core generator (FontAtlasGenerator, render_lines, generate) + CLI.
mgsfontgen_gui.py PySide6 GUI (uses the generated UI).
mgsfontgen_gui.ui Qt Designer layout file.
ui_mgsfontgen_gui.py Generated from .ui (regenerate with pyside6-uic).
charsets Sample charsets.

Session save / load

To reproduce a past atlas exactly, use the GUI's Session group:

  • Export session writes every generation-affecting setting to a JSON file (session.json). This includes the font family, font size, baseline X/Y, cell width/height, per-line cell/glyph spacing, forced Columns, kerning, image format, premultiplication, outline toggle, charset/compound/output-dir paths, and the full per-character adjustment table.
  • Import session reads that JSON back and re-applies all controls, reloads the charset/compound files, and restores per-line spacing + adjustments, then refreshes the preview.

The charset, compound and output-dir entries are stored as paths (same machine / working copy). If a path no longer exists on import, the field is still filled in so you can re-point it; per-line spacing is padded/truncated to the loaded charset's line count.


Notes / differences from the original

  • Rasterisation uses Pillow/numpy rather than DirectWrite, so pixel output is not byte-identical, but layout, metrics, outline passes and the width table are faithful.
  • The Python port adds the finer glyph spacing control and per-line spacing on top of the original's single spacing.
  • A ZDR Hy3 model was used during the porting / testing process of this utility.

About

Python port of the mgsfontgen-dx Committee of Zero tool

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages