<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <link rel="stylesheet" href="style.css" type="text/css"> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <link rel="Start" href="index.html"> <link rel="Up" href="index.html"> <link title="Index of types" rel=Appendix href="index_types.html"> <link title="Index of values" rel=Appendix href="index_values.html"> <link title="Index of modules" rel=Appendix href="index_modules.html"> <link title="Otfm" rel="Chapter" href="Otfm.html"><link title="Tags" rel="Section" href="#1_Tags"> <link title="Unicode code points" rel="Section" href="#1_Unicodecodepoints"> <link title="Decode" rel="Section" href="#1_Decode"> <link title="Table decoding" rel="Section" href="#1_Tabledecoding"> <link title="Limitations" rel="Section" href="#limitations"> <link title="Examples" rel="Section" href="#examples"> <link title="Convenience decodes" rel="Subsection" href="#convenience"> <link title="cmap table" rel="Subsection" href="#cmap"> <link title="head table" rel="Subsection" href="#head"> <link title="hhea table" rel="Subsection" href="#hhea"> <link title="hmtx table" rel="Subsection" href="#hmtx"> <link title="name table" rel="Subsection" href="#name"> <link title="OS/2 table" rel="Subsection" href="#os2"> <link title="kern table" rel="Subsection" href="#kern"> <title>Otfm</title> </head> <body> <div class="navbar"> <a class="up" href="index.html" title="Index">Up</a> </div> <h1>Module <a href="type_Otfm.html">Otfm</a></h1> <pre><span class="keyword">module</span> Otfm: <code class="code"><span class="keyword">sig</span></code> <a href="Otfm.html">..</a> <code class="code"><span class="keyword">end</span></code></pre><div class="info"> OpenType font decoder. <p> <b>WARNING.</b> This interface is subject to change in the future. <p> <code class="code"><span class="constructor">Otfm</span></code> is an in-memory decoder for the OpenType font data format. It provides low-level access to OpenType fonts tables and functions to decode some of them. <p> Consult the <a href="Otfm.html#limitations">limitations</a> and <a href="Otfm.html#examples">example</a> of use. <p> <b>Note.</b> Unless otherwise specified the strings returned are UTF-8 encoded. <p> <em>Release 0.1.0 — Daniel Bünzli <daniel.buenzl i@erratique.ch> </em> <h3 id="3_References">References</h3> <ul> <li>Microsoft. <em><a href="http://www.microsoft.com/typography/otspec/default.htm"> The OpenType Specification</a></em>, 2009.</li> </ul> <br> </div> <hr width="100%"> <br> <h1 id="1_Tags">Tags</h1><br> <pre><span id="TYPEtag"><span class="keyword">type</span> <code class="type"></code>tag</span> </pre> <div class="info"> The type for OpenType tags.<br> </div> <pre><span class="keyword">module</span> <a href="Otfm.Tag.html">Tag</a>: <code class="code"><span class="keyword">sig</span></code> <a href="Otfm.Tag.html">..</a> <code class="code"><span class="keyword">end</span></code></pre><div class="info"> Tags. </div> <br> <h1 id="1_Unicodecodepoints">Unicode code points</h1> <p> For some reason OpenType allows the (textually meaningless) <a href="http://unicode.org/glossary/#surrogate_code_point">surrogate code points</a> to be mapped to glyphs. Hence we deal with Unicode <a href="http://unicode.org/glossary/#code_point">code points</a> not <a href="http://unicode.org/glossary/#unicode_scalar_value"> scalar values</a>.<br> <pre><span id="TYPEcp"><span class="keyword">type</span> <code class="type"></code>cp</span> = <code class="type">int</code> </pre> <div class="info"> The type for Unicode <a href="http://unicode.org/glossary/#code_point">code points</a>, ranges from <code class="code">0x0000</code> to <code class="code">0x10_FFFF</code>. Any code point returned by <code class="code"><span class="constructor">Otfm</span></code> is guaranteed to be in the range.<br> </div> <pre><span id="TYPEcp_range"><span class="keyword">type</span> <code class="type"></code>cp_range</span> = <code class="type"><a href="Otfm.html#TYPEcp">cp</a> * <a href="Otfm.html#TYPEcp">cp</a></code> </pre> <div class="info"> The type for Unicode code point ranges. Any range <code class="code">(u0, u1)</code> returned by <code class="code"><span class="constructor">Otfm</span></code> has <code class="code">u0 <= u1</code>.<br> </div> <pre><span id="VALis_cp"><span class="keyword">val</span> is_cp</span> : <code class="type">int -> bool</code></pre><div class="info"> <code class="code">is_cp i</code> is <code class="code"><span class="keyword">true</span></code> if <code class="code">i</code> is an Unicode <a href="http://unicode.org/glossary/#code_point">code point</a>.<br> </div> <br> <h1 id="1_Decode">Decode</h1><br> <pre><span id="TYPEerror_ctx"><span class="keyword">type</span> <code class="type"></code>error_ctx</span> = <code class="type">[ `Offset_table | `Table of <a href="Otfm.html#TYPEtag">tag</a> | `Table_directory ]</code> </pre> <div class="info"> The type for error contexts.<br> </div> <pre><span id="TYPEerror"><span class="keyword">type</span> <code class="type"></code>error</span> = <code class="type">[ `Invalid_cp of int<br> | `Invalid_cp_range of int * int<br> | `Invalid_offset of <a href="Otfm.html#TYPEerror_ctx">error_ctx</a> * int<br> | `Invalid_postscript_name of string<br> | `Missing_required_table of <a href="Otfm.html#TYPEtag">tag</a><br> | `Unexpected_eoi of <a href="Otfm.html#TYPEerror_ctx">error_ctx</a><br> | `Unknown_flavour of <a href="Otfm.html#TYPEtag">tag</a><br> | `Unknown_version of <a href="Otfm.html#TYPEerror_ctx">error_ctx</a> * int32<br> | `Unsupported_TTC<br> | `Unsupported_cmaps of (int * int * int) list ]</code> </pre> <div class="info"> The type for decoding errors. <p> <b>Note.</b> In case of <code class="code"><span class="keywordsign">`</span><span class="constructor">Invalid_poscript_name</span></code> a string of <em>bytes</em> is returned.<br> </div> <pre><span id="VALpp_error"><span class="keyword">val</span> pp_error</span> : <code class="type">Format.formatter -> [< <a href="Otfm.html#TYPEerror">error</a> ] -> unit</code></pre><div class="info"> <code class="code">pp_error ppf e</code> prints an uspecified representation of <code class="code">e</code> on <code class="code">ppf</code>.<br> </div> <pre><span id="TYPEsrc"><span class="keyword">type</span> <code class="type"></code>src</span> = <code class="type">[ `String of string ]</code> </pre> <div class="info"> The type for input sources.<br> </div> <pre><span id="TYPEdecoder"><span class="keyword">type</span> <code class="type"></code>decoder</span> </pre> <div class="info"> The type for OpenType font decoders.<br> </div> <pre><span id="VALdecoder"><span class="keyword">val</span> decoder</span> : <code class="type">[< <a href="Otfm.html#TYPEsrc">src</a> ] -> <a href="Otfm.html#TYPEdecoder">decoder</a></code></pre><div class="info"> <code class="code">decoder src</code> is a decoder decoding from <code class="code">src</code>.<br> </div> <pre><span id="VALdecoder_src"><span class="keyword">val</span> decoder_src</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> <a href="Otfm.html#TYPEsrc">src</a></code></pre><div class="info"> <code class="code">decoder_src d</code> is <code class="code">d</code>'s input source.<br> </div> <br> <h1 id="1_Tabledecoding">Table decoding</h1> <p> These functions can be used in any order and are robust: when they return an error the decoder is back to a consistant state and can be used further. However if <a href="Otfm.html#VALflavour"><code class="code"><span class="constructor">Otfm</span>.flavour</code></a> or <a href="Otfm.html#VALtable_list"><code class="code"><span class="constructor">Otfm</span>.table_list</code></a> returns an error you can safely assume that all other functions will. The fields are in general not documented please refer to the OpenType <a href="http://www.microsoft.com/typography/otspec/default.htm"> specification</a> for details.<br> <pre><span id="TYPEflavour"><span class="keyword">type</span> <code class="type"></code>flavour</span> = <code class="type">[ `CFF | `TTF ]</code> </pre> <div class="info"> The type for OpenType flavours.<br> </div> <pre><span id="VALflavour"><span class="keyword">val</span> flavour</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of <a href="Otfm.html#TYPEflavour">flavour</a> ]</code></pre><div class="info"> <code class="code">decode_flavour d</code> is the flavour of the font decoded by <code class="code">d</code>.<br> </div> <pre><span id="VALtable_list"><span class="keyword">val</span> table_list</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of <a href="Otfm.html#TYPEtag">tag</a> list ]</code></pre><div class="info"> <code class="code">table_list t</code> is the list of tables of the font decoded by <code class="code">d</code>.<br> </div> <pre><span id="VALtable_mem"><span class="keyword">val</span> table_mem</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> <a href="Otfm.html#TYPEtag">tag</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of bool ]</code></pre><div class="info"> <code class="code">table_mem d t</code> is <code class="code"><span class="keyword">true</span></code> if table <code class="code">t</code> is in the font decoded by <code class="code">d</code>.<br> </div> <pre><span id="VALtable_raw"><span class="keyword">val</span> table_raw</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> <a href="Otfm.html#TYPEtag">tag</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of string option ]</code></pre><div class="info"> <code class="code">table_raw d t</code> is the (unpadded) data of the table <code class="code">t</code> as a string if the table <code class="code">t</code> exists.<br> </div> <br> <h2 id="convenience">Convenience decodes</h2> <p> These functions lookup data in the right table.<br> <pre><span id="VALglyph_count"><span class="keyword">val</span> glyph_count</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of int ]</code></pre><div class="info"> <code class="code">glyph_count d</code> is the number of glyphs in the font (bounded by <code class="code">65535</code>).<br> </div> <pre><span id="VALpostscript_name"><span class="keyword">val</span> postscript_name</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of string option ]</code></pre><div class="info"> <code class="code">poscript_name d</code> is the PostScript name of <code class="code">d</code>. Looks up and validates as mandated by the OTF standard, don't rely on <a href="Otfm.html#VALname"><code class="code"><span class="constructor">Otfm</span>.name</code></a> if you really need this information.<br> </div> <br> <h2 id="cmap">cmap table</h2><br> <pre><span id="TYPEglyph_id"><span class="keyword">type</span> <code class="type"></code>glyph_id</span> = <code class="type">int</code> </pre> <div class="info"> The type for glyph ids, from <code class="code">0</code> to <code class="code">65534</code>.<br> </div> <pre><span id="TYPEmap_kind"><span class="keyword">type</span> <code class="type"></code>map_kind</span> = <code class="type">[ `Glyph | `Glyph_range ]</code> </pre> <div class="info"> The type for map kinds. <p> Determines how an unicode range <code class="code">(u0, u1)</code> and a glyph id <code class="code">gid</code> must be interpreted in the folding function of <a href="Otfm.html#VALcmap"><code class="code"><span class="constructor">Otfm</span>.cmap</code></a>. <ul> <li><code class="code"><span class="keywordsign">`</span><span class="constructor">Glyph</span></code> all characters in the range map to to <code class="code">gid</code>.</li> <li><code class="code"><span class="keywordsign">`</span><span class="constructor">Glyph_range</span></code>, <code class="code">u0</code> maps to <code class="code">gid</code>, <code class="code">u0 + 1</code> to <code class="code">gid + 1</code>, ... and <code class="code">u1</code> to <code class="code">gid + (u1 - u0)</code></li> </ul> <br> </div> <pre><span id="VALcmap"><span class="keyword">val</span> cmap</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -><br> ('a -> <a href="Otfm.html#TYPEmap_kind">map_kind</a> -> <a href="Otfm.html#TYPEcp_range">cp_range</a> -> <a href="Otfm.html#TYPEglyph_id">glyph_id</a> -> 'a) -><br> 'a -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of (int * int * int) * 'a ]</code></pre><div class="info"> <code class="code">cmap d f acc</code> folds over a mapping from unicode scalar values to glyph ids by reading the <a href="http://www.microsoft.com/typography/otspec/cmap.htm">cmap</a> table. The returned triple of integer indicates the platform id, encoding id and format of the cmap used. <p> <b>Limitations.</b> Only the format 13 (last resort font), format 12 (UCS-4) and format 4 (UCS-2) cmap table formats are supported. <p> If multiple tables are present, it favours 13 over 12 over 4. If multiple tables of the same format are present it takes the first one it finds. <p> If no supported cmap table is found the error <code class="code"><span class="keywordsign">`</span><span class="constructor">Unsupported_cmaps</span></code> is returned with the list of platform id, encoding id, format available in the font.<br> </div> <br> <h2 id="head">head table</h2><br> <pre><code><span id="TYPEhead"><span class="keyword">type</span> <code class="type"></code>head</span> = {</code></pre><table class="typetable"> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_font_revision">head_font_revision</span> :<code class="type">int32</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_flags">head_flags</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_units_per_em">head_units_per_em</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_created">head_created</span> :<code class="type">float</code>;</code></td> <td class="typefieldcomment" align="left" valign="top" ><code>(*</code></td><td class="typefieldcomment" align="left" valign="top" >Unix timestamp.</td><td class="typefieldcomment" align="left" valign="bottom" ><code>*)</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_modified">head_modified</span> :<code class="type">float</code>;</code></td> <td class="typefieldcomment" align="left" valign="top" ><code>(*</code></td><td class="typefieldcomment" align="left" valign="top" >Unix timestamp.</td><td class="typefieldcomment" align="left" valign="bottom" ><code>*)</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_xmin">head_xmin</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_ymin">head_ymin</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_xmax">head_xmax</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_ymax">head_ymax</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_mac_style">head_mac_style</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_lowest_rec_ppem">head_lowest_rec_ppem</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThead.head_index_to_loc_format">head_index_to_loc_format</span> :<code class="type">int</code>;</code></td> </tr></table> } <div class="info"> The type for representing <a href="http://www.microsoft.com/typography/otspec/head.htm">head</a> tables.<br> </div> <pre><span id="VALhead"><span class="keyword">val</span> head</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of <a href="Otfm.html#TYPEhead">head</a> ]</code></pre><div class="info"> <code class="code">head d</code> is the head table.<br> </div> <br> <h2 id="hhea">hhea table</h2><br> <pre><code><span id="TYPEhhea"><span class="keyword">type</span> <code class="type"></code>hhea</span> = {</code></pre><table class="typetable"> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_ascender">hhea_ascender</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_descender">hhea_descender</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_line_gap">hhea_line_gap</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_advance_width_max">hhea_advance_width_max</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_min_left_side_bearing">hhea_min_left_side_bearing</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_min_right_side_bearing">hhea_min_right_side_bearing</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_xmax_extent">hhea_xmax_extent</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_caret_slope_rise">hhea_caret_slope_rise</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_caret_slope_run">hhea_caret_slope_run</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELThhea.hhea_caret_offset">hhea_caret_offset</span> :<code class="type">int</code>;</code></td> </tr></table> } <div class="info"> The type for <a href="http://www.microsoft.com/typography/otspec/hhea.htm">hhea</a> tables.<br> </div> <pre><span id="VALhhea"><span class="keyword">val</span> hhea</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of <a href="Otfm.html#TYPEhhea">hhea</a> ]</code></pre><div class="info"> <code class="code">hhea d</code> is the hhea table.<br> </div> <br> <h2 id="hmtx">hmtx table</h2><br> <pre><span id="VALhmtx"><span class="keyword">val</span> hmtx</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -><br> ('a -> <a href="Otfm.html#TYPEglyph_id">glyph_id</a> -> int -> int -> 'a) -><br> 'a -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of 'a ]</code></pre><div class="info"> <code class="code">hmtx d f acc</code> folds over the horizontal metrics of the font by reading the <a href="http://www.microsoft.com/typography/otspec/hmtx.htm">hmtx</a> table. <code class="code">f</code> is applied on each entry with <code class="code">f acc' gid adv lsb</code> with <code class="code">gid</code> the glyph id (guaranteed to range, in order, from <code class="code">0</code> to glyph count minus one), <code class="code">adv</code> the (unsigned) advance width, and <code class="code">lsb</code> the (signed) left side bearing.<br> </div> <br> <h2 id="name">name table</h2><br> <pre><span id="TYPElang"><span class="keyword">type</span> <code class="type"></code>lang</span> = <code class="type">string</code> </pre> <div class="info"> The type for <a href="http://tools.ietf.org/html/bcp47">BCP 47</a> language tags.<br> </div> <pre><span id="VALname"><span class="keyword">val</span> name</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -><br> ('a -> int -> <a href="Otfm.html#TYPElang">lang</a> -> string -> 'a) -><br> 'a -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of 'a ]</code></pre><div class="info"> <code class="code">name d f acc</code> folds over the name records of the font by reading the <a href="http://www.microsoft.com/typography/otspec/name.htm">name</a> table. <code class="code">f</code> is applied on each name id entry with <code class="code">f acc' nid lang name</code> with <code class="code">nid</code> the name id, lang the language tag, and <code class="code">name</code> the UTF-8 encoded name value. <p> <b>Note.</b> The module normalizes Windows language ids to lowercased BCP 47 ids. Language tags found in language tag records should be BCP 47 language tags but are not checked for conformance. <p> <b>Tip.</b> If you are looking for the postcript name use <a href="Otfm.html#VALpostscript_name"><code class="code"><span class="constructor">Otfm</span>.postscript_name</code></a>. <p> <b>Limitations.</b> Lookups data only in platform ids 0, 2 and 3 (Unicode, ISO and Windows) with UTF-16BE encoding and reports only the data of the first one it finds for a given name id.<br> </div> <br> <h2 id="os2">OS/2 table</h2><br> <pre><code><span id="TYPEos2"><span class="keyword">type</span> <code class="type"></code>os2</span> = {</code></pre><table class="typetable"> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_x_avg_char_width">os2_x_avg_char_width</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_weight_class">os2_us_weight_class</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_width_class">os2_us_width_class</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_fs_type">os2_fs_type</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_subscript_x_size">os2_y_subscript_x_size</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_subscript_y_size">os2_y_subscript_y_size</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_subscript_x_offset">os2_y_subscript_x_offset</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_subscript_y_offset">os2_y_subscript_y_offset</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_superscript_x_size">os2_y_superscript_x_size</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_superscript_y_size">os2_y_superscript_y_size</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_superscript_x_offset">os2_y_superscript_x_offset</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_superscript_y_offset">os2_y_superscript_y_offset</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_strikeout_size">os2_y_strikeout_size</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_y_strikeout_position">os2_y_strikeout_position</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_family_class">os2_family_class</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_panose">os2_panose</span> :<code class="type">string</code>;</code></td> <td class="typefieldcomment" align="left" valign="top" ><code>(*</code></td><td class="typefieldcomment" align="left" valign="top" >10 bytes</td><td class="typefieldcomment" align="left" valign="bottom" ><code>*)</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_ul_unicode_range1">os2_ul_unicode_range1</span> :<code class="type">int32</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_ul_unicode_range2">os2_ul_unicode_range2</span> :<code class="type">int32</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_ul_unicode_range3">os2_ul_unicode_range3</span> :<code class="type">int32</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_ul_unicode_range4">os2_ul_unicode_range4</span> :<code class="type">int32</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_ach_vend_id">os2_ach_vend_id</span> :<code class="type">int32</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_fs_selection">os2_fs_selection</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_first_char_index">os2_us_first_char_index</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_last_char_index">os2_us_last_char_index</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_s_typo_ascender">os2_s_typo_ascender</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_s_type_descender">os2_s_type_descender</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_s_typo_linegap">os2_s_typo_linegap</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_win_ascent">os2_us_win_ascent</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_win_descent">os2_us_win_descent</span> :<code class="type">int</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_ul_code_page_range_1">os2_ul_code_page_range_1</span> :<code class="type">int32 option</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_ul_code_page_range_2">os2_ul_code_page_range_2</span> :<code class="type">int32 option</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_s_x_height">os2_s_x_height</span> :<code class="type">int option</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_s_cap_height">os2_s_cap_height</span> :<code class="type">int option</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_default_char">os2_us_default_char</span> :<code class="type">int option</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_break_char">os2_us_break_char</span> :<code class="type">int option</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTos2.os2_us_max_context">os2_us_max_context</span> :<code class="type">int option</code>;</code></td> </tr></table> } <div class="info"> The type for <a href="http://www.microsoft.com/typography/otspec/os2.htm">OS/2</a> tables.<br> </div> <pre><span id="VALos2"><span class="keyword">val</span> os2</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of <a href="Otfm.html#TYPEos2">os2</a> ]</code></pre><div class="info"> <code class="code">os2 d</code> is the OS/2 table.<br> </div> <br> <h2 id="kern">kern table</h2><br> <pre><code><span id="TYPEkern_info"><span class="keyword">type</span> <code class="type"></code>kern_info</span> = {</code></pre><table class="typetable"> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTkern_info.kern_dir">kern_dir</span> :<code class="type">[ `H | `V ]</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTkern_info.kern_kind">kern_kind</span> :<code class="type">[ `Kern | `Min ]</code>;</code></td> </tr> <tr> <td align="left" valign="top" > <code> </code></td> <td align="left" valign="top" > <code><span id="TYPEELTkern_info.kern_cross_stream">kern_cross_stream</span> :<code class="type">bool</code>;</code></td> </tr></table> } <div class="info"> The type for kerning (sub)table information.<br> </div> <pre><span id="VALkern"><span class="keyword">val</span> kern</span> : <code class="type"><a href="Otfm.html#TYPEdecoder">decoder</a> -><br> ('a -> <a href="Otfm.html#TYPEkern_info">kern_info</a> -> [ `Fold | `Skip ] * 'a) -><br> ('a -> <a href="Otfm.html#TYPEglyph_id">glyph_id</a> -> <a href="Otfm.html#TYPEglyph_id">glyph_id</a> -> int -> 'a) -><br> 'a -> [> `Error of <a href="Otfm.html#TYPEerror">error</a> | `Ok of 'a ]</code></pre><div class="info"> <code class="code">kern d t p acc</code> folds over the kerning tables of <code class="code">d</code> by reading the <a href="http://www.microsoft.com/typography/otspec/kern.htm">kern</a> table. <code class="code">t</code> is called on each new (sub)table, the table pairs are skipped if it returns <code class="code"><span class="keywordsign">`</span><span class="constructor">Skip</span></code> otherwise <code class="code">p acc' left right value</code> is called on each kerning pair of the table. The function returns <code class="code">acc</code> if there is no kern table. <p> <b>Limitations.</b> Only format 0 kerning tables are supported.<br> </div> <br> <h1 id="limitations">Limitations</h1> <p> As it stands <code class="code"><span class="constructor">Otfm</span></code> has the following limitations. Some of these may be lifted in the future and a few of these can be overcome by pre-processing your font (e.g. extract <code class="code">.ttc</code> files to <code class="code">.ttf</code>, or removing hinting information to reduce the font size). See also the individual table decoding functions for other limitations. <p> <ul> <li>True Type collections (<code class="code">.ttc</code> files) are not supported</li> <li>The whole font needs to be loaded in memory as a string. This may be a limiting factor on 32 bits platforms (but non <code class="code">.ttc</code> font files tend to be smaller than 16 Mo).</li> <li>Table checksums are not verified.</li> </ul> <br> <br> <h1 id="examples">Examples</h1> <p> The following code prints the postscript name of the font on stdout. <pre class="codepre"><code class="code"> <span class="keyword">let</span> otf_postscript_name bytes = <br> <span class="keyword">let</span> d = <span class="constructor">Otfm</span>.decoder (<span class="keywordsign">`</span><span class="constructor">String</span> bytes) <span class="keyword">in</span><br> <span class="keyword">match</span> <span class="constructor">Otfm</span>.postscript_name d <span class="keyword">with</span> <br> <span class="keywordsign">|</span> <span class="keywordsign">`</span><span class="constructor">Error</span> e <span class="keywordsign">-></span> <span class="constructor">Format</span>.eprintf <span class="string">"@[%a@]@."</span> <span class="constructor">Otfm</span>.pp_error e<br> <span class="keywordsign">|</span> <span class="keywordsign">`</span><span class="constructor">Ok</span> (<span class="constructor">Some</span> n) <span class="keywordsign">-></span> <span class="constructor">Format</span>.printf <span class="string">"%s@."</span> n;<br> <span class="keywordsign">|</span> <span class="keywordsign">`</span><span class="constructor">Ok</span> <span class="constructor">None</span> <span class="keywordsign">-></span> ()<br> </code></pre><br> </body></html>