Files
benilla-octo/crates/benilla-app/assets/ui/Fonts.xml
T
SamandClaude Fable 5 a683d5524f the interface code is ours: the transcription debt is paid
- forty files that carried the reference's literal Lua are rewritten as our own expression of the behaviour — worst identical run 61 lines down to 7 — and the README now says exactly that
- the overlap gate measures the code itself across all four reference corpora, and ratchets: the number may only go down
- a lost session ends at the login screen instead of silently re-authenticating and stealing the account back
- a building's skybox is a real model: Caverns of Time's white ceiling becomes its painted nebula and additive stars

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 19:21:03 +07:00

362 lines
19 KiB
XML

<Ui xmlns="http://www.blizzard.com/wow/ui/">
<!--
Benilla's named virtual Font objects: the COMPLETE set from the real 1.12.1 FrameXML
`Fonts.xml`, quoted verbatim — names, TTF paths, heights, colors, outlines, and
(critically) which families carry a `<Shadow>` and which don't. The reference copy is
re-extractable from the client at any time with the `mpqx` bin (crates/benilla-mpq,
virtual path `Interface\FrameXML\Fonts.xml`); this is our own authored file (MIT/Apache),
only the TTFs themselves stream from the client at render.
Being COMPLETE is the point: the first partial transcription lacked `QuestFontNormalSmall`,
a window substituted `GameFontNormalSmall` for it, and the parchment objectives rendered
10px gold WITH the MasterFont drop shadow instead of 12px warm-brown WITHOUT one — a look
bug born entirely from a missing font object, invisible to every engine test. Substituting
"a similar font" is never safe (shadow/height/color all ride the name), so every name the
real FrameXML defines exists here.
A FontString picks a font object up with `inherits="GameFontNormal"`; `SetFontObject`
re-points it. Each object resolves {font path, height, color, outline, shadow} through its
`inherits` chain. NOTE the load-bearing asymmetry, straight from the ref: the `GameFont*`
families chain through `MasterFont` (whose only content is the (1,-1) black `<Shadow>`),
while `GameFontBlack`/`GameFontWhite`, the `NumberFont*` family (outlined instead), and the
parchment `QuestFont*` family (except the brown-shadowed `QuestTitleFont`) do NOT — dark
text on parchment is shadowless in the real client.
-->
<!-- The shared font-color globals, QUOTED from the real Fonts.xml's own <Script> block
(ref l.8-19) — the |cAARRGGBB escape prefixes the stat/tooltip builders concatenate, and
the two color tables tooltip AddLine calls read. Defined here (the ref's own home, loaded
first) so every window shares one verified set. -->
<Script><![CDATA[
-- ── The four font-PATH globals (ref Fonts.xml l.4-7) ──────────────────────────────────
-- This file quoted the reference's colour block (l.8-19) and skipped the four lines above
-- it. `STANDARD_TEXT_FONT` is the one that matters: **68 corpus addons name it**, and per
-- 1207's rule that number is read rather than quoted — 64 of them are copies of
-- `Dewdrop-2.0.lua` and only 4 are addon code. But Dewdrop is *the* Ace2 menu library, and
-- it calls `button.text:SetFont(STANDARD_TEXT_FONT, height)` **unguarded** at two of its
-- three sites (l.207 and l.496; only l.2294 writes `STANDARD_TEXT_FONT or "Fonts\\..."`),
-- so a nil global is a failed SetFont on every menu button the Ace2 ecosystem draws.
--
-- The other three come with it because they are the same four-line block and cost nothing:
-- UNIT_NAME_FONT (0 corpus addons), DAMAGE_TEXT_FONT (1), NAMEPLATE_FONT (1). All four are
-- the same face in 1.12 — the reference assigns FRIZQT__ to every one — and that identity
-- is the reference's, not a simplification of ours.
STANDARD_TEXT_FONT = "Fonts\\FRIZQT__.TTF" -- ref Fonts.xml l.4
UNIT_NAME_FONT = "Fonts\\FRIZQT__.TTF" -- l.5
DAMAGE_TEXT_FONT = "Fonts\\FRIZQT__.TTF" -- l.6
NAMEPLATE_FONT = "Fonts\\FRIZQT__.TTF" -- l.7
NORMAL_FONT_COLOR_CODE = "|cffffd200" -- ref Fonts.xml l.8
HIGHLIGHT_FONT_COLOR_CODE = "|cffffffff" -- l.9
RED_FONT_COLOR_CODE = "|cffff2020" -- l.10
GREEN_FONT_COLOR_CODE = "|cff20ff20" -- l.11
GRAY_FONT_COLOR_CODE = "|cff808080" -- l.12
FONT_COLOR_CODE_CLOSE = "|r" -- l.14
NORMAL_FONT_COLOR = { r = 1.0, g = 0.82, b = 0 } -- l.15
HIGHLIGHT_FONT_COLOR = { r = 1.0, g = 1.0, b = 1.0 } -- l.16
GRAY_FONT_COLOR = { r = 0.5, g = 0.5, b = 0.5 } -- l.17
GREEN_FONT_COLOR = { r = 0.1, g = 1.0, b = 0.1 } -- l.18
RED_FONT_COLOR = { r = 1.0, g = 0.1, b = 0.1 } -- l.19
-- Added this session (decision 0216 §8, the spellbook slice) — the ref's own l.20, the
-- one color this file was missing: a passive spell's name text (SpellBookFrame.lua:385).
PASSIVE_SPELL_FONT_COLOR = { r = 0.77, g = 0.64, b = 0 } -- l.20
-- The item-quality palette — **built from the engine verb, exactly as the reference
-- builds it** (ref UIParent.lua l.65-72, verbatim shape; decision 1199):
--
-- ITEM_QUALITY_COLORS = { }
-- for i = -1, 6 do … = GetItemQualityColor(i) end
--
-- It used to be seven hand-typed rows here. They were CLOSE and not exact — 0.62 where
-- the client's byte is 0x9d/255 = 0.6157, 0.64/0.21/0.93 where Epic is
-- 0xa3/0x35/0xee — and they carried no `.hex`, which the reference's table has and
-- which addons splice straight into a chat link. `GetItemQualityColor` is now a real
-- engine binding over wow-5875-re RF-0055's byte-verified table, so the rounding and
-- the second source both go.
--
-- The loop starts at -1 like the reference's: `UIParent.lua` reads one index before the
-- array there, and our binding answers Poor for it rather than reproducing that.
ITEM_QUALITY_COLORS = { }
for i = -1, 6 do
ITEM_QUALITY_COLORS[i] = { }
ITEM_QUALITY_COLORS[i].r,
ITEM_QUALITY_COLORS[i].g,
ITEM_QUALITY_COLORS[i].b,
ITEM_QUALITY_COLORS[i].hex = GetItemQualityColor(i)
end
-- ── RAID_CLASS_COLORS (spec: ref Fonts.xml l.43-53 — same name, same nine keys, same
-- channel values; our own way of writing them down) ───────────────────────────────────
--
-- The per-class colour every raid/party addon paints names with. **22 corpus addons** reach
-- it — nine of them through `Babble-Class-2.0`, but seven more by hand (KLHThreatMeter,
-- CT_RaidAssist, CT_ExpenseHistory, _LazyPig, FuBar_oRA2CooldownFu, and BigWigs in two
-- plugins) — and absent it is `bad argument #1 to 'pairs' (table expected, got nil)` at
-- file scope. That was the whole of the harness's remaining `table expected` row: three
-- addons, one missing table, found by asking the blocker table which addons were behind it.
--
-- Written as the eight distinct triples plus a loop that lifts them into the `{r=,g=,b=}`
-- records addons index (`RAID_CLASS_COLORS["HUNTER"].r`), the same spec-plus-builder shape
-- ITEM_QUALITY_COLORS above takes. The only thing worth SAYING about a palette is which
-- colours are in it, and a bare triple says that with no ceremony; the record shape is the
-- addon-facing contract and belongs in the one line that builds it.
--
-- EIGHT triples for nine classes, and that is the 1.12 client's own doing: shamans have no
-- colour of their own. They were Horde-only and paladins Alliance-only, so the two never
-- shared a raid frame and the client hands SHAMAN the paladin pink. We ASSIGN it, which
-- states the fact instead of re-typing three numbers and asking the next reader to believe
-- a comment. (`ROGUE`'s yellow likewise reconciles with nothing else in the client. A later
-- client's palette is not this one's; these are 1.12's.) Each class still gets its OWN
-- record below, so an addon that writes to `.PALADIN.r` does not move SHAMAN — the
-- reference's two equal-but-separate tables, preserved.
local classRGB = {
WARRIOR = { 0.78, 0.61, 0.43 },
PALADIN = { 0.96, 0.55, 0.73 },
HUNTER = { 0.67, 0.83, 0.45 },
ROGUE = { 1.0, 0.96, 0.41 },
PRIEST = { 1.0, 1.0, 1.0 },
MAGE = { 0.41, 0.8, 0.94 },
WARLOCK = { 0.58, 0.51, 0.79 },
DRUID = { 1.0, 0.49, 0.04 },
}
classRGB.SHAMAN = classRGB.PALADIN
RAID_CLASS_COLORS = {}
for token, rgb in pairs(classRGB) do
RAID_CLASS_COLORS[token] = { r = rgb[1], g = rgb[2], b = rgb[3] }
end
-- The three OTHER tables the reference's Fonts.xml `<Script>` block carries —
-- CHAT_FONT_HEIGHTS, MATERIAL_TEXT_COLOR_TABLE, MATERIAL_TITLETEXT_COLOR_TABLE — are
-- deliberately not here: **zero corpus addons name any of them**, and nothing benilla ships
-- reads them. They cost nine lines each the day something does.
]]></Script>
<!-- MasterFont: the shadow-only root the GameFont* families chain through (ref l.56). -->
<Font name="MasterFont" virtual="true">
<Shadow>
<Offset><AbsDimension x="1" y="-1"/></Offset>
<Color r="0" g="0" b="0"/>
</Shadow>
</Font>
<!-- SystemFont: FRIZQT, 15px, yellow (ref l.64). -->
<Font name="SystemFont" inherits="MasterFont" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="15"/></FontHeight>
<Color r="1.0" g="1.0" b="0"/>
</Font>
<!-- The GameFont body family: FRIZQT, 12px, gold; color variants override only <Color> (ref l.70-96). -->
<Font name="GameFontNormal" inherits="MasterFont" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="12"/></FontHeight>
<Color r="1.0" g="0.82" b="0"/>
</Font>
<Font name="GameFontHighlight" inherits="GameFontNormal" virtual="true">
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="GameFontDisable" inherits="GameFontNormal" virtual="true">
<Color r="0.5" g="0.5" b="0.5"/>
</Font>
<Font name="GameFontGreen" inherits="GameFontNormal" virtual="true">
<Color r="0.1" g="1.0" b="0.1"/>
</Font>
<Font name="GameFontRed" inherits="GameFontNormal" virtual="true">
<Color r="1.0" g="0.1" b="0.1"/>
</Font>
<!-- GameFontBlack/White: 12px FRIZQT with NO MasterFont chain — shadowless (ref l.88-96). -->
<Font name="GameFontBlack" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="12"/></FontHeight>
<Color r="0" g="0" b="0"/>
</Font>
<Font name="GameFontWhite" inherits="GameFontBlack" virtual="true">
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<!-- The GameFont Small family: FRIZQT, 10px, gold (ref l.97-125). -->
<Font name="GameFontNormalSmall" inherits="MasterFont" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="10"/></FontHeight>
<Color r="1.0" g="0.82" b="0"/>
</Font>
<Font name="GameFontHighlightSmall" inherits="GameFontNormalSmall" virtual="true">
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="GameFontDisableSmall" inherits="GameFontNormalSmall" virtual="true">
<Color r="0.5" g="0.5" b="0.5"/>
</Font>
<Font name="GameFontDarkGraySmall" inherits="GameFontNormalSmall" virtual="true">
<Color r="0.35" g="0.35" b="0.35"/>
</Font>
<Font name="GameFontGreenSmall" inherits="GameFontNormalSmall" virtual="true">
<Color r="0.1" g="1.0" b="0.1"/>
</Font>
<Font name="GameFontRedSmall" inherits="GameFontNormalSmall" virtual="true">
<Color r="1.0" g="0.1" b="0.1"/>
</Font>
<!-- Despite the name, the ref declares a SHADOW here, not an outline (ref l.119). -->
<Font name="GameFontHighlightSmallOutline" inherits="GameFontHighlightSmall" virtual="true">
<Shadow>
<Offset><AbsDimension x="1" y="-1"/></Offset>
<Color r="0" g="0" b="0"/>
</Shadow>
</Font>
<!-- The GameFont Large family: FRIZQT, 16px, gold (ref l.127-145). -->
<Font name="GameFontNormalLarge" inherits="MasterFont" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="16"/></FontHeight>
<Color r="1.0" g="0.82" b="0"/>
</Font>
<Font name="GameFontHighlightLarge" inherits="GameFontNormalLarge" virtual="true">
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="GameFontDisableLarge" inherits="GameFontNormalLarge" virtual="true">
<Color r="0.5" g="0.5" b="0.5"/>
</Font>
<Font name="GameFontGreenLarge" inherits="GameFontNormalLarge" virtual="true">
<Color r="0.1" g="1.0" b="0.1"/>
</Font>
<Font name="GameFontRedLarge" inherits="GameFontNormalLarge" virtual="true">
<Color r="1.0" g="0.1" b="0.1"/>
</Font>
<!-- FRIZQT, 20px, gold (ref l.145). -->
<Font name="GameFontNormalHuge" inherits="MasterFont" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="20"/></FontHeight>
<Color r="1.0" g="0.82" b="0"/>
</Font>
<!-- The Number family: ARIALN, outlined, white — NO shadow (ref l.150-179). -->
<Font name="NumberFontNormal" font="Fonts\ARIALN.TTF" outline="NORMAL" virtual="true">
<FontHeight><AbsValue val="14"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="NumberFontNormalYellow" inherits="NumberFontNormal" virtual="true">
<Color r="1.0" g="0.82" b="0"/>
</Font>
<Font name="NumberFontNormalSmall" font="Fonts\ARIALN.TTF" outline="THICK" virtual="true" monochrome="true">
<FontHeight><AbsValue val="12"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="NumberFontNormalSmallGray" inherits="NumberFontNormalSmall" outline="THICK" virtual="true">
<Color r="0.6" g="0.6" b="0.6"/>
</Font>
<Font name="NumberFontNormalLarge" font="Fonts\ARIALN.TTF" outline="NORMAL" virtual="true">
<FontHeight><AbsValue val="16"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="NumberFontNormalHuge" font="Fonts\skurri.ttf" outline="THICK" virtual="true">
<FontHeight><AbsValue val="30"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<!-- ChatFontNormal: ARIALN, 14px, white, (1,-1) black shadow (ref l.180). -->
<Font name="ChatFontNormal" font="Fonts\ARIALN.TTF" virtual="true">
<FontHeight><AbsValue val="14"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
<Shadow>
<Offset><AbsDimension x="1" y="-1"/></Offset>
<Color r="0" g="0" b="0"/>
</Shadow>
</Font>
<!-- The quest/parchment fonts (ref l.191-215): MORPHEUS 18 title with a warm-brown (0.49,0.35,0.05)
shadow; the FRIZQT body fonts are dark-on-parchment and SHADOWLESS (QuestFontNormalSmall
chains through GameFontBlack, not MasterFont). -->
<Font name="QuestTitleFont" font="Fonts\MORPHEUS.ttf" virtual="true">
<FontHeight><AbsValue val="18"/></FontHeight>
<Color r="0" g="0" b="0"/>
<Shadow>
<Offset><AbsDimension x="1" y="-1"/></Offset>
<Color r="0.49" g="0.35" b="0.05"/>
</Shadow>
</Font>
<Font name="QuestFont" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="13"/></FontHeight>
<Color r="0" g="0" b="0"/>
</Font>
<Font name="QuestFontNormalSmall" inherits="GameFontBlack" virtual="true">
<Color r="0.30" g="0.18" b="0"/>
</Font>
<Font name="QuestFontHighlight" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="14"/></FontHeight>
<Color r="0" g="0" b="0"/>
</Font>
<!-- The MORPHEUS 15px book/mail body fonts (ref l.216-229). -->
<Font name="ItemTextFontNormal" font="Fonts\MORPHEUS.TTF" justifyH="LEFT" virtual="true">
<FontHeight><AbsValue val="15"/></FontHeight>
<Color r="0.18" g="0.12" b="0.06"/>
</Font>
<Font name="MailTextFontNormal" font="Fonts\MORPHEUS.TTF" justifyH="LEFT" virtual="true">
<FontHeight><AbsValue val="15"/></FontHeight>
<Color r="0.18" g="0.12" b="0.06"/>
</Font>
<!-- SubSpellFont: FRIZQT 10, dark brown (ref l.231). -->
<Font name="SubSpellFont" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="10"/></FontHeight>
<Color r="0.35" g="0.2" b="0"/>
</Font>
<!-- The dialog (StaticPopup) button pair: FRIZQT 16 (ref l.237-245). -->
<Font name="DialogButtonNormalText" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="16"/></FontHeight>
<Color r="1.0" g="0.82" b="0.0"/>
</Font>
<Font name="DialogButtonHighlightText" inherits="DialogButtonNormalText" virtual="true">
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<!-- The zone-announce banners: THICK-outlined FRIZQT; the ref's bare `<Shadow/>` transcribed
as-is (offset defaults, i.e. no visible offset) (ref l.246-257). -->
<Font name="ZoneTextFont" font="Fonts\FRIZQT__.TTF" outline="THICK" virtual="true">
<FontHeight><AbsValue val="102"/></FontHeight>
<Color r="1.0" g="0.9294" b="0.7607"/>
<Shadow/>
</Font>
<Font name="SubZoneTextFont" font="Fonts\FRIZQT__.TTF" outline="THICK" virtual="true">
<FontHeight><AbsValue val="26"/></FontHeight>
</Font>
<Font name="ErrorFont" inherits="GameFontNormalLarge" virtual="true"/>
<Font name="TextStatusBarText" inherits="NumberFontNormal" virtual="true"/>
<Font name="TextStatusBarTextSmall" font="Fonts\ARIALN.TTF" outline="NORMAL" virtual="true" monochrome="false">
<FontHeight><AbsValue val="12"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="CombatLogFont" inherits="GameFontHighlight" justifyH="LEFT" virtual="true"/>
<!-- The tooltip family: FRIZQT white, no shadow (ref l.267-285). -->
<Font name="GameTooltipText" font="Fonts\FRIZQT__.TTF" justifyH="LEFT" virtual="true">
<FontHeight><AbsValue val="12"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="GameTooltipTextSmall" font="Fonts\FRIZQT__.TTF" justifyH="LEFT" virtual="true">
<FontHeight><AbsValue val="10"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="GameTooltipHeaderText" font="Fonts\FRIZQT__.TTF" justifyH="LEFT" virtual="true">
<FontHeight><AbsValue val="14"/></FontHeight>
<Color r="1.0" g="1.0" b="1.0"/>
</Font>
<Font name="WorldMapTextFont" font="Fonts\FRIZQT__.TTF" outline="THICK" virtual="true">
<FontHeight><AbsValue val="102"/></FontHeight>
<Color r="1.0" g="0.9294" b="0.7607"/>
<Shadow/>
</Font>
<!-- The invoice (auction mail) parchment fonts (ref l.293-304). -->
<Font name="InvoiceTextFontNormal" font="Fonts\FRIZQT__.TTF" justifyH="LEFT" virtual="true">
<FontHeight><AbsValue val="12"/></FontHeight>
<Color r="0.18" g="0.12" b="0.06"/>
</Font>
<Font name="InvoiceTextFontSmall" font="Fonts\FRIZQT__.TTF" justifyH="LEFT" virtual="true">
<FontHeight><AbsValue val="10"/></FontHeight>
<Color r="0.18" g="0.12" b="0.06"/>
</Font>
<!-- CombatTextFont: FRIZQT 25, gold, MasterFont shadow (ref l.305). -->
<Font name="CombatTextFont" inherits="MasterFont" font="Fonts\FRIZQT__.TTF" virtual="true">
<FontHeight><AbsValue val="25"/></FontHeight>
<Color r="1.0" g="0.82" b="0"/>
</Font>
</Ui>