<!DOCTYPE chapter PUBLIC "-//Davenport//DTD DocBook V3.0//EN"[
<!ENTITY wrt "with respect to">
]>

<chapter>
  <docinfo>
    <edition/First official draft for first release/
    <author>
      <firstname/Yann/
      <surname/Dirson/
      <authorblurb>
	<simpara>
	  Current maintainer of the Linux Console Tools
	</simpara>
      </authorblurb>
      <contrib/Original design and specifications/
    </author>
    <copyright>
      <year/1997,98,99/
      <holder>Yann Dirson 
	<comment><email>dirson@debian.org</email></comment>
      </holder>
    </copyright>
    <legalnotice>
      <simpara>
	You may do what you want with it according to the GPL, version
	2, except from redistributing a modified version with the same
	name without permission from the original authors.
      </simpara>
    </legalnotice>
  </docinfo>

  <title>eXtended PC Font Format (XPSF) -- draft specifications</title>

		    
  <important>
    <title>IMPORTANT NOTICE</title>
    <simpara>
      This document is a draft for a file-format.  Please do not use
      it yet to implement any software.  You may do what you want with
      it according to the GPL, version 2, except from redistributing a
      modified version with the same name without permission from the
      original authors.
    </simpara>
  </important>

<!--  
  <sect1>
    <title>Changes</title>

    <literallayout>
1999/05/25: started conversion to Docbook 3.0 DTD.
1999/05/25: clarified syntax explanation.
1999/05/25: dropped virtual font from the spec.
1999/05/06: dropped the format_version field, obsoleted by bitfields.
1999/05/06: redesigned the bitfield mechanism to use section ID's.
1999/05/06: misc reformulations
1998/10/08: replaced version-based compatibility mechanism with bitfields as suggested by hpa.
1998/10/08: reduced size of section-id from u16 to u8.
1998/10/08: compressed syntax description by using type definitions inside structure definitions.
1998/10/08: added section for copyright and license.
1998/10/08: fixed section-ids: obsolete xpsf_console_override_map was still allocated.
1998/10/08: mentionned VGA pseudo-9bit-wide characters.
1998/10/08: proposed a 4-byte magic.
1998/10/08: don't allow a glyph to have no UTF8 mapping.
1998/10/08: use UTF8 instead of UCS2 to describe glyphs.
1998/08/06: `=' in the description grammar was ambiguous - replaced one of the 2 meanings with `:'.
1998/08/06: changed how integer types are named.
1998/08/06: added note that virtual fonts may not be necessary.
1998/04/20: updated author's e-mail.
1998/04/20: changed ref from libconsole to libcfont.
1998/04/20: suggested more width for magic.
1998/04/20: changed section name from xpsf_font_data to xpsf_fixed_font_data.
1998/04/20: minor clarifications.
1997/09/27: removed console-maps sections - I finally understand what they are for.
1997/09/04: initial draft release.
    </literallayout>
  </sect1>
-->

  <sect1><title/Summary/

    <simpara>
      The future XPSF format is intended to be a replacement for all
      current font-file formats used with the console utilities ('kbd'
      and `console-tools').  For this, it is intended to have all
      features from the PSF, CPI, and CP file-formats, and more.
    </simpara>
    <simpara>
      Functions to manipulate files in the XPSF format will be
      included in <literal/libcfont/, provided as a sample
      implementation.  Tools to handle them and convert to/from XPSF
      will be provided together with the library.
    </simpara>
  </sect1>

  <sect1><title/Requirements/
    <para>
      <orderedlist>
	<listitem id="req-ident">
	  <formalpara><title id="lbl-req-ident"/Identification/
	    <para>
	      An XPSF file should be easily identified as such with
	      a probability for mistakes as low as reasonable.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-magic" linkend="sol-magic"//.
	  </simpara>
	</listitem>

	<listitem id="req-extendable">
	  <formalpara><title id="lbl-req-extendable"/Extendability/
	    <para>
	      Should be easily extendable, while remaining as readable
	      as possible for any program knowing of older versions of
	      the file-format.  If however the file could be
	      mis-interpreted by a program not knowing about the new
	      features, there should be a mean to warn the program.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-sectionning" linkend="sol-sectionning"//,
	    <link endterm="lbl-sol-bitfields" linkend="sol-bitfields"//.
	  </simpara>
	</listitem>

	<listitem id="req-bw-compat">
	  <formalpara><title id="lbl-req-bw-compat"/Backward compatibility/
	    <para>
	      Similarly, backward compatibility has to be ensured,
	      but the existence in older version of the file-format of
	      obsolete section-types should not force a new program to
	      support these obsolete sections.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-bitfields" linkend="sol-bitfields"//.
	  </simpara>
	</listitem>

	<listitem id="req-multi-font-size">
	  <formalpara><title id="lbl-req-multi-font-size"/Multiple font-sizes/
	    <para>
	      Multiple font-sizes (both in height and width)
	      should be storable in one file.  This will allow to
	      prevent duplication of common data such as copyright
	      information, and mapping table, for different
	      renderings of a family of fonts.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-sectionning" linkend="sol-sectionning"//,
	    <link endterm="lbl-sol-any-size-bitmap" linkend="sol-any-size-bitmap"//.
	  </simpara>
	</listitem>

	<listitem id="req-shared-sfm">
	  <formalpara><title id="lbl-req-shared-sfm"/Shared font mappings/
	    <para>
	      A unique unicode-to-glyph mapping (SFM) should be
	      sharable by several sizes for a family of fonts, while
	      ensuring the mandatory association of an SFM with each
	      font.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-force-sfm" linkend="sol-force-sfm"//,
	    <link endterm="lbl-sol-any-size-bitmap" linkend="sol-any-size-bitmap"//.
	  </simpara>
	</listitem>

	<listitem id="req-mach-indep">
	  <formalpara><title id="lbl-req-mach-indep"/Machine independance/
	    <para>
	      File-format should be machine-independant.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-byte-ordering" linkend="sol-byte-ordering"//.
	  </simpara>
	</listitem>

	<listitem id="req-multi-sfm-range">
	  <formalpara><title id="lbl-req-multi-sfm-range"/Multiple mapping ranges/
	    <para>
	      XPSF should allow more than the UCS2 range for SFM's; it
	      should for example be able to support the full range of
	      UCS4 characters, and possibly other charset definitions.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-" linkend="sol-"//
	  </simpara>
	</listitem>

	<listitem id="req-memory-friendly">
	  <formalpara><title id="lbl-req-memory-friendly"/Easy
	      memory-efficient implementations/
	    <para>
	      Provide enough info, whatever redundant, to allow
	      just-sufficient malloc's while reading.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-" linkend="sol-"//
	  </simpara>
	</listitem>

	<listitem id="req-allow-9bit-vga">
	  <formalpara><title id="lbl-req-allow-9bit-vga"/Usability of
	      VGA pseudo-9bit fonts/
	    <para>
	      Make it possible to use textmode-VGA pseudo-9bit fonts.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-any-size-bitmap" linkend="sol-any-size-bitmap"//.
	  </simpara>
	</listitem>

	<listitem id="req-legal-avail">
	  <formalpara><title id="lbl-req-legal-avail"/Availability of legal informations/
	    <para>
	      Copyright and redistribution info MUST be included.  Too
	      many fonts are available on the net without such
	      information, and are thus legally unusable.
	    </para>
	  </formalpara>
	  <simpara>
	    Addressed by: <link endterm="lbl-sol-mandatory-copyright" linkend="sol-mandatory-copyright"//.
	  </simpara>
	</listitem>
	
      </orderedlist>
    </para>

    <!-- <link endterm="lbl-sol-" linkend="sol-"// -->

    <sect2><title/Things not yet fully formalized/
      <para>
	<orderedlist>
	  <listitem id="req-no-chains">
	    <formalpara><title id="lbl-req-no-chains"/No chained data/
	      <para>
		File format should be described by a sort of
		context-free grammar.
	      </para>
	    </formalpara>
	  </listitem>

	  <listitem id="req-skippable">
	    <formalpara><title id="lbl-req-skippable"/Skippable sections/
	      <para>
		h * All sections of a file should tell their length,
		in order to skip them easily (idea from Amiga's IFF
		file format).
	      </para>
	    </formalpara>
	  </listitem>

	  <listitem>
	    <simpara>
	      i * Font-size specific SFM overrides, for cases where
	      eg. some characters are (hopefully temporarily) not
	      available at one size).
	    </simpara>
	  </listitem>

	  <listitem id="req-vfont">
	    <formalpara><title id="lbl-req-vfont"/Virtual fonts/
	      <para>
		j * Maybe provide virtual fonts support, to avoid
		character-description duplication.  For example,
		building individual isoXX/codepages by mapping them
		into a larger font with a custom encoding will save
		the storage place needed by all those duplicated
		characters.  This one may not be necessary, and may be
		dropped in the final spec.
	      </para>
	    </formalpara>
	  </listitem>

	</orderedlist>
      </para>
    </sect2>
  </sect1>


  <sect1><title/Possible solutions/

    <orderedlist>
      <listitem id="sol-magic">
	<formalpara>
	  <title id="lbl-sol-magic"/Magic number/
	  <para>
	    I suggest a variation on the PSF magic number (which is
	    <literal/0x36 0x04/).  A 4-byte magic will lower the risk
	    of mis-interpreting random data as XPSF.  The <literal/0x36
	    0x05 0x84 0xBF/ sequence seems unassigned - it will have
	    to be registered.
	  </para>
	</formalpara>
	<simpara>
	  Addresses: <link endterm="lbl-req-ident" linkend="req-ident"//.
	</simpara>
      </listitem>

      <listitem id="sol-sectionning">
	<formalpara><title id="lbl-sol-sectionning"/File sectionning/
	  <para>
	    Extendability can be achieved through file sectionning,
	    each section containing an identifier announcing its
	    content-type.  Several sections with the same content type
	    are allowed in the same XPSF file (eg. several bitmap
	    sizes for the same font-family).  Upward readability can
	    be achieved by additionnaly providing at the very start of
	    each section header the length of the full section.
	  </para>
	</formalpara>
	<simpara>
	  Addresses: <link endterm="lbl-req-extendable" linkend="req-extendable"//,
	  <link endterm="lbl-req-multi-font-size" linkend="req-multi-font-size"//.
	</simpara>
      </listitem>

      <listitem id="sol-bitfields">
	<formalpara><title id="lbl-sol-bitfields"/Bit fields for
	    section features/
	  <para>
	    Sections will be listed in this specification, and will
	    each be assigned a bit in a bitfield structure, according
	    to their section ID (a section of id S will use bit S in
	    the bitfield -- that is a bitmask of (1&lt;&lt;S)).  An
	    XPSF file will contain 2 instances of this bitfield
	    structure, used to respectively declare <emphasis>R/O
	    compatibility</emphasis> and <emphasis/incompatibility/ of
	    a reader not knowing of these sections:
	    <itemizedlist>
	      <listitem>
		<simpara>
		  When a reader does not support a feature declared as
		  <emphasis>R/O compatibility</emphasis> in a file, it
		  may still interpret those other sections it
		  supports, at the expense of not making profit of
		  those <emphasis>R/O compatibility</emphasis>
		  sections it doesn't know about (it must then not
		  attempt to modify this file).
		</simpara>
	      </listitem>
	      <listitem>
		<simpara>
		  When a reader does not support a section tagged with
		  <emphasis/incompatibility/, it will know that even
		  when attempting to read the sections it otherwise
		  supports, it would mis-interpret them because of
		  this section.
		</simpara>
	      </listitem>
	    </itemizedlist>
	    As the section ID for the mandatory copyright section is
	    <literal/0x00/, the corresponding bit in each field should
	    be ignored.
	  </para>
	</formalpara>
	<simpara>
	  Addresses: <link endterm="lbl-req-extendable" linkend="req-extendable"//,
	  <link endterm="lbl-req-bw-compat" linkend="req-bw-compat"//.
	</simpara>
	
	<formalpara>
	  <title/Possible implementations/
	  <para>
	    <variablelist>
	      <varlistentry>
		<term/Full fields/
		<listitem>
		  <simpara>
		    We only need 256=8*32 possible bits (the number of
		    possible sections) in a bitfield, that is 32
		    bytes.  This may be considered as small enough to
		    be included as a whole in the file header.
		  </simpara>
		</listitem>
	      </varlistentry>

	      <varlistentry>
		<term/Single range/
		<listitem>
		  <para>
		    An alternative would be not to include full
		    bitfields (not all possible feature IDs are
		    allocated, and a file will not usually use all of
		    them), but to include for each bitfield:
		    <itemizedlist>
		      <listitem>
			<simpara>
			  the useful range of bits, by specifying the
			  number of included bytes (not bits),
			</simpara>
		      </listitem>
		      <listitem>
			<simpara>
			  the index within the bitfield of the first
			  (least significant) bit in the range.
			</simpara>
		      </listitem>
		    </itemizedlist>
		  </para>
		  <simpara>
		    The simple way would be to use one byte for the
		    range index (248 possible values) and 5 bits for
		    the range width (32 possible values).  This would
		    allow for some invalid combinations of these 2
		    parameters, which suggests that we may compress
		    further these 13 bits.
		  </simpara>
		</listitem>
	      </varlistentry>	    

	      <varlistentry>
		<term/Single range, compressed/
		<listitem>
		  <simpara>
		    A still-to-be-defined more complex alternative
		    that would prevent those possible invalid
		    combinations, and could consume even less bits.
		    Maybe this can be scaled down enough to fit the
		    range-positionning parameters into 1 byte only
		    (yes, I <emphasis/am/ a genuine dreamer ;).
		  </simpara>
		</listitem>
	      </varlistentry>	    
	    </variablelist>
	  </para>
	</formalpara>
      </listitem>

      <listitem id="sol-obsolescence">
	<formalpara><title id="lbl-sol-obsolescence"/Section obsolescence/
	  <para>
	    Each section-type may become obsolete at any time; when it
	    occurs it will be documented in a special section of the
	    XPSF specs, stating the first version of the specs when
	    the section was declared obsolete.  A reading program
	    claming to implement a given version of the XPSF file
	    format will be allowed not to implement features declared
	    obsolete &wrt; the version it claims to implement, and the
	    <link endterm="lbl-sol-bitfields"
		  linkend="sol-bitfields"// mechanism will allow to detect old
	    files that should not be read.
	  </para>
	</formalpara>
	<simpara>
	  Addresses:
	</simpara>
      </listitem>

      <listitem id="sol-any-size-bitmap">
	<formalpara><title id="lbl-sol-any-size-bitmap"/Any-size font bitmaps/
	  <para>
	    Multiple font-sizes can be included as multiple sections
	    of a "font-data" type, which will allow to specify both
	    height and width, as some system - including Linux 2.2.x -
	    allow widths different from 8.  One byte per dimension
	    should be enough; one half-byte would be too small.
	    Should this <emphasis/one-byte/ choice prove to be not
	    sufficient at some (I think distant) time in the future, a
	    new "font-data" type allowing for more will be trivial to
	    add.

	    9-bit-wide VGA fonts can be encoded as standard 9-bit
	    fonts.  The reading software will check for VGA-ification
	    and take care of possibly reordering the chars.
	  </para>
	</formalpara>
	<simpara>
	  Addresses:<link endterm="lbl-req-multi-font-size" linkend="req-multi-font-size"//,
	  <link endterm="lbl-req-allow-9bit-vga" linkend="req-allow-9bit-vga"//,
	  <link endterm="lbl-req-shared-sfm" linkend="req-shared-sfm"//.
	</simpara>
      </listitem>

      <listitem id="sol-force-sfm">
	<formalpara><title id="lbl-sol-force-sfm"/Explicit font mappings/
	  <para>
	    Unicode font mappings (SFM's) will be described in
	    specific sections.  Each <literal/font-data/ section will
	    have a reference to the corresponding SFM in the file.
	    <footnote>
	      <simpara/This will even allow multiple maps in one file, FWIW./
	    </footnote>
	  </para>
	</formalpara>
	<simpara>
	  Addresses: <link endterm="lbl-req-shared-sfm" linkend="req-shared-sfm"//.
	</simpara>
      </listitem>

      <listitem id="sol-byte-ordering">
	<formalpara><title id="lbl-sol-byte-ordering"/Specific byte-ordering/
	  <para>
	    Allowing integers to be unambiguously interpreted requires
	    a convention for integer byte-ordering.  There are two
	    widely used alternatives:
	    <itemizedlist>
	      <listitem id="sol-big-endian">
		<formalpara><title id="lbl-sol-big-endian"/Big-endian byte-ordering/
		  <para>
		    This is the <emphasis/Internet network byte
		      order/, and there are (BSD) library calls
		      (<citerefentry><refentrytitle/htons/<manvolnum/3/</citerefentry>
		      and
		      <citerefentry><refentrytitle/htonl/<manvolnum/3/</citerefentry>)
		      available on most platforms to convert to this
		      byte-order.
		  </para>
		</formalpara>
	      </listitem>

	      <listitem id="sol-little-endian">
		<formalpara><title id="lbl-sol-little-endian"/Little-endian byte-ordering/
		  <para>
		    This is the alternative, which has no such
		    standard library calls to convert to and from.
		  </para>
		</formalpara>
	      </listitem>
	    </itemizedlist>
	  </para>
	</formalpara>
	<simpara>
	  Addresses: <link endterm="lbl-req-mach-indep" linkend="req-mach-indep"//
	</simpara>
      </listitem>

      <listitem id="sol-utf8-sfm">
	<formalpara><title id="lbl-sol-utf8-sfm"/Use of UTF8 for mapping tables/
	  <para>
	    f * UCS2, as shown in the PSF format, causes some waste of
	    space for common encodings, mainly due to the fact that we
	    need to use 0xFFFF as a separator.  Using UTF8 to describe
	    the mappings will allow to use only 0xFF as a separator.
	    The ASCII set will give us a small benefit too, being
	    encoded in 1 byte instead of 2, and most widly-used chars
	    will stay on 2 bytes (latin, cyrillic, arabic, hebrew...),
	    only more exotic chars will take one more byte.  This will
	    also make it possible to use chars outside of the Basic
	    Multilingal Plane (ie. UCS2).
	  </para>
	</formalpara>
	<simpara>
	  Addresses:  <link endterm="lbl-req-" linkend="req-"//
	</simpara>
      </listitem>

      <listitem id="sol-mapping-override">
	<formalpara><title id="lbl-sol-mapping-override"/Mapping-overrides sections/
	  <para>
	    i * Can be defined as a section refering to the map to be
	    overriden, and containing a list of override entries.
	  </para>
	</formalpara>
	<simpara>
	  Addresses:  <link endterm="lbl-req-" linkend="req-"//
	</simpara>
      </listitem>

      <listitem id="sol-count-fields">
	<formalpara><title id="lbl-sol-count-fields"><emphasis/count/ fields</title>
	  <para>
	    k * a "count" field has to be available before every
	    variable-size array.
	  </para>
	</formalpara>
	<simpara>
	  Addresses:  <link endterm="lbl-req-" linkend="req-"//
	</simpara>
      </listitem>

      <listitem id="sol-mandatory-copyright">
	<formalpara><title id="lbl-sol-mandatory-copyright"/Mandatory copyright section/
	  <para>
	    m * a specific section type describe copyright and
	    license.  It is the mandatory first section in an XPSF
	    file.  We distinguish the copyright string, such as "(c)
	    1997,98 John Doe and others", and the license, such as
	    "GPL" or a more descriptive text.  These strings shall be
	    UTF8-encoded to ensure they won't be erroneously displayed
	    using an incompatible charset.  Maybe it should be allowed
	    for an OS or a software package to install a separate text
	    file describing the license.  In this case the `license'
	    field in the XPSF file should be an absolute path to this
	    file (to be distinguished by the leading `/' (slash)
	    character), and the default behavior of the reading
	    software if this file is not available should be to fail
	    to read the font, with an explicit message.  A 'force'
	    option can be provided to force installation of the font.
	  </para>
	</formalpara>
	<simpara>
	  Addresses: <link endterm="lbl-req-legal-avail" linkend="req-legal-avail"//.
	</simpara>
      </listitem>

    <!-- <link endterm="lbl-req-" linkend="req-"// -->

      <listitem id="sol-">
	<para>
	  <note>
	    <simpara>This section may be removed at any time</simpara>
	  </note>
	  A 1st step would be to provide virtual mapping
	  into a single font (possibly larger).  The virtual-font
	  section will provide a reference to a single font-file, and
	  an array of size <replaceable/font_size/ of
	  character-positions telling for each fontpos in the virtual
	  font, in which fontpos the corresponding glyph should be
	  found.  The virtual-font section should be handled by
	  programs as as-many font-data sections that the target
	  font-file contains, using the relevant font_height and
	  font_width.  To save space and have some flexibility, the
	  references to the target characters will be allowed in
	  several sizes ; the chosen size will be specified in the
	  section as the number of bits.  It is expected that this
	  size will be a power of 2 compatible with available
	  computers (ie., in 1997: 8, 16, 32), but this is not
	  enforced, and programs may make use of other sizes, but then
	  SHOULD NOT rely on third-party XPSF-aware programs to be
	  able to read them.  Should the need arise, as an XPSF-file
	  can eventually contain several fonts with different
	  mappings, fields could be added in the virtual-font to
	  specify, if any, a mapping in the target file on which to
	  restrict target font-data sections (ie. only target sections
	  with this encoding will be seen by the virtual-font
	  section).  But placing different mappings in the same XPSF
	  file is discouraged, unless you really have use of it;
	  probably override-maps should be sufficient for most usages.
	</para>
	<simpara>
	  Addresses:  <link endterm="lbl-req-" linkend="req-"//
	</simpara>
      </listitem>

    </orderedlist>
  </sect1>


  <sect1><title/Draft specifications/

    <note>
      <simpara>
	This section was not updated yet to reflect recent changes in
	the design choices.  The overall structure is not likely to
	change, but some details may not reflect the current state of
	this draft.
      </simpara>
    </note>

    <para>The file format is described here in sort-of EBNF notation:
      <itemizedlist>
	<listitem>
	  <simpara>
	    Lower-case words (eg: <literal/xpsf_file/) represent
	    symbols defined in terms of other symbols;
	  </simpara>
	</listitem>

	<listitem>
	  <simpara>
	    The integer types are specified using their length
	    expressed in decimal notation, prefixed with <literal/u/
	    for unsigned types, or <literal/s/ for signed types.  Eg,
	    <literal/u16/ denotes a <emphasis/16-bit unsigned
	    integer/.
	  </simpara>
	</listitem>

	<listitem>
	  <simpara>
	    Upper-case words (eg: <literal/BIT/, <literal/UTF8/)
	    represent other symbols that won't be further decomposed;
	  </simpara>
	</listitem>

	<listitem>
	  <simpara>Composition of symbols:</simpara>
	  <itemizedlist>
	    <listitem>
	      <simpara>
		<literal/sym1 sym2/ is sym1 followed by sym2
	      </simpara>
	    </listitem>
	    <listitem>
	      <simpara>
		<literal/sym1 | sym2/ is either sym1 or sym2
	      </simpara>
	    </listitem>
	    <listitem>
	      <simpara>
		<literal/[sym]/ is an optional symbol
	      </simpara>
	    </listitem>
	    <listitem>
	      <simpara>
		<literal/{sym}/ is a symbol that can be repeated 0 or more times
	      </simpara>
	    </listitem>
	    <listitem>
	      <simpara>
		<literal/{sym}*N/ is a symbol that must be repeated
		<literal/N/ times (<literal/N/ may be the result of a
		numeric expression)
	      </simpara>
	    </listitem>
	    <listitem>
	      <simpara>
		<literal>(<replaceable/expression/)</literal> is a
		numeric expression
	      </simpara>
	    </listitem>
	  </itemizedlist>
	</listitem>

	<listitem>
	  <simpara>
	    Comments are introduced with a <literal/#/ sign.
	  </simpara>
	</listitem>
      </itemizedlist>
    </para>

    <programlisting role="grammar">
xpsf_file :
                xpsf_header
                xpsf_section            # id = xpsf_copyright
                {xpsf_section}

xpsf_header :
                magic_id
                header_length : u16
                font_size
                nb_sections : u16
                features_incompat : large_bitfield
                features_ro_compat : large_bitfield

# magic number proposal:
magic_id :
                u8 = <literal/0x36/
                u8 = <literal/0x05/
                u8 = <literal/0x84/
                u8 = <literal/0xBF/

font_size :
                u32             # number of chars in font - enough for UCS4 ;)
                                # note that as data_length is a u32 too, not all
                                # 16M chars of such a font would fit in one section.
                                # A new file-format will probably be needed before that :)

large_bitfield :
                real_size_1: u8 # effective width in bytes, minus 1
                {BIT}*(8*(real_size_1+1))

#

xpsf_section :
                xpsf_section_header
                xpsf_section_data

xpsf_section_header :
                header_length = 8
                data_length : u32
                section_id : u8

xpsf_section_data :
                  xpsf_copyright                # id = 0x00
                | xpsf_fixed_font_data          # id = 0x01
                | xpsf_UTF8_map                 # id = 0x02
                | xpsf_UTF8_override_map        # id = 0x03


# Copyright and distribution licence
# Appeared in release: 1

xpsf_copyright :
                copyright : string
                distribution_licence : string

string :
                string_length : u16
                {UTF8}*<replaceable/string_length/
                
# A bitmap font data of a particular size
# Appeared in release: 1

xpsf_fixed_font_data :
                char_height : u8
                char_width : u8
                {{BIT}*<replaceable/char_width/}*<replaceable/char_height/
                UTF8_map_ref : file_offset

file_offset :
                u32             


# Unicode fontpos-to-UTF8 map
# Appeared in release: 1

xpsf_UTF8_map :
                { UTF8_array psf_separator }*<replaceable/font_size/

UTF8_array :
                UTF8                    # at least one.
                { UTF8 }                # any necessary number of times

UTF8 :
                u8                      # at least 1 byte
                {u8}

psf_separator :
                u8 = 0xFF

# Unicode fontpos-to-UTF8 override-map
# Appeared in release: 1

xpsf_UTF8_override_map :
                parent_map : file_offset
                nb_entries : u16
                fontpos_size
                { fontpos UTF8 {UTF8} psf_separator }*<replaceable/nb_entries/

fontpos_size :
                u8                      # typically 8, 16 or 32

fontpos :
                {BIT}*<replaceable/fontpos_size/
    </programlisting>
  </sect1>
</chapter>
