FNT is an Atlus format that stores font data used for rendering message text. It compresses the bitmap glyphs (letters and symbols) that comprise the font so that PS2 architecture can load it all at once without exceeding video memory.
In both the Japanese and English releases of Persona 3 and Persona 4, the font Skip B by FontWorks was used.
0x0-0x20 main header 0x0-0x4 header size 0xE-0x10 total glyph count 0x10-0x14 tile size, two word values 0x20-0x60 4-byte-per-color palette 0x60-0x3F0 font width table 0x60-0x64 block size 0x64-0x3F0 metrics, two 1 byte values for every glyph (left cut and right cut) 0x3F0-0xC38 unused reserved font map, 4-byte-per-glyph 0xC38-0xF4B2 compressed font area 0xC38-0xC58 header 0xC38-0xC3C header size 0xC3C-0xC40 compression dictionary block size 0xC40-0xC44 last block size 0xC50-0xC54 glyph position table block size 0xC54-0xC58 uncompressed font size (number-of-glyphs*512 in this case, since each is 32x32 4bpp) 0xC58-0x17A4 compression dictionary block 0xC58-0xC5A number of entries 0xC5A-0xC5C number of entries subtract 1 0xC5C-0xC5E number of dictionary entries dedicated for storing uncompressed byte values 0xC5E-0x17A4 dictionary entries, number-of-entries * 6 0xC5E-0xC64 dictionary entry. consists of 3 word values. first value is a entry count. 0x17A4-0x1F88 compressed glyph position table, 4-byte-per-glyph, unused for whole decompression, required for recompression. processed by shifting value right to $4 (Rsh), shifting left to $1 (Lsh), adding last block start position. 0x1F88-0xF4B2 compressed last block data
Above data is based on FONT0.FNT from the US version of Persona 4.
A general-purpose modding utility but a good tool for FNT editing. The latest release can be found here.
A tool made by RikuKH3 for extracting the bitmap from a FNT file was made available here. The source code for the decompressor was posted here in Delphi. However, his tool for successfully re-importing a modified bitmap has never been released to the public.