<?xml version="1.0"?>
<!DOCTYPE riscos-prm PUBLIC "-//Gerph//DTD PRM documentation 1.02//EN"
                            "http://gerph.org/dtd/102/prm.dtd">

<riscos-prm>
<chapter title="FontMap">
<section title="Introduction and Overview">
<p>
The FontMap module provides two functions:
</p>
<p>
<list>
    <item>A means by which font names from other systems can be converted to RISC OS font names used by FontManager</item>
    <item>A means by which a font's properties can be returned and manipulated</item>
</list>
</p>
<p>
    The FontMap module allows conversion of the names os fonts from Windows (which have generally been converged upon). These font mappings are intended to be extended and configurable on a given system.
</p>
<p>
    The font properties which the FontMap module manages are those that can be derived from the font name - the weight, obliqueness, and condensedness features.
</p>

</section>


<section title="Technical details">
    <subsection title="Font naming systems">
<p>
    The FontMap module handles two naming systems, but has scope to be expanded with more in the future. The module specifically handles the RISC OS naming system, and the Windows naming system. Although the system is called 'Windows', it is actually a more widely adopted naming scheme due to the specification of fonts on websites and the availability of fonts.
</p>
<p>
    There is another naming system which is not supported by FontMap at present - the PostScript font naming system. This is partially catered for by the Printer driver system, so is not explicitly handled in the FontMap module.
</p>
<p>
    The font naming systems use the following values:
    <value-table>
        <value number="0">RISC OS</value>
        <value number="1">Windows</value>
        <value number="2-7">Reserved</value>

    </value-table>
</p>
    </subsection>

    <subsection title="Font naming components">
<p>
Fonts consist of four major features which can be recognised by the FontMap module:
</p>

<p>
<list>
    <item>The font family name, for example 'Homerton' or 'Helvetica'.</item>
    <item>The weight of the font, for example 'Bold', or 'Light'.</item>
    <item>The obliqueness of the font, which is commonly given as 'Oblique' or 'Italic'.</item>
    <item>The stretchedness of the font, which is commonly given as 'Condensed' or 'Expanded'.</item>
</list>
</p>

<p>The properties recognised here take their inspiration from the
    <reference type='link' name="https://www.w3.org/TR/SVG10/fonts.html#FontFaceElement">SVG 'font-face' element</reference>, which is itself based on the CSS 2 '@font-face' facility.
</p>

<category title="Font family">
<p>
    The font family generally groups fonts which have the stylistic design. How characters are formed, and how they relate to one another is what distinguishes the families of fonts. The FontMap module can perform a mapping between these font families where they are sufficiently similar. This is necessary because RISC OS does not use the same standardised names for its fonts as are used elsewhere.
</p>

<p>
    For example, the RISC OS font family has similar stylistic design to the font used elsewhere as 'Helvetica'. The FontMap module allows a translation between these font names to produce an approximation of the original intent. This translation is (commonly) bidirectional, so that as well as importing content which uses the foreign naming schemes to RISC OS, the RISC OS font names can be translated to the equivalent foreign font names.
</p>
</category>

<category title="Font weight">
<p>
    The weight of a font indicates the relative darkness or heaviness of the text. There is no standardised naming scheme for the weights of gonts, but there are commonly used weight names that are used in a self-consistent continuum within a family.
</p>
<p>
    The FontMap module assigns these weights values which can be compared and used to understand the relationship between different fonts within the family.
</p>
<p>
    <value-table>
        <value number="0">Don't care - a value that can be requested when any suitable weight is accepted</value>
        <value number="100">Thin</value>
        <value number="200">Extra light</value>
        <value number="300">Light</value>
        <value number="400">Regular</value>
        <value number="500">Medium</value>
        <value number="600">Semi-bold</value>
        <value number="700">Bold</value>
        <value number="800">Extra bold</value>
        <value number="900">Black</value>
    </value-table>
</p>
</category>

<category title="Font obliqueness">
<p>
    The obliqueness of a font indicates whether the font is set at an angle (which is usually used for emphasis), or not. Within the FontMap module this is a binary choice - either the font is at an angle or it is not.
</p>

<p>
    Stylistically, the font may differentiate the manner in which it is angled. Generally, 'Oblique' fonts are the same as the non-oblique font, but with a simple transformation applied to make the top of the font lean rightwards. 'Italic' fonts are those that have been specially crafted to look different when set at an angle, sometimes with different ornamentation or flourishes, or with different emphasis on components of the characters.
</p>

<p>
    The FontMap module does not differentiate between 'Italic' and 'Oblique' variants of a font, but treats both as the same state in its values. The FontMap module has no support for the degree to which the font is angled, and has no support for reverse leaning fonts. The values used by the module for obliqueness are:
</p>

<p>
    <value-table>
        <value number="0">Don't care - a value that can be requested when any suitable obliqueness is accepted</value>
        <value number="1">Plain, not at any angle</value>
        <value number="2">Oblique or italic</value>
    </value-table>
</p>
</category>

<category title="Font stretch">
<p>
    The stretch of a font gives a relative measure of how much wider or thinner a font is than others within the same family. As with the font weight names, there is no standardised naming for these features, but a continuum within a given font is usually expected.
</p>

<p>
    The values used by FontMap are:
</p>

<p>
    <value-table>
        <value number="0">Don't care - a value that can be requested when any suitable stretch is accepted</value>
        <value number="100">Ultra-condensed</value>
        <value number="200">Extra-condensed</value>
        <value number="300">Condensed</value>
        <value number="400">Semi-condensed</value>
        <value number="500">Normal</value>
        <value number="600">Semi-expanded</value>
        <value number="700">Expanded</value>
        <value number="800">Extra-expanded</value>
        <value number="900">Ultra-expanded</value>
    </value-table>
</p>
</category>
</subsection>


<subsection title="FontMap mappings file">
<p>
    The Font Mapping file describes the translation between formats. It is configured through the <reference type="sysvar" name="FontMap$Mappings"/> variable.
</p>
<p>
The translation file is a text file containing lines for mappings between the formats. The file has a simple line oriented format, which uses '#' character prefix for comments. Other lines consist of:
</p>

<p>
<list>
    <item>The source system format, either an 'R' or a 'W' for RISC OS or Windows format of font family.</item>
    <item>The conversion type, either a '-' or a '>'. '-' indicates a bidirectional conversion between the source and destination system formats. '>' indicates a unidirectional conversion.</item>
    <item>The destination system format, either an 'R' or a 'W' for RISC OS or Windows format of font family.</item>
    <item>A colon (':') separator.</item>
    <item>The source font family name.</item>
    <item>A colon (':') separator.</item>
    <item>The destination font family name.</item>
</list>
</p>

<p>Described in ABNF the format is:</p>

<p>
<bnf xmlns="http://gerph.org/dtd/bnf/100/bnf.dtd"
     caption="Syntax for FontMap mappings files">
 <rule-def name="mapping-file">
  <rule-use name="mapping-line" repeat="true"/>
 </rule-def>

 <rule-def name="mapping-line">
    <group alternates="true" optional="true">
        <rule-use name="comment"/>
        <rule-use name="rule"/>
    </group>
    <rule-use name="LF"/>
</rule-def>

<rule-def name="comment">
    <literal string="#"/>
    <group alternates="true" repeat="true">
        <rule-use name='SP'/>
        <rule-use name='VCHAR'/>
    </group>
</rule-def>

<rule-def name="rule">
    <rule-use name='src-system'/>
    <rule-use name='conversion'/>
    <rule-use name='dst-system'/>
    <literal string=":"/>
    <rule-use name='src-family'/>
    <literal string=":"/>
    <rule-use name='dst-family'/>
</rule-def>

<rule-def name="src-system">
 <rule-use name='system'/>
</rule-def>

<rule-def name="dst-system">
 <rule-use name='system'/>
</rule-def>

<rule-def name="conversion">
    <group alternates="true">
     <literal string="-"/>
     <literal string="&gt;"/>
    </group>
</rule-def>

<rule-def name="src-family">
 <rule-use name='family'/>
</rule-def>

<rule-def name="dst-family">
 <rule-use name='family'/>
</rule-def>

<rule-def name="family">
    <group alternates="true" repeat-min="1">
        <rule-use name='SP'/>
        <rule-use name='ALPHA'/>
        <rule-use name='DIGIT'/>
        <literal string="-"/>
        <literal string="_"/>
    </group>
</rule-def>

</bnf>
</p>

<p>
    By default the FontMap module will use a font mapping file that looks similar to the following:
</p>

<p>
<extended-example type='format'>
# Foreign font mappings
#
# Cut down form as fallback for ROM.

# Standard mappings for RISC OS and Windows fonts
R-W:Trinity:Times New Roman
R-W:Homerton:Arial
W>R:Helvetica:Homerton
R-W:Corpus:Courier New
</extended-example>
</p>
</subsection>


<subsection title="Translating font names">
<p>
    The <reference type='swi' name="FontMap_Translate"/> SWI provides a means of applying these properties and mappings to font names. The FontMap module will try to satisfy requests using the information available to it from the FontManager and the font mapping file.
</p>
<p>
    The translation process goes through simple steps to translate the fonts:
</p>

<p>
<list type='ordered'>
    <item>Identify the input font and its properties in the input font system. This means extracting the font properties from the name, and identifying the font family.</item>
    <item>Replace any of the properties from the input font with those supplied by the user.</item>
    <item>Map the font family name from the input system to the output system.</item>
    <item>Search the output font system for a suitable font name for the closest match to the font required.</item>
    <item>Return the result to the caller.</item>
</list>
</p>

<p>This process is expected to be inexact when translating between font systems. Different property inputs may match multiple fonts - for example, if an Extra Bold weight font is requested, but only Bold is available, the Bold will be returned, just as it would if Bold weight had been requested.</p>

<p>
    When translating RISC OS fonts, the FontMap module is able to synthesise oblique fonts by using a font transformation matrix. This is only performed when there is no suitable oblique or italic font.
</p>
</subsection>

</section>


<section title="System variables">
<sysvar-definition name="FontMap$Mappings"
                   description="Filename of the FontMap mappings definition">
<use>
<p>The <sysvar>FontMap$Mappings</sysvar> variable contains a filename which should be used for the mappings to and from RISC OS font names. The file's format is described in the <reference type='subsection' name="FontMap mappings file"/>.
</p>

</use>

<related>
    <reference type="swi" name="FontMap_Translate" />
</related>
</sysvar-definition>
</section>


<section title="SWI calls">
<swi-definition name="FontMap_Translate"
                number="57F00"
                description="Perform a translation of the supplied font name"
                irqs="undefined"
                fiqs="enabled"
                processor-mode="SVC"
                re-entrant="no">

<entry>
  <register-use number="0">Flags:
    <bitfield-table>
        <bit number="0-2">Input <reference type="subsection" name="Font naming systems">font name system</reference></bit>
        <bit number="3-5">Output <reference type="subsection" name="Font naming systems">font name system</reference></bit>
    </bitfield-table>
  </register-use>
  <register-use number="1">Pointer to a zero-terminated font name</register-use>
  <register-use number="2">Requested <reference type="category" name="Font obliqueness">font oblique state</reference>, or 0 for a default</register-use>
  <register-use number="3">Requested <reference type="category" name="Font weight">font weight</reference>, or 0 for a default</register-use>
  <register-use number="4">Requested <reference type="category" name="Font stretch">font stretch state</reference>, or 0 for a default</register-use>
  <register-use number="5">Pointer to output buffer for font name, or 0 to just request the length required</register-use>
  <register-use number="6">Length of the font buffer</register-use>
</entry>

<exit>
  <register-use number="0" state="preserved"/>
  <register-use number="1" state="preserved"/>
  <register-use number="2">Returned font oblique state</register-use>
  <register-use number="3">Returned font weight</register-use>
  <register-use number="4">Returned font stretch state</register-use>
  <register-use number="5" state="preserved" />
  <register-use number="6">Number of bytes written to the output buffer, including the terminator</register-use>
</exit>

<use>
<p>The Font_Translate SWI is used to either convert between RISC OS and foreign font naming systems, or to apply styling to a font name. The requested properties will be matched as closely as possible for a given font, and the actual matched font's properties will be returned. Because the closest match for a given font may not be suitable, callers may wish to check the returned properties.</p>

<p>If no translation is required, and only the font properties are desired, R5 may be set to 0. This will perform the translation and update the properties in the return registers, but no font name will be returned.</p>

<p>If the font name will not fit into the output buffer, the value of R6 will be updated to the size required, and the Buffer overflow (error number &hex;1E5) error will be returned.</p>

</use>

<related>
<!-- <reference type="vector" name="BingleV" /> -->
</related>

</swi-definition>
</section>


<section title="Error messages">

<error-definition name="BadFlags"
                  number="81AE40"
                  description="Invalid flags were supplied to FontMap"
                  >

<use>
<p>This error is returned by the FontMap module when the flags supplied in R0 are not recognised.</p>
</use>

<related>
<reference type="swi" name="FontMap_Translate" />
</related>

</error-definition>

<error-definition name="BadMappingType"
                  number="81AE41"
                  description="Invalid font format mapping was requested of FontMap"
                  >

<use>
<p>This error is returned by the FontMap module when the input or output font system supplied in R0 was not recognised.</p>
</use>

<related>
<reference type="swi" name="FontMap_Translate" />
</related>

</error-definition>

<error-definition name="NoMappingAvailable"
                  number="81AE42"
                  description="No equivalent font name available"
                  >

<use>
<p>This error is returned by the FontMap module when the font name, or the font family name, was nor recognised, or when the equivalent font is not available in the output font system.</p>
</use>

<related>
<reference type="swi" name="FontMap_Translate" />
</related>

</error-definition>

</section>



<section title="Examples">
<p>
Reading the properties of a font:
</p>

<extended-example type='basic'>
&gt;DIM buf% 256
&gt;SYS "FontMap_Translate",(0&lt;&lt;0) OR (0&lt;&lt;0), "Homerton.Medium", 0,0,0 TO ,,oblique,weight,stretch
&gt;PRINT oblique, weight, stretch
         1       500       500
</extended-example>

<p>
Making a font bold:
</p>

<extended-example type='basic'>
&gt;DIM buf% 256
&gt;SYS "FontMap_Translate",(0&lt;&lt;0) OR (0&lt;&lt;0), "Homerton.Medium", 0,900,0,buf%,256 TO ,,oblique,weight,stretch,font$
PRINT oblique, weight, stretch; " - ";font$
         1       900       500 - Homerton.Bold
</extended-example>

</section>

</chapter>

<!-- MetaData -->
<meta>
 <maintainer>
  <email name="Charles Ferguson" address="gerph@gerph.org" />
 </maintainer>
 <disclaimer>
    <p>
        &copy; Gerph.
    </p>
 </disclaimer>

 <history>
  <revision number="1" author="Gerph" date="17 Oct 2020" title="Initial version for 0.05">
    <change>Initial documentation created for the old module.</change>
  </revision>
 </history>
</meta>
</riscos-prm>
