Quasar Posted February 27, 2009 I've completed addition of a new EDF font engine for Eternity. There are two types of fonts that can be specified: patch fonts, which work like the traditional type of DOOM font, where each letter has its own patch graphic; and block fonts, where the entire font is stored in a single graphic and is blitted to the screen with a very fast masked block drawing routine. The full EDF specification: font <mnemonic> { id = <number> start = <number> OR <char> end = <number> OR <char> linesize = <number> spacesize = <number> widthdelta = <number> tallestchar = <number> centerwidth = <number> colorable = <boolean> uppercase = <boolean> blockcentered = <boolean> patchnumoffset = <number> linearformat = <string> linearlump = <string> // One or more of the following are required: filter { // A filter must either specify THESE: start = <number> OR <char> end = <number> OR <char> // OR this: chars = { <number> OR <char>, ... } // Mask is required and can contain one and only // one optional C printf integer or character // formatting sequence mask = <string> } } Explanation of the fields: id : This is the numeric ID of the font, which is useful in Small scripting for setting the font to HUD widgets. start : The first character in the font, in ASCII order. end : The last character in the font, in ASCII order. All of the following fields are only relevant to patch fonts: linesize : The amount to step in y coords when a line break is hit. spacesize : Width of a blank space (including characters with no patch specified). widthdelta : An amount subtracted from the width of a character when stepping in x coords to the next character. "1" is a typical value, used by the main Heretic font for example. tallestchar : The absolute tallest character in the font. Needed for situations when text is drawn relative to the bottom of a clipping rectangle (such as the screen buffer). centerwidth : Used for block-centered fonts only. Characters are centered within squares of this size. Hard to understand, and rarely needed. colorable : This font does/doesn't support text color translations. uppercase : This font does/doesn't treat text as all-caps. blockcentered : Centers each character within uniformly spaced blocks of "centerwidth" size; really a special hack for the Heretic intermission screen... patchnumoffset : An amount to subtract from the character amount when calculating the number that is part of a patch font's lump names. For Heretic FONTA and all gamemodes' FONTBs, this value is 32. To make a block font is drastically more simple. You only have to specify one field if the lump format is linear (raw, headerless 8-bit like Heretic's title screen, or a flat); this increases to two fields if the format is a patch (which is converted into a linear block of data at runtime): linearlump : The lump to use for the entire block font. linearformat : Either "linear" or "patch" currently. Linear is the default value. When a font is determined to be linear, all of the other fields in the font are given forced default values that work with the linear font blitting code. Filters: To make a patch font, it is necessary to identify to the game engine what patches make up the font. This can either be very simple or very complicated depending on how wisely you name your font's graphic lumps. When loading each font glyph, the filters are applied in the order in which they are specified in the font object. Each filter can specify a range of characters to which it applies, or a list of one or more explicit character values. The filter is used by taking the character's ASCII value, subtracting the optional "patchnumoffset" value from it, and formatting that number into the "mask" string, like in this example: filter { start = '!'; end = 0x7f; mask = "STCFN%.3d" } For ASCII character 'A', this would load STCFN065 because the ASCII value of 'A' is 65. This does require some basic knowledge of C printf format specifiers, but this required knowledge never exceeds how to print a width-limited integer. (For those alarmist types, this mask formatting string is stringently analyzed for attempts to exploit printf vulnerabilities. Only one specifier is allowed, and it must be of types c, i, d, x, X, o, or u when it exists.) Since all of this is overwhelming, here are some real-world examples from the new fonts.edf files in Eternity's base directory: // Console font font ee_consolefont { id = 4; linearlump = "CONCHARS"; } // Small font - this is used by the HUD, finale, and V-system by default font ee_smallfont { id = 0; start = '!'; end = 0x7f; linesize = 8; spacesize = 4; tallestchar = 8; colorable = true; uppercase = true; filter { start = '!'; end = 0x7f; mask = "STCFN%.3d" } } // And this is just to show that it can be unnecessarily // complicated if you make your lump naming scheme completely // illogical (Thanks BOOM team...): // Hud overlay font - used by BOOM-style HUD font ee_hudfont { id = 1; start = '!'; end = 0x7f; linesize = 8; spacesize = 4; tallestchar = 8; colorable = true; uppercase = true; filter { start = '0'; end = '9'; mask = "DIG%c" } filter { start = 'A'; end = 'Z'; mask = "DIG%c" } filter { chars = { 45, 47, 58, 91, 93 }; mask = "DIG%i" } filter { start = 123; end = 127; mask = "STBR%i" } filter { chars = { '_' }; mask = "DIG45" } filter { chars = { '(' }; mask = "DIG91" } filter { chars = { ')' }; mask = "DIG93" } } 0 Quote Share this post Link to post
esselfortium Posted February 27, 2009 Very cool! :) edit: Nvm, question answered. 0 Quote Share this post Link to post
Quasar Posted February 27, 2009 BTW I forgot to explain the fact that you can override the default fonts used by all native subsystems, including the HUD, HUD overlay, menus, finale, and intermission via a series of new global EDF variables :) It works like this example: hu_overlayfont = MyNewOverlayFont; 0 Quote Share this post Link to post
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.